diff options
27 files changed, 22298 insertions, 18082 deletions
diff --git a/mitmproxy/web/static/app.css b/mitmproxy/web/static/app.css index 94a6abf0..1f64abe7 100644 --- a/mitmproxy/web/static/app.css +++ b/mitmproxy/web/static/app.css @@ -42,7 +42,8 @@ html { } html, body, -#container { +#container, +#mitmproxy { height: 100%; margin: 0; overflow: hidden; diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index 27f356f7..400c3c51 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -82,18 +82,11 @@ EventEmitter.prototype.emit = function(type) { break; // slower default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; + args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - + args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) @@ -131,7 +124,6 @@ EventEmitter.prototype.addListener = function(type, listener) { // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { - var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { @@ -253,7 +245,7 @@ EventEmitter.prototype.removeAllListeners = function(type) { if (isFunction(listeners)) { this.removeListener(type, listeners); - } else { + } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); @@ -274,15 +266,20 @@ EventEmitter.prototype.listeners = function(type) { return ret; }; +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; + return emitter.listenerCount(type); }; function isFunction(arg) { @@ -442,61 +439,74 @@ module.exports = { Query: Query }; - },{"./dispatcher.js":21,"jquery":"jquery","lodash":"lodash"}],3:[function(require,module,exports){ "use strict"; -var React = require("react"); -var ReactRouter = require("react-router"); -var $ = require("jquery"); -var Connection = require("./connection"); -var proxyapp = require("./components/proxyapp.js"); -var EventLogActions = require("./actions.js").EventLogActions; +var _react = require("react"); -$(function () { - window.ws = new Connection("/updates"); +var _react2 = _interopRequireDefault(_react); + +var _reactDom = require("react-dom"); + +var _jquery = require("jquery"); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _connection = require("./connection"); + +var _connection2 = _interopRequireDefault(_connection); + +var _proxyapp = require("./components/proxyapp.js"); + +var _actions = require("./actions.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(0, _jquery2.default)(function () { + window.ws = new _connection2.default("/updates"); window.onerror = function (msg) { - EventLogActions.add_event(msg); + _actions.EventLogActions.add_event(msg); }; - ReactRouter.run(proxyapp.routes, function (Handler, state) { - React.render(React.createElement(Handler, null), document.body); - }); + (0, _reactDom.render)(_proxyapp.app, document.getElementById("mitmproxy")); }); - -},{"./actions.js":2,"./components/proxyapp.js":18,"./connection":20,"jquery":"jquery","react":"react","react-router":"react-router"}],4:[function(require,module,exports){ +},{"./actions.js":2,"./components/proxyapp.js":18,"./connection":20,"jquery":"jquery","react":"react","react-dom":"react-dom"}],4:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); var React = require("react"); +var ReactDOM = require("react-dom"); var ReactRouter = require("react-router"); var _ = require("lodash"); // http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) -var AutoScrollMixin = { +var AutoScrollMixin = exports.AutoScrollMixin = { componentWillUpdate: function componentWillUpdate() { - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); this._shouldScrollBottom = node.scrollTop !== 0 && node.scrollTop + node.clientHeight === node.scrollHeight; }, componentDidUpdate: function componentDidUpdate() { if (this._shouldScrollBottom) { - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); node.scrollTop = node.scrollHeight; } } }; -var StickyHeadMixin = { +var StickyHeadMixin = exports.StickyHeadMixin = { adjustHead: function adjustHead() { // Abusing CSS transforms to set the element // referenced as head into some kind of position:sticky. - var head = this.refs.head.getDOMNode(); - head.style.transform = "translate(0," + this.getDOMNode().scrollTop + "px)"; + var head = this.refs.head; + head.style.transform = "translate(0," + ReactDOM.findDOMNode(this).scrollTop + "px)"; } }; -var SettingsState = { +var SettingsState = exports.SettingsState = { contextTypes: { settingsStore: React.PropTypes.object.isRequired }, @@ -518,57 +528,61 @@ var SettingsState = { } }; -var ChildFocus = { +var ChildFocus = exports.ChildFocus = { contextTypes: { returnFocus: React.PropTypes.func }, returnFocus: function returnFocus() { - React.findDOMNode(this).blur(); + ReactDOM.findDOMNode(this).blur(); window.getSelection().removeAllRanges(); this.context.returnFocus(); } }; -var Navigation = _.extend({}, ReactRouter.Navigation, { +var Navigation = exports.Navigation = { + contextTypes: { + routerFoo: React.PropTypes.object, + router: React.PropTypes.object.isRequired + }, setQuery: function setQuery(dict) { - var q = this.context.router.getCurrentQuery(); + var q = this.context.routerFoo.location.query; for (var i in dict) { if (dict.hasOwnProperty(i)) { q[i] = dict[i] || undefined; //falsey values shall be removed. } } - this.replaceWith(this.context.router.getCurrentPath(), this.context.router.getCurrentParams(), q); + this.replaceWith(undefined, q); }, - replaceWith: function replaceWith(routeNameOrPath, params, query) { - if (routeNameOrPath === undefined) { - routeNameOrPath = this.context.router.getCurrentPath(); - } - if (params === undefined) { - params = this.context.router.getCurrentParams(); + replaceWith: function replaceWith(pathname, query) { + if (pathname === undefined) { + pathname = this.context.routerFoo.location.pathname; } if (query === undefined) { - query = this.context.router.getCurrentQuery(); + query = this.context.routerFoo.query; } - - this.context.router.replaceWith(routeNameOrPath, params, query); + console.log({ pathname: pathname, query: query }); + this.context.router.replace({ pathname: pathname, query: query }); } -}); +}; // react-router is fairly good at changing its API regularly. // We keep the old method for now - if it should turn out that their changes are permanent, // we may remove this mixin and access react-router directly again. -var RouterState = _.extend({}, ReactRouter.State, { +var RouterState = exports.RouterState = { + contextTypes: { + routerFoo: React.PropTypes.object + }, getQuery: function getQuery() { // For whatever reason, react-router always returns the same object, which makes comparing // the current props with nextProps impossible. As a workaround, we just clone the query object. - return _.clone(this.context.router.getCurrentQuery()); + return _.clone(this.context.routerFoo.location.query); }, getParams: function getParams() { - return _.clone(this.context.router.getCurrentParams()); + return _.clone(this.context.routerFoo.params); } -}); +}; -var Splitter = React.createClass({ +var Splitter = exports.Splitter = React.createClass({ displayName: "Splitter", getDefaultProps: function getDefaultProps() { @@ -594,7 +608,7 @@ var Splitter = React.createClass({ window.addEventListener("dragend", this.onDragEnd); }, onDragEnd: function onDragEnd() { - this.getDOMNode().style.transform = ""; + ReactDOM.findDOMNode(this).style.transform = ""; window.removeEventListener("dragend", this.onDragEnd); window.removeEventListener("mouseup", this.onMouseUp); window.removeEventListener("mousemove", this.onMouseMove); @@ -602,7 +616,7 @@ var Splitter = React.createClass({ onMouseUp: function onMouseUp(e) { this.onDragEnd(); - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); var prev = node.previousElementSibling; var next = node.nextElementSibling; @@ -631,7 +645,7 @@ var Splitter = React.createClass({ } else { dY = e.pageY - this.state.startY; } - this.getDOMNode().style.transform = "translate(" + dX + "px," + dY + "px)"; + ReactDOM.findDOMNode(this).style.transform = "translate(" + dX + "px," + dY + "px)"; }, onResize: function onResize() { // Trigger a global resize event. This notifies components that employ virtual scrolling @@ -644,7 +658,7 @@ var Splitter = React.createClass({ if (!this.state.applied) { return; } - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); var prev = node.previousElementSibling; var next = node.nextElementSibling; @@ -676,23 +690,13 @@ var Splitter = React.createClass({ } }); -module.exports = { - ChildFocus: ChildFocus, - RouterState: RouterState, - Navigation: Navigation, - StickyHeadMixin: StickyHeadMixin, - AutoScrollMixin: AutoScrollMixin, - Splitter: Splitter, - SettingsState: SettingsState -}; - - -},{"lodash":"lodash","react":"react","react-router":"react-router"}],5:[function(require,module,exports){ +},{"lodash":"lodash","react":"react","react-dom":"react-dom","react-router":"react-router"}],5:[function(require,module,exports){ "use strict"; 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 React = require("react"); +var ReactDOM = require('react-dom'); var common = require("./common.js"); var utils = require("../utils.js"); @@ -740,8 +744,8 @@ var EditorBase = React.createClass({ return React.createElement(Tag, _extends({}, this.props, { tabIndex: "0", className: className, - contentEditable: this.state.editable || undefined, // workaround: use undef instead of false to remove attr - onFocus: this.onFocus, + contentEditable: this.state.editable || undefined // workaround: use undef instead of false to remove attr + , onFocus: this.onFocus, onMouseDown: this.onMouseDown, onClick: this.onClick, onBlur: this._stop, @@ -793,12 +797,12 @@ var EditorBase = React.createClass({ range = document.caretRangeFromPoint(e.clientX, e.clientY); } else { range = document.createRange(); - range.selectNodeContents(React.findDOMNode(this)); + range.selectNodeContents(ReactDOM.findDOMNode(this)); } this._ignore_events = true; this.setState({ editable: true }, function () { - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); node.blur(); node.focus(); this._ignore_events = false; @@ -810,7 +814,7 @@ var EditorBase = React.createClass({ // a stop would cause a blur as a side-effect. // but a blur event must trigger a stop as well. // to fix this, make stop = blur and do the actual stop in the onBlur handler. - React.findDOMNode(this).blur(); + ReactDOM.findDOMNode(this).blur(); this.props.onStop && this.props.onStop(); }, _stop: function _stop(e) { @@ -819,14 +823,14 @@ var EditorBase = React.createClass({ } console.log("_stop", _.extend({}, e)); window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); var content = this.props.nodeToContent(node); this.setState({ editable: false }); this.props.onDone(content); this.props.onBlur && this.props.onBlur(e); }, reset: function reset() { - React.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); + ReactDOM.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); }, onKeyDown: function onKeyDown(e) { e.stopPropagation(); @@ -847,7 +851,7 @@ var EditorBase = React.createClass({ } }, onInput: function onInput() { - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); var content = this.props.nodeToContent(node); this.props.onInput && this.props.onInput(content); } @@ -923,7 +927,7 @@ var ValueEditor = React.createClass({ })); }, focus: function focus() { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, onStop: function onStop() { this.returnFocus(); @@ -934,14 +938,15 @@ module.exports = { ValueEditor: ValueEditor }; - -},{"../utils.js":26,"./common.js":4,"react":"react"}],6:[function(require,module,exports){ +},{"../utils.js":26,"./common.js":4,"react":"react","react-dom":"react-dom"}],6:[function(require,module,exports){ "use strict"; +var _virtualscroll = require("./virtualscroll.js"); + var React = require("react"); var common = require("./common.js"); var Query = require("../actions.js").Query; -var VirtualScrollMixin = require("./virtualscroll.js"); + var views = require("../store/view.js"); var _ = require("lodash"); @@ -980,7 +985,7 @@ var EventLogContents = React.createClass({ contextTypes: { eventStore: React.PropTypes.object.isRequired }, - mixins: [common.AutoScrollMixin, VirtualScrollMixin], + mixins: [common.AutoScrollMixin, _virtualscroll.VirtualScrollMixin], getInitialState: function getInitialState() { var filterFn = function filterFn(entry) { return this.props.filter[entry.level]; @@ -1104,7 +1109,6 @@ var EventLog = React.createClass({ module.exports = EventLog; - },{"../actions.js":2,"../store/view.js":25,"./common.js":4,"./virtualscroll.js":19,"lodash":"lodash","react":"react"}],7:[function(require,module,exports){ "use strict"; @@ -1365,16 +1369,17 @@ var all_columns = [TLSColumn, IconColumn, PathColumn, MethodColumn, StatusColumn module.exports = all_columns; - },{"../flow/utils.js":23,"../utils.js":26,"react":"react"}],8:[function(require,module,exports){ "use strict"; +var _virtualscroll = require("./virtualscroll.js"); + var React = require("react"); +var ReactDOM = require('react-dom'); var common = require("./common.js"); var utils = require("../utils.js"); var _ = require("lodash"); -var VirtualScrollMixin = require("./virtualscroll.js"); var flowtable_columns = require("./flowtable-columns.js"); var FlowRow = React.createClass({ @@ -1382,9 +1387,9 @@ var FlowRow = React.createClass({ render: function render() { var flow = this.props.flow; - var columns = this.props.columns.map((function (Column) { + var columns = this.props.columns.map(function (Column) { return React.createElement(Column, { key: Column.displayName, flow: flow }); - }).bind(this)); + }.bind(this)); var className = ""; if (this.props.selected) { className += " selected"; @@ -1458,7 +1463,7 @@ var FlowTableHead = React.createClass({ this.props.setSortKeyFun(sortKeyFun); }, render: function render() { - var columns = this.props.columns.map((function (Column) { + var columns = this.props.columns.map(function (Column) { var onClick = this.onClick.bind(this, Column); var className; if (this.state.sortColumn === Column) { @@ -1472,7 +1477,7 @@ var FlowTableHead = React.createClass({ key: Column.displayName, onClick: onClick, className: className }); - }).bind(this)); + }.bind(this)); return React.createElement( "thead", null, @@ -1490,7 +1495,7 @@ var ROW_HEIGHT = 32; var FlowTable = React.createClass({ displayName: "FlowTable", - mixins: [common.StickyHeadMixin, common.AutoScrollMixin, VirtualScrollMixin], + mixins: [common.StickyHeadMixin, common.AutoScrollMixin, _virtualscroll.VirtualScrollMixin], contextTypes: { view: React.PropTypes.object.isRequired }, @@ -1524,7 +1529,7 @@ var FlowTable = React.createClass({ this.forceUpdate(); }, scrollIntoView: function scrollIntoView(flow) { - this.scrollRowIntoView(this.context.view.index(flow), this.refs.body.getDOMNode().offsetTop); + this.scrollRowIntoView(this.context.view.index(flow), ReactDOM.findDOMNode(this.refs.body).offsetTop); }, renderRow: function renderRow(flow) { var selected = flow === this.props.selected; @@ -1566,8 +1571,7 @@ var FlowTable = React.createClass({ module.exports = FlowTable; - -},{"../utils.js":26,"./common.js":4,"./flowtable-columns.js":7,"./virtualscroll.js":19,"lodash":"lodash","react":"react"}],9:[function(require,module,exports){ +},{"../utils.js":26,"./common.js":4,"./flowtable-columns.js":7,"./virtualscroll.js":19,"lodash":"lodash","react":"react","react-dom":"react-dom"}],9:[function(require,module,exports){ "use strict"; 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; }; @@ -1613,16 +1617,16 @@ var RawMixin = { content: undefined, request: request }); - request.done((function (data) { + request.done(function (data) { this.setState({ content: data }); - }).bind(this)).fail((function (jqXHR, textStatus, errorThrown) { + }.bind(this)).fail(function (jqXHR, textStatus, errorThrown) { if (textStatus === "abort") { return; } this.setState({ content: "AJAX Error: " + textStatus + "\r\n" + errorThrown }); - }).bind(this)).always((function () { + }.bind(this)).always(function () { this.setState({ request: undefined }); - }).bind(this)); + }.bind(this)); }, componentWillMount: function componentWillMount() { this.requestContent(this.props); @@ -1865,7 +1869,6 @@ var ContentView = React.createClass({ module.exports = ContentView; - },{"../../flow/utils.js":23,"../../utils.js":26,"lodash":"lodash","react":"react"}],10:[function(require,module,exports){ "use strict"; @@ -1920,6 +1923,7 @@ var TimeStamp = React.createClass({ var ConnectionInfo = React.createClass({ displayName: "ConnectionInfo", + render: function render() { var conn = this.props.conn; var address = conn.address.address.join(":"); @@ -2122,7 +2126,6 @@ var Details = React.createClass({ module.exports = Details; - },{"../../utils.js":26,"lodash":"lodash","react":"react"}],11:[function(require,module,exports){ "use strict"; @@ -2169,10 +2172,7 @@ var FlowView = React.createClass({ this.selectTab(tabs[nextIndex]); }, selectTab: function selectTab(panel) { - this.replaceWith("flow", { - flowId: this.getParams().flowId, - detailTab: panel - }); + this.replaceWith("/flows/" + this.getParams().flowId + "/" + panel); }, getActive: function getActive() { return this.getParams().detailTab; @@ -2196,12 +2196,12 @@ var FlowView = React.createClass({ this.setState({ prompt: { - done: (function (k) { + done: function (k) { this.setState({ prompt: false }); if (k) { this.refs.tab.edit(k); } - }).bind(this), + }.bind(this), options: options } }); @@ -2211,7 +2211,7 @@ var FlowView = React.createClass({ var tabs = this.getTabs(flow); var active = this.getActive(); - if (!_.contains(tabs, active)) { + if (tabs.indexOf(active) < 0) { if (active === "response" && flow.error) { active = "error"; } else if (active === "error" && flow.response) { @@ -2244,13 +2244,13 @@ var FlowView = React.createClass({ module.exports = FlowView; - },{"../common.js":4,"../prompt.js":17,"./details.js":10,"./messages.js":12,"./nav.js":13,"lodash":"lodash","react":"react"}],12:[function(require,module,exports){ "use strict"; 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 React = require("react"); +var ReactDOM = require('react-dom'); var _ = require("lodash"); var common = require("../common.js"); @@ -2316,7 +2316,7 @@ var Headers = React.createClass({ }, render: function render() { - var rows = this.props.message.headers.map((function (header, i) { + var rows = this.props.message.headers.map(function (header, i) { var kEdit = React.createElement(HeaderEditor, { ref: i + "-key", @@ -2345,7 +2345,7 @@ var Headers = React.createClass({ vEdit ) ); - }).bind(this)); + }.bind(this)); return React.createElement( "table", { className: "header-table" }, @@ -2365,7 +2365,7 @@ var HeaderEditor = React.createClass({ return React.createElement(ValueEditor, _extends({ ref: "input" }, this.props, { onKeyDown: this.onKeyDown, inline: true })); }, focus: function focus() { - this.getDOMNode().focus(); + ReactDOM.findDOMNode(this).focus(); }, onKeyDown: function onKeyDown(e) { switch (e.keyCode) { @@ -2594,10 +2594,8 @@ module.exports = { Response: Response, Error: Error }; -/*<ResponseLine flow={flow}/>*/ /*<RequestLine flow={flow}/>*/ - -},{"../../actions.js":2,"../../flow/utils.js":23,"../../utils.js":26,"../common.js":4,"../editor.js":5,"./contentview.js":9,"lodash":"lodash","react":"react"}],13:[function(require,module,exports){ +},{"../../actions.js":2,"../../flow/utils.js":23,"../../utils.js":26,"../common.js":4,"../editor.js":5,"./contentview.js":9,"lodash":"lodash","react":"react","react-dom":"react-dom"}],13:[function(require,module,exports){ "use strict"; var React = require("react"); @@ -2629,13 +2627,13 @@ var Nav = React.createClass({ render: function render() { var flow = this.props.flow; - var tabs = this.props.tabs.map((function (e) { + var tabs = this.props.tabs.map(function (e) { var str = e.charAt(0).toUpperCase() + e.slice(1); var className = this.props.active === e ? "active" : ""; - var onClick = (function (event) { + var onClick = function (event) { this.props.selectTab(e); event.preventDefault(); - }).bind(this); + }.bind(this); return React.createElement( "a", { key: e, @@ -2644,7 +2642,7 @@ var Nav = React.createClass({ onClick: onClick }, str ); - }).bind(this)); + }.bind(this)); var acceptButton = null; if (flow.intercepted) { @@ -2659,7 +2657,7 @@ var Nav = React.createClass({ "nav", { ref: "head", className: "nav-tabs nav-tabs-sm" }, tabs, - React.createElement(NavAction, { title: "[d]elete flow", icon: "fa-trash", onClick: actions.FlowActions["delete"].bind(null, flow) }), + React.createElement(NavAction, { title: "[d]elete flow", icon: "fa-trash", onClick: actions.FlowActions.delete.bind(null, flow) }), React.createElement(NavAction, { title: "[D]uplicate flow", icon: "fa-copy", onClick: actions.FlowActions.duplicate.bind(null, flow) }), React.createElement(NavAction, { disabled: true, title: "[r]eplay flow", icon: "fa-repeat", onClick: actions.FlowActions.replay.bind(null, flow) }), acceptButton, @@ -2670,7 +2668,6 @@ var Nav = React.createClass({ module.exports = Nav; - },{"../../actions.js":2,"react":"react"}],14:[function(require,module,exports){ "use strict"; @@ -2706,11 +2703,11 @@ var Footer = React.createClass({ module.exports = Footer; - },{"./common.js":4,"react":"react"}],15:[function(require,module,exports){ "use strict"; var React = require("react"); +var ReactDOM = require('react-dom'); var $ = require("jquery"); var Filt = require("../filt/filt.js"); @@ -2734,9 +2731,9 @@ var FilterDocs = React.createClass({ }); } if (FilterDocs.xhr) { - FilterDocs.xhr.done((function () { + FilterDocs.xhr.done(function () { this.forceUpdate(); - }).bind(this)); + }.bind(this)); } }, render: function render() { @@ -2815,24 +2812,24 @@ var FilterInput = React.createClass({ }, isValid: function isValid(filt) { try { - Filt.parse(filt || this.state.value); + var str = filt || this.state.value; + if (str) { + Filt.parse(filt || this.state.value); + } return true; } catch (e) { return false; } }, getDesc: function getDesc() { - var desc; - try { - desc = Filt.parse(this.state.value).desc; - } catch (e) { - desc = "" + e; - } - if (desc !== "true") { - return desc; - } else { - return React.createElement(FilterDocs, null); + if (this.state.value) { + try { + return Filt.parse(this.state.value).desc; + } catch (e) { + return "" + e; + } } + return React.createElement(FilterDocs, null); }, onFocus: function onFocus() { this.setState({ focus: true }); @@ -2855,11 +2852,11 @@ var FilterInput = React.createClass({ e.stopPropagation(); }, blur: function blur() { - this.refs.input.getDOMNode().blur(); + ReactDOM.findDOMNode(this.refs.input).blur(); this.returnFocus(); }, select: function select() { - this.refs.input.getDOMNode().select(); + ReactDOM.findDOMNode(this.refs.input).select(); }, render: function render() { var isValid = this.isValid(); @@ -3027,10 +3024,10 @@ var FileMenu = React.createClass({ handleFileClick: function handleFileClick(e) { e.preventDefault(); if (!this.state.showFileMenu) { - var close = (function () { + var close = function () { this.setState({ showFileMenu: false }); document.removeEventListener("click", close); - }).bind(this); + }.bind(this); document.addEventListener("click", close); this.setState({ @@ -3113,7 +3110,7 @@ var Header = React.createClass({ this.setState({ active: active }); }, render: function render() { - var header = header_entries.map((function (entry, i) { + var header = header_entries.map(function (entry, i) { var className; if (entry === this.state.active) { className = "active"; @@ -3128,7 +3125,7 @@ var Header = React.createClass({ onClick: this.handleClick.bind(this, entry) }, entry.title ); - }).bind(this)); + }.bind(this)); return React.createElement( "header", @@ -3152,30 +3149,8 @@ module.exports = { Header: Header, MainMenu: MainMenu }; -/* -<li> -<a href="#" onClick={this.handleOpenClick}> -<i className="fa fa-fw fa-folder-open"></i> -Open -</a> -</li> -<li> -<a href="#" onClick={this.handleSaveClick}> -<i className="fa fa-fw fa-save"></i> -Save -</a> -</li> -<li role="presentation" className="divider"></li> -<li> -<a href="#" onClick={this.handleShutdownClick}> -<i className="fa fa-fw fa-plug"></i> -Shutdown -</a> -</li> -*/ - - -},{"../actions.js":2,"../filt/filt.js":22,"../utils.js":26,"./common.js":4,"jquery":"jquery","react":"react"}],16:[function(require,module,exports){ + +},{"../actions.js":2,"../filt/filt.js":22,"../utils.js":26,"./common.js":4,"jquery":"jquery","react":"react","react-dom":"react-dom"}],16:[function(require,module,exports){ "use strict"; var React = require("react"); @@ -3224,7 +3199,10 @@ var MainView = React.createClass({ }, getViewFilt: function getViewFilt() { try { - var filt = Filt.parse(this.getQuery()[Query.SEARCH] || ""); + var filtStr = this.getQuery()[Query.SEARCH]; + var filt = filtStr ? Filt.parse(filtStr) : function () { + return true; + }; var highlightStr = this.getQuery()[Query.HIGHLIGHT]; var highlight = highlightStr ? Filt.parse(highlightStr) : false; } catch (e) { @@ -3272,13 +3250,11 @@ var MainView = React.createClass({ }, selectFlow: function selectFlow(flow) { if (flow) { - this.replaceWith("flow", { - flowId: flow.id, - detailTab: this.getParams().detailTab || "request" - }); + var tab = this.getParams().detailTab || "request"; + this.replaceWith("/flows/" + flow.id + "/" + tab); this.refs.flowTable.scrollIntoView(flow); } else { - this.replaceWith("flows", {}); + this.replaceWith("/flows"); } }, selectFlowRelative: function selectFlowRelative(shift) { @@ -3356,7 +3332,7 @@ var MainView = React.createClass({ if (e.shiftKey) { actions.FlowActions.duplicate(flow); } else { - actions.FlowActions["delete"](flow); + actions.FlowActions.delete(flow); } } break; @@ -3417,11 +3393,11 @@ var MainView = React.createClass({ module.exports = MainView; - },{"../actions.js":2,"../filt/filt.js":22,"../store/view.js":25,"../utils.js":26,"./common.js":4,"./flowtable.js":8,"./flowview/index.js":11,"react":"react"}],17:[function(require,module,exports){ "use strict"; var React = require("react"); +var ReactDOM = require('react-dom'); var _ = require("lodash"); var utils = require("../utils.js"); @@ -3437,7 +3413,7 @@ var Prompt = React.createClass({ prompt: React.PropTypes.string }, componentDidMount: function componentDidMount() { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, onKeyDown: function onKeyDown(e) { e.stopPropagation(); @@ -3490,7 +3466,7 @@ var Prompt = React.createClass({ }, render: function render() { var opts = this.getOptions(); - opts = _.map(opts, (function (o) { + opts = _.map(opts, function (o) { var prefix, suffix; var idx = o.text.indexOf(o.key); if (idx !== -1) { @@ -3500,10 +3476,10 @@ var Prompt = React.createClass({ prefix = o.text + " ("; suffix = ")"; } - var onClick = (function (e) { + var onClick = function (e) { this.done(o.key); e.stopPropagation(); - }).bind(this); + }.bind(this); return React.createElement( "span", { @@ -3518,7 +3494,7 @@ var Prompt = React.createClass({ ), suffix ); - }).bind(this)); + }.bind(this)); return React.createElement( "div", { tabIndex: "0", onKeyDown: this.onKeyDown, onClick: this.onClick, className: "prompt-dialog" }, @@ -3538,11 +3514,18 @@ var Prompt = React.createClass({ module.exports = Prompt; - -},{"../utils.js":26,"./common.js":4,"lodash":"lodash","react":"react"}],18:[function(require,module,exports){ +},{"../utils.js":26,"./common.js":4,"lodash":"lodash","react":"react","react-dom":"react-dom"}],18:[function(require,module,exports){ "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.app = undefined; + +var _reactRouter = require("react-router"); + var React = require("react"); +var ReactDOM = require("react-dom"); var ReactRouter = require("react-router"); var _ = require("lodash"); @@ -3576,7 +3559,8 @@ var ProxyAppMain = React.createClass({ settingsStore: React.PropTypes.object.isRequired, flowStore: React.PropTypes.object.isRequired, eventStore: React.PropTypes.object.isRequired, - returnFocus: React.PropTypes.func.isRequired + returnFocus: React.PropTypes.func.isRequired, + routerFoo: React.PropTypes.object }, componentDidMount: function componentDidMount() { this.focus(); @@ -3586,7 +3570,11 @@ var ProxyAppMain = React.createClass({ settingsStore: this.state.settingsStore, flowStore: this.state.flowStore, eventStore: this.state.eventStore, - returnFocus: this.focus + returnFocus: this.focus, + routerFoo: { + location: this.props.location, + params: this.props.params + } }; }, getInitialState: function getInitialState() { @@ -3603,19 +3591,19 @@ var ProxyAppMain = React.createClass({ }; }, focus: function focus() { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, getMainComponent: function getMainComponent() { - return this.refs.view.refs.__routeHandler__; + return this.refs.view; }, onKeydown: function onKeydown(e) { - var selectFilterInput = (function (name) { + var selectFilterInput = function (name) { var headerComponent = this.refs.header; headerComponent.setState({ active: header.MainMenu }, function () { headerComponent.refs.active.refs[name].select(); }); - }).bind(this); + }.bind(this); switch (e.keyCode) { case Key.I: @@ -3638,48 +3626,55 @@ var ProxyAppMain = React.createClass({ }, render: function render() { var eventlog; - if (this.getQuery()[Query.SHOW_EVENTLOG]) { + if (this.props.location.query[Query.SHOW_EVENTLOG]) { eventlog = [React.createElement(common.Splitter, { key: "splitter", axis: "y" }), React.createElement(EventLog, { key: "eventlog" })]; } else { eventlog = null; } + var children = React.cloneElement(this.props.children, { ref: "view", query: this.props.location.query }); return React.createElement( "div", { id: "container", tabIndex: "0", onKeyDown: this.onKeydown }, React.createElement(header.Header, { ref: "header" }), - React.createElement(RouteHandler, { ref: "view", query: this.getQuery() }), + children, eventlog, React.createElement(Footer, null) ); } }); -var Route = ReactRouter.Route; -var RouteHandler = ReactRouter.RouteHandler; -var Redirect = ReactRouter.Redirect; -var DefaultRoute = ReactRouter.DefaultRoute; -var NotFoundRoute = ReactRouter.NotFoundRoute; - -var routes = React.createElement( - Route, - { path: "/", handler: ProxyAppMain }, - React.createElement(Route, { name: "flows", path: "flows", handler: MainView }), - React.createElement(Route, { name: "flow", path: "flows/:flowId/:detailTab", handler: MainView }), - React.createElement(Route, { name: "reports", handler: Reports }), - React.createElement(Redirect, { path: "/", to: "flows" }) +var app = exports.app = React.createElement( + _reactRouter.Router, + { history: _reactRouter.hashHistory }, + React.createElement(_reactRouter.Redirect, { from: "/", to: "/flows" }), + React.createElement( + _reactRouter.Route, + { path: "/", component: ProxyAppMain }, + React.createElement(_reactRouter.Route, { path: "flows", component: MainView }), + React.createElement(_reactRouter.Route, { path: "flows/:flowId/:detailTab", component: MainView }), + React.createElement(_reactRouter.Route, { path: "reports", component: Reports }) + ) ); -module.exports = { - routes: routes -}; +},{"../actions.js":2,"../store/store.js":24,"../utils.js":26,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":16,"lodash":"lodash","react":"react","react-dom":"react-dom","react-router":"react-router"}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.VirtualScrollMixin = undefined; -},{"../actions.js":2,"../store/store.js":24,"../utils.js":26,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":16,"lodash":"lodash","react":"react","react-router":"react-router"}],19:[function(require,module,exports){ -"use strict"; +var _react = require("react"); -var React = require("react"); +var _react2 = _interopRequireDefault(_react); -var VirtualScrollMixin = { +var _reactDom = require("react-dom"); + +var _reactDom2 = _interopRequireDefault(_reactDom); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var VirtualScrollMixin = exports.VirtualScrollMixin = { getInitialState: function getInitialState() { return { start: 0, @@ -3698,11 +3693,11 @@ var VirtualScrollMixin = { var style = { height: Math.min(this.state.start, total) * this.props.rowHeight }; - var spacer = React.createElement(Tag, { key: "placeholder-top", style: style }); + var spacer = _react2.default.createElement(Tag, { key: "placeholder-top", style: style }); if (this.state.start % 2 === 1) { // fix even/odd rows - return [spacer, React.createElement(Tag, { key: "placeholder-top-2" })]; + return [spacer, _react2.default.createElement(Tag, { key: "placeholder-top-2" })]; } else { return spacer; } @@ -3712,7 +3707,7 @@ var VirtualScrollMixin = { var style = { height: Math.max(0, total - this.state.stop) * this.props.rowHeight }; - return React.createElement(Tag, { key: "placeholder-bottom", style: style }); + return _react2.default.createElement(Tag, { key: "placeholder-bottom", style: style }); }, componentDidMount: function componentDidMount() { this.onScroll(); @@ -3722,7 +3717,7 @@ var VirtualScrollMixin = { window.removeEventListener('resize', this.onScroll); }, onScroll: function onScroll() { - var viewport = this.getDOMNode(); + var viewport = _reactDom2.default.findDOMNode(this); var top = viewport.scrollTop; var height = viewport.offsetHeight; var start = Math.floor(top / this.props.rowHeight); @@ -3748,7 +3743,7 @@ var VirtualScrollMixin = { var row_top = index * this.props.rowHeight + head_height; var row_bottom = row_top + this.props.rowHeight; - var viewport = this.getDOMNode(); + var viewport = _reactDom2.default.findDOMNode(this); var viewport_top = viewport.scrollTop; var viewport_bottom = viewport_top + viewport.offsetHeight; @@ -3761,10 +3756,7 @@ var VirtualScrollMixin = { } }; -module.exports = VirtualScrollMixin; - - -},{"react":"react"}],20:[function(require,module,exports){ +},{"react":"react","react-dom":"react-dom"}],20:[function(require,module,exports){ "use strict"; var actions = require("./actions.js"); @@ -3796,7 +3788,6 @@ function Connection(url) { module.exports = Connection; - },{"./actions.js":2,"./dispatcher.js":21}],21:[function(require,module,exports){ "use strict"; @@ -3821,15 +3812,16 @@ module.exports = { AppDispatcher: AppDispatcher }; - },{"flux":"flux"}],22:[function(require,module,exports){ "use strict"; -module.exports = (function () { +module.exports = function () { + "use strict"; + /* - * Generated by PEG.js 0.8.0. + * Generated by PEG.js 0.9.0. * - * http://pegjs.majda.cz/ + * http://pegjs.org/ */ function peg$subclass(child, parent) { @@ -3840,191 +3832,185 @@ module.exports = (function () { child.prototype = new ctor(); } - function SyntaxError(message, expected, found, offset, line, column) { + function peg$SyntaxError(message, expected, found, location) { this.message = message; this.expected = expected; this.found = found; - this.offset = offset; - this.line = line; - this.column = column; - + this.location = location; this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError); + } } - peg$subclass(SyntaxError, Error); + peg$subclass(peg$SyntaxError, Error); - function parse(input) { + function peg$parse(input) { var options = arguments.length > 1 ? arguments[1] : {}, + parser = this, peg$FAILED = {}, peg$startRuleFunctions = { start: peg$parsestart }, peg$startRuleFunction = peg$parsestart, peg$c0 = { type: "other", description: "filter expression" }, - peg$c1 = peg$FAILED, - peg$c2 = function peg$c2(orExpr) { + peg$c1 = function peg$c1(orExpr) { return orExpr; }, - peg$c3 = [], - peg$c4 = function peg$c4() { - return trueFilter; - }, - peg$c5 = { type: "other", description: "whitespace" }, - peg$c6 = /^[ \t\n\r]/, - peg$c7 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, - peg$c8 = { type: "other", description: "control character" }, - peg$c9 = /^[|&!()~"]/, - peg$c10 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, - peg$c11 = { type: "other", description: "optional whitespace" }, - peg$c12 = "|", - peg$c13 = { type: "literal", value: "|", description: "\"|\"" }, - peg$c14 = function peg$c14(first, second) { + peg$c2 = { type: "other", description: "whitespace" }, + peg$c3 = /^[ \t\n\r]/, + peg$c4 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, + peg$c5 = { type: "other", description: "control character" }, + peg$c6 = /^[|&!()~"]/, + peg$c7 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, + peg$c8 = { type: "other", description: "optional whitespace" }, + peg$c9 = "|", + peg$c10 = { type: "literal", value: "|", description: "\"|\"" }, + peg$c11 = function peg$c11(first, second) { return or(first, second); }, - peg$c15 = "&", - peg$c16 = { type: "literal", value: "&", description: "\"&\"" }, - peg$c17 = function peg$c17(first, second) { + peg$c12 = "&", + peg$c13 = { type: "literal", value: "&", description: "\"&\"" }, + peg$c14 = function peg$c14(first, second) { return and(first, second); }, - peg$c18 = "!", - peg$c19 = { type: "literal", value: "!", description: "\"!\"" }, - peg$c20 = function peg$c20(expr) { + peg$c15 = "!", + peg$c16 = { type: "literal", value: "!", description: "\"!\"" }, + peg$c17 = function peg$c17(expr) { return not(expr); }, - peg$c21 = "(", - peg$c22 = { type: "literal", value: "(", description: "\"(\"" }, - peg$c23 = ")", - peg$c24 = { type: "literal", value: ")", description: "\")\"" }, - peg$c25 = function peg$c25(expr) { + peg$c18 = "(", + peg$c19 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c20 = ")", + peg$c21 = { type: "literal", value: ")", description: "\")\"" }, + peg$c22 = function peg$c22(expr) { return binding(expr); }, - peg$c26 = "~a", - peg$c27 = { type: "literal", value: "~a", description: "\"~a\"" }, - peg$c28 = function peg$c28() { + peg$c23 = "~a", + peg$c24 = { type: "literal", value: "~a", description: "\"~a\"" }, + peg$c25 = function peg$c25() { return assetFilter; }, - peg$c29 = "~e", - peg$c30 = { type: "literal", value: "~e", description: "\"~e\"" }, - peg$c31 = function peg$c31() { + peg$c26 = "~e", + peg$c27 = { type: "literal", value: "~e", description: "\"~e\"" }, + peg$c28 = function peg$c28() { return errorFilter; }, - peg$c32 = "~q", - peg$c33 = { type: "literal", value: "~q", description: "\"~q\"" }, - peg$c34 = function peg$c34() { + peg$c29 = "~q", + peg$c30 = { type: "literal", value: "~q", description: "\"~q\"" }, + peg$c31 = function peg$c31() { return noResponseFilter; }, - peg$c35 = "~s", - peg$c36 = { type: "literal", value: "~s", description: "\"~s\"" }, - peg$c37 = function peg$c37() { + peg$c32 = "~s", + peg$c33 = { type: "literal", value: "~s", description: "\"~s\"" }, + peg$c34 = function peg$c34() { return responseFilter; }, - peg$c38 = "true", - peg$c39 = { type: "literal", value: "true", description: "\"true\"" }, - peg$c40 = function peg$c40() { + peg$c35 = "true", + peg$c36 = { type: "literal", value: "true", description: "\"true\"" }, + peg$c37 = function peg$c37() { return trueFilter; }, - peg$c41 = "false", - peg$c42 = { type: "literal", value: "false", description: "\"false\"" }, - peg$c43 = function peg$c43() { + peg$c38 = "false", + peg$c39 = { type: "literal", value: "false", description: "\"false\"" }, + peg$c40 = function peg$c40() { return falseFilter; }, - peg$c44 = "~c", - peg$c45 = { type: "literal", value: "~c", description: "\"~c\"" }, - peg$c46 = function peg$c46(s) { + peg$c41 = "~c", + peg$c42 = { type: "literal", value: "~c", description: "\"~c\"" }, + peg$c43 = function peg$c43(s) { return responseCode(s); }, - peg$c47 = "~d", - peg$c48 = { type: "literal", value: "~d", description: "\"~d\"" }, - peg$c49 = function peg$c49(s) { + peg$c44 = "~d", + peg$c45 = { type: "literal", value: "~d", description: "\"~d\"" }, + peg$c46 = function peg$c46(s) { return domain(s); }, - peg$c50 = "~h", - peg$c51 = { type: "literal", value: "~h", description: "\"~h\"" }, - peg$c52 = function peg$c52(s) { + peg$c47 = "~h", + peg$c48 = { type: "literal", value: "~h", description: "\"~h\"" }, + peg$c49 = function peg$c49(s) { return header(s); }, - peg$c53 = "~hq", - peg$c54 = { type: "literal", value: "~hq", description: "\"~hq\"" }, - peg$c55 = function peg$c55(s) { + peg$c50 = "~hq", + peg$c51 = { type: "literal", value: "~hq", description: "\"~hq\"" }, + peg$c52 = function peg$c52(s) { return requestHeader(s); }, - peg$c56 = "~hs", - peg$c57 = { type: "literal", value: "~hs", description: "\"~hs\"" }, - peg$c58 = function peg$c58(s) { + peg$c53 = "~hs", + peg$c54 = { type: "literal", value: "~hs", description: "\"~hs\"" }, + peg$c55 = function peg$c55(s) { return responseHeader(s); }, - peg$c59 = "~m", - peg$c60 = { type: "literal", value: "~m", description: "\"~m\"" }, - peg$c61 = function peg$c61(s) { + peg$c56 = "~m", + peg$c57 = { type: "literal", value: "~m", description: "\"~m\"" }, + peg$c58 = function peg$c58(s) { return method(s); }, - peg$c62 = "~t", - peg$c63 = { type: "literal", value: "~t", description: "\"~t\"" }, - peg$c64 = function peg$c64(s) { + peg$c59 = "~t", + peg$c60 = { type: "literal", value: "~t", description: "\"~t\"" }, + peg$c61 = function peg$c61(s) { return contentType(s); }, - peg$c65 = "~tq", - peg$c66 = { type: "literal", value: "~tq", description: "\"~tq\"" }, - peg$c67 = function peg$c67(s) { + peg$c62 = "~tq", + peg$c63 = { type: "literal", value: "~tq", description: "\"~tq\"" }, + peg$c64 = function peg$c64(s) { return requestContentType(s); }, - peg$c68 = "~ts", - peg$c69 = { type: "literal", value: "~ts", description: "\"~ts\"" }, - peg$c70 = function peg$c70(s) { + peg$c65 = "~ts", + peg$c66 = { type: "literal", value: "~ts", description: "\"~ts\"" }, + peg$c67 = function peg$c67(s) { return responseContentType(s); }, - peg$c71 = "~u", - peg$c72 = { type: "literal", value: "~u", description: "\"~u\"" }, - peg$c73 = function peg$c73(s) { + peg$c68 = "~u", + peg$c69 = { type: "literal", value: "~u", description: "\"~u\"" }, + peg$c70 = function peg$c70(s) { return url(s); }, - peg$c74 = { type: "other", description: "integer" }, - peg$c75 = null, - peg$c76 = /^['"]/, - peg$c77 = { type: "class", value: "['\"]", description: "['\"]" }, - peg$c78 = /^[0-9]/, - peg$c79 = { type: "class", value: "[0-9]", description: "[0-9]" }, - peg$c80 = function peg$c80(digits) { + peg$c71 = { type: "other", description: "integer" }, + peg$c72 = /^['"]/, + peg$c73 = { type: "class", value: "['\"]", description: "['\"]" }, + peg$c74 = /^[0-9]/, + peg$c75 = { type: "class", value: "[0-9]", description: "[0-9]" }, + peg$c76 = function peg$c76(digits) { return parseInt(digits.join(""), 10); }, - peg$c81 = { type: "other", description: "string" }, - peg$c82 = "\"", - peg$c83 = { type: "literal", value: "\"", description: "\"\\\"\"" }, - peg$c84 = function peg$c84(chars) { + peg$c77 = { type: "other", description: "string" }, + peg$c78 = "\"", + peg$c79 = { type: "literal", value: "\"", description: "\"\\\"\"" }, + peg$c80 = function peg$c80(chars) { return chars.join(""); }, - peg$c85 = "'", - peg$c86 = { type: "literal", value: "'", description: "\"'\"" }, - peg$c87 = void 0, - peg$c88 = /^["\\]/, - peg$c89 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, - peg$c90 = { type: "any", description: "any character" }, - peg$c91 = function peg$c91(char) { + peg$c81 = "'", + peg$c82 = { type: "literal", value: "'", description: "\"'\"" }, + peg$c83 = /^["\\]/, + peg$c84 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, + peg$c85 = { type: "any", description: "any character" }, + peg$c86 = function peg$c86(char) { return char; }, - peg$c92 = "\\", - peg$c93 = { type: "literal", value: "\\", description: "\"\\\\\"" }, - peg$c94 = /^['\\]/, - peg$c95 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, - peg$c96 = /^['"\\]/, - peg$c97 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, - peg$c98 = "n", - peg$c99 = { type: "literal", value: "n", description: "\"n\"" }, - peg$c100 = function peg$c100() { + peg$c87 = "\\", + peg$c88 = { type: "literal", value: "\\", description: "\"\\\\\"" }, + peg$c89 = /^['\\]/, + peg$c90 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, + peg$c91 = /^['"\\]/, + peg$c92 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, + peg$c93 = "n", + peg$c94 = { type: "literal", value: "n", description: "\"n\"" }, + peg$c95 = function peg$c95() { return "\n"; }, - peg$c101 = "r", - peg$c102 = { type: "literal", value: "r", description: "\"r\"" }, - peg$c103 = function peg$c103() { + peg$c96 = "r", + peg$c97 = { type: "literal", value: "r", description: "\"r\"" }, + peg$c98 = function peg$c98() { return "\r"; }, - peg$c104 = "t", - peg$c105 = { type: "literal", value: "t", description: "\"t\"" }, - peg$c106 = function peg$c106() { + peg$c99 = "t", + peg$c100 = { type: "literal", value: "t", description: "\"t\"" }, + peg$c101 = function peg$c101() { return "\t"; }, peg$currPos = 0, - peg$reportedPos = 0, - peg$cachedPos = 0, - peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$savedPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, @@ -4039,34 +4025,42 @@ module.exports = (function () { } function text() { - return input.substring(peg$reportedPos, peg$currPos); - } - - function offset() { - return peg$reportedPos; - } - - function line() { - return peg$computePosDetails(peg$reportedPos).line; + return input.substring(peg$savedPos, peg$currPos); } - function column() { - return peg$computePosDetails(peg$reportedPos).column; + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); } function expected(description) { - throw peg$buildException(null, [{ type: "other", description: description }], peg$reportedPos); + throw peg$buildException(null, [{ type: "other", description: description }], input.substring(peg$savedPos, peg$currPos), peg$computeLocation(peg$savedPos, peg$currPos)); } function error(message) { - throw peg$buildException(message, null, peg$reportedPos); + throw peg$buildException(message, null, input.substring(peg$savedPos, peg$currPos), peg$computeLocation(peg$savedPos, peg$currPos)); } function peg$computePosDetails(pos) { - function advance(details, startPos, endPos) { - var p, ch; + var details = peg$posDetailsCache[pos], + p, + ch; - for (p = startPos; p < endPos; p++) { + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column, + seenCR: details.seenCR + }; + + while (p < pos) { ch = input.charAt(p); if (ch === "\n") { if (!details.seenCR) { @@ -4082,19 +4076,31 @@ module.exports = (function () { details.column++; details.seenCR = false; } - } - } - if (peg$cachedPos !== pos) { - if (peg$cachedPos > pos) { - peg$cachedPos = 0; - peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + p++; } - advance(peg$cachedPosDetails, peg$cachedPos, pos); - peg$cachedPos = pos; + + peg$posDetailsCache[pos] = details; + return details; } + } - return peg$cachedPosDetails; + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; } function peg$fail(expected) { @@ -4110,7 +4116,7 @@ module.exports = (function () { peg$maxFailExpected.push(expected); } - function peg$buildException(message, expected, pos) { + function peg$buildException(message, expected, found, location) { function cleanupExpected(expected) { var i = 1; @@ -4143,9 +4149,9 @@ module.exports = (function () { return '\\x0' + hex(ch); }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) { return '\\x' + hex(ch); - }).replace(/[\u0180-\u0FFF]/g, function (ch) { + }).replace(/[\u0100-\u0FFF]/g, function (ch) { return "\\u0" + hex(ch); - }).replace(/[\u1080-\uFFFF]/g, function (ch) { + }).replace(/[\u1000-\uFFFF]/g, function (ch) { return "\\u" + hex(ch); }); } @@ -4166,14 +4172,11 @@ module.exports = (function () { return "Expected " + expectedDesc + " but " + foundDesc + " found."; } - var posDetails = peg$computePosDetails(pos), - found = pos < input.length ? input.charAt(pos) : null; - if (expected !== null) { cleanupExpected(expected); } - return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column); + return new peg$SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, location); } function peg$parsestart() { @@ -4187,29 +4190,20 @@ module.exports = (function () { if (s2 !== peg$FAILED) { s3 = peg$parse__(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c2(s2); + peg$savedPos = s0; + s1 = peg$c1(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = []; - if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c4(); - } - s0 = s1; + s0 = peg$FAILED; } peg$silentFails--; if (s0 === peg$FAILED) { @@ -4226,20 +4220,20 @@ module.exports = (function () { var s0, s1; peg$silentFails++; - if (peg$c6.test(input.charAt(peg$currPos))) { + if (peg$c3.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c7); + peg$fail(peg$c4); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c5); + peg$fail(peg$c2); } } @@ -4250,20 +4244,20 @@ module.exports = (function () { var s0, s1; peg$silentFails++; - if (peg$c9.test(input.charAt(peg$currPos))) { + if (peg$c6.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c10); + peg$fail(peg$c7); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c8); + peg$fail(peg$c5); } } @@ -4284,7 +4278,7 @@ module.exports = (function () { if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c11); + peg$fail(peg$c8); } } @@ -4300,12 +4294,12 @@ module.exports = (function () { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c12; + s3 = peg$c9; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c13); + peg$fail(peg$c10); } } if (s3 !== peg$FAILED) { @@ -4313,28 +4307,28 @@ module.exports = (function () { if (s4 !== peg$FAILED) { s5 = peg$parseOrExpr(); if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c14(s1, s5); + peg$savedPos = s0; + s1 = peg$c11(s1, s5); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseAndExpr(); @@ -4352,12 +4346,12 @@ module.exports = (function () { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 38) { - s3 = peg$c15; + s3 = peg$c12; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c16); + peg$fail(peg$c13); } } if (s3 !== peg$FAILED) { @@ -4365,28 +4359,28 @@ module.exports = (function () { if (s4 !== peg$FAILED) { s5 = peg$parseAndExpr(); if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c17(s1, s5); + peg$savedPos = s0; + s1 = peg$c14(s1, s5); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; @@ -4400,25 +4394,25 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseAndExpr(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c17(s1, s3); + peg$savedPos = s0; + s1 = peg$c14(s1, s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseNotExpr(); @@ -4433,12 +4427,12 @@ module.exports = (function () { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c18; + s1 = peg$c15; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c19); + peg$fail(peg$c16); } } if (s1 !== peg$FAILED) { @@ -4446,20 +4440,20 @@ module.exports = (function () { if (s2 !== peg$FAILED) { s3 = peg$parseNotExpr(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c20(s3); + peg$savedPos = s0; + s1 = peg$c17(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseBindingExpr(); @@ -4473,12 +4467,12 @@ module.exports = (function () { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c21; + s1 = peg$c18; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c22); + peg$fail(peg$c19); } } if (s1 !== peg$FAILED) { @@ -4489,37 +4483,37 @@ module.exports = (function () { s4 = peg$parse__(); if (s4 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c23; + s5 = peg$c20; peg$currPos++; } else { s5 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c24); + peg$fail(peg$c21); } } if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c25(s3); + peg$savedPos = s0; + s1 = peg$c22(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseExpr(); @@ -4545,66 +4539,66 @@ module.exports = (function () { s0 = peg$parseBooleanLiteral(); if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c26) { - s1 = peg$c26; + if (input.substr(peg$currPos, 2) === peg$c23) { + s1 = peg$c23; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c27); + peg$fail(peg$c24); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c28(); + peg$savedPos = s0; + s1 = peg$c25(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c29) { - s1 = peg$c29; + if (input.substr(peg$currPos, 2) === peg$c26) { + s1 = peg$c26; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c30); + peg$fail(peg$c27); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c31(); + peg$savedPos = s0; + s1 = peg$c28(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c32) { - s1 = peg$c32; + if (input.substr(peg$currPos, 2) === peg$c29) { + s1 = peg$c29; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c33); + peg$fail(peg$c30); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c34(); + peg$savedPos = s0; + s1 = peg$c31(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c35) { - s1 = peg$c35; + if (input.substr(peg$currPos, 2) === peg$c32) { + s1 = peg$c32; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c36); + peg$fail(peg$c33); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c37(); + peg$savedPos = s0; + s1 = peg$c34(); } s0 = s1; } @@ -4619,34 +4613,34 @@ module.exports = (function () { var s0, s1; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c38) { - s1 = peg$c38; + if (input.substr(peg$currPos, 4) === peg$c35) { + s1 = peg$c35; peg$currPos += 4; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c39); + peg$fail(peg$c36); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c40(); + peg$savedPos = s0; + s1 = peg$c37(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c41) { - s1 = peg$c41; + if (input.substr(peg$currPos, 5) === peg$c38) { + s1 = peg$c38; peg$currPos += 5; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c42); + peg$fail(peg$c39); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c43(); + peg$savedPos = s0; + s1 = peg$c40(); } s0 = s1; } @@ -4658,13 +4652,13 @@ module.exports = (function () { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c44) { - s1 = peg$c44; + if (input.substr(peg$currPos, 2) === peg$c41) { + s1 = peg$c41; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c45); + peg$fail(peg$c42); } } if (s1 !== peg$FAILED) { @@ -4676,35 +4670,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseIntegerLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c46(s3); + peg$savedPos = s0; + s1 = peg$c43(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c47) { - s1 = peg$c47; + if (input.substr(peg$currPos, 2) === peg$c44) { + s1 = peg$c44; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c48); + peg$fail(peg$c45); } } if (s1 !== peg$FAILED) { @@ -4716,35 +4710,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c49(s3); + peg$savedPos = s0; + s1 = peg$c46(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c50) { - s1 = peg$c50; + if (input.substr(peg$currPos, 2) === peg$c47) { + s1 = peg$c47; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c51); + peg$fail(peg$c48); } } if (s1 !== peg$FAILED) { @@ -4756,35 +4750,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c52(s3); + peg$savedPos = s0; + s1 = peg$c49(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c53) { - s1 = peg$c53; + if (input.substr(peg$currPos, 3) === peg$c50) { + s1 = peg$c50; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c54); + peg$fail(peg$c51); } } if (s1 !== peg$FAILED) { @@ -4796,35 +4790,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c55(s3); + peg$savedPos = s0; + s1 = peg$c52(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c56) { - s1 = peg$c56; + if (input.substr(peg$currPos, 3) === peg$c53) { + s1 = peg$c53; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c57); + peg$fail(peg$c54); } } if (s1 !== peg$FAILED) { @@ -4836,35 +4830,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c58(s3); + peg$savedPos = s0; + s1 = peg$c55(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c59) { - s1 = peg$c59; + if (input.substr(peg$currPos, 2) === peg$c56) { + s1 = peg$c56; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c60); + peg$fail(peg$c57); } } if (s1 !== peg$FAILED) { @@ -4876,35 +4870,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c61(s3); + peg$savedPos = s0; + s1 = peg$c58(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c62) { - s1 = peg$c62; + if (input.substr(peg$currPos, 2) === peg$c59) { + s1 = peg$c59; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c63); + peg$fail(peg$c60); } } if (s1 !== peg$FAILED) { @@ -4916,35 +4910,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c64(s3); + peg$savedPos = s0; + s1 = peg$c61(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c65) { - s1 = peg$c65; + if (input.substr(peg$currPos, 3) === peg$c62) { + s1 = peg$c62; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c66); + peg$fail(peg$c63); } } if (s1 !== peg$FAILED) { @@ -4956,35 +4950,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c67(s3); + peg$savedPos = s0; + s1 = peg$c64(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c68) { - s1 = peg$c68; + if (input.substr(peg$currPos, 3) === peg$c65) { + s1 = peg$c65; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c69); + peg$fail(peg$c66); } } if (s1 !== peg$FAILED) { @@ -4996,35 +4990,35 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c70(s3); + peg$savedPos = s0; + s1 = peg$c67(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c71) { - s1 = peg$c71; + if (input.substr(peg$currPos, 2) === peg$c68) { + s1 = peg$c68; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c72); + peg$fail(peg$c69); } } if (s1 !== peg$FAILED) { @@ -5036,32 +5030,32 @@ module.exports = (function () { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c73(s3); + peg$savedPos = s0; + s1 = peg$c70(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = peg$parseStringLiteral(); if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c73(s1); + peg$savedPos = s0; + s1 = peg$c70(s1); } s0 = s1; } @@ -5083,79 +5077,79 @@ module.exports = (function () { peg$silentFails++; s0 = peg$currPos; - if (peg$c76.test(input.charAt(peg$currPos))) { + if (peg$c72.test(input.charAt(peg$currPos))) { s1 = input.charAt(peg$currPos); peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c77); + peg$fail(peg$c73); } } if (s1 === peg$FAILED) { - s1 = peg$c75; + s1 = null; } if (s1 !== peg$FAILED) { s2 = []; - if (peg$c78.test(input.charAt(peg$currPos))) { + if (peg$c74.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c79); + peg$fail(peg$c75); } } if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); - if (peg$c78.test(input.charAt(peg$currPos))) { + if (peg$c74.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c79); + peg$fail(peg$c75); } } } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { - if (peg$c76.test(input.charAt(peg$currPos))) { + if (peg$c72.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c77); + peg$fail(peg$c73); } } if (s3 === peg$FAILED) { - s3 = peg$c75; + s3 = null; } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c80(s2); + peg$savedPos = s0; + s1 = peg$c76(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c74); + peg$fail(peg$c71); } } @@ -5168,12 +5162,12 @@ module.exports = (function () { peg$silentFails++; s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c82; + s1 = peg$c78; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c83); + peg$fail(peg$c79); } } if (s1 !== peg$FAILED) { @@ -5185,39 +5179,39 @@ module.exports = (function () { } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c82; + s3 = peg$c78; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c83); + peg$fail(peg$c79); } } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c85; + s1 = peg$c81; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c86); + peg$fail(peg$c82); } } if (s1 !== peg$FAILED) { @@ -5229,29 +5223,29 @@ module.exports = (function () { } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c85; + s3 = peg$c81; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c86); + peg$fail(peg$c82); } } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; @@ -5260,10 +5254,10 @@ module.exports = (function () { s2 = peg$parsecc(); peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { s2 = []; @@ -5274,19 +5268,19 @@ module.exports = (function () { s3 = peg$parseUnquotedStringChar(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } } @@ -5294,7 +5288,7 @@ module.exports = (function () { if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c81); + peg$fail(peg$c77); } } @@ -5307,21 +5301,21 @@ module.exports = (function () { s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; - if (peg$c88.test(input.charAt(peg$currPos))) { + if (peg$c83.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c89); + peg$fail(peg$c84); } } peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -5330,45 +5324,45 @@ module.exports = (function () { } else { s2 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c90); + peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c92; + s1 = peg$c87; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c93); + peg$fail(peg$c88); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } @@ -5381,21 +5375,21 @@ module.exports = (function () { s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; - if (peg$c94.test(input.charAt(peg$currPos))) { + if (peg$c89.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c95); + peg$fail(peg$c90); } } peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -5404,45 +5398,45 @@ module.exports = (function () { } else { s2 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c90); + peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c92; + s1 = peg$c87; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c93); + peg$fail(peg$c88); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } @@ -5458,10 +5452,10 @@ module.exports = (function () { s2 = peg$parsews(); peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -5470,20 +5464,20 @@ module.exports = (function () { } else { s2 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c90); + peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } return s0; @@ -5492,61 +5486,61 @@ module.exports = (function () { function peg$parseEscapeSequence() { var s0, s1; - if (peg$c96.test(input.charAt(peg$currPos))) { + if (peg$c91.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c97); + peg$fail(peg$c92); } } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 110) { - s1 = peg$c98; + s1 = peg$c93; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c99); + peg$fail(peg$c94); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c100(); + peg$savedPos = s0; + s1 = peg$c95(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 114) { - s1 = peg$c101; + s1 = peg$c96; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c102); + peg$fail(peg$c97); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c103(); + peg$savedPos = s0; + s1 = peg$c98(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 116) { - s1 = peg$c104; + s1 = peg$c99; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { - peg$fail(peg$c105); + peg$fail(peg$c100); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c106(); + peg$savedPos = s0; + s1 = peg$c101(); } s0 = s1; } @@ -5712,16 +5706,15 @@ module.exports = (function () { peg$fail({ type: "end", description: "end of input" }); } - throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)); } } return { - SyntaxError: SyntaxError, - parse: parse + SyntaxError: peg$SyntaxError, + parse: peg$parse }; -})(); - +}(); },{"../flow/utils.js":23}],23:[function(require,module,exports){ "use strict"; @@ -5854,7 +5847,6 @@ module.exports = { isValidHttpVersion: isValidHttpVersion }; - },{"jquery":"jquery","lodash":"lodash"}],24:[function(require,module,exports){ "use strict"; @@ -5971,11 +5963,11 @@ _.extend(LiveStoreMixin.prototype, { if (data) { this.handle_fetch(data); } else { - this._fetchxhr = $.getJSON("/" + this.type).done((function (message) { + this._fetchxhr = $.getJSON("/" + this.type).done(function (message) { this.handle_fetch(message.data); - }).bind(this)).fail((function () { + }.bind(this)).fail(function () { EventLogActions.add_event("Could not fetch " + this.type); - }).bind(this)); + }.bind(this)); } }, handle_fetch: function handle_fetch(data) { @@ -6020,9 +6012,9 @@ _.extend(EventLogStore.prototype, LiveListStore.prototype, { // Make sure to display updates even if fetching all events failed. // This way, we can send "fetch failed" log messages to the log. if (this._fetchxhr) { - this._fetchxhr.fail((function () { + this._fetchxhr.fail(function () { this.handle_fetch(null); - }).bind(this)); + }.bind(this)); } } }); @@ -6033,7 +6025,6 @@ module.exports = { FlowStore: FlowStore }; - },{"../actions.js":2,"../dispatcher.js":21,"../utils.js":26,"events":1,"jquery":"jquery","lodash":"lodash"}],25:[function(require,module,exports){ "use strict"; @@ -6156,7 +6147,6 @@ module.exports = { StoreView: StoreView }; - },{"../utils.js":26,"events":1,"lodash":"lodash"}],26:[function(require,module,exports){ "use strict"; @@ -6264,7 +6254,6 @@ module.exports = { Key: Key }; - },{"./actions.js":2,"jquery":"jquery","lodash":"lodash","react":"react"}]},{},[3]) diff --git a/mitmproxy/web/static/vendor.css b/mitmproxy/web/static/vendor.css index 4ed1f0b8..f8df478e 100644 --- a/mitmproxy/web/static/vendor.css +++ b/mitmproxy/web/static/vendor.css @@ -264,10 +264,10 @@ th { -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { - content: "\2a"; + content: "\002a"; } .glyphicon-plus:before { - content: "\2b"; + content: "\002b"; } .glyphicon-euro:before, .glyphicon-eur:before { @@ -2564,6 +2564,10 @@ output { .form-control::-webkit-input-placeholder { color: #999; } +.form-control::-ms-expand { + border: 0; + background-color: transparent; +} .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { @@ -2970,7 +2974,7 @@ select[multiple].input-lg { } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { - padding-top: 14.333333px; + padding-top: 11px; font-size: 18px; } } @@ -3077,9 +3081,6 @@ fieldset[disabled] a.btn { .open > .dropdown-toggle.btn-default { background-image: none; } -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, @@ -3088,13 +3089,7 @@ fieldset[disabled] .btn-default:hover, fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { +fieldset[disabled] .btn-default.focus { background-color: #fff; border-color: #ccc; } @@ -3143,9 +3138,6 @@ fieldset[disabled] .btn-default.active { .open > .dropdown-toggle.btn-primary { background-image: none; } -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, @@ -3154,13 +3146,7 @@ fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled.focus, .btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { +fieldset[disabled] .btn-primary.focus { background-color: #337ab7; border-color: #2e6da4; } @@ -3209,9 +3195,6 @@ fieldset[disabled] .btn-primary.active { .open > .dropdown-toggle.btn-success { background-image: none; } -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, @@ -3220,13 +3203,7 @@ fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, .btn-success.disabled.focus, .btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { +fieldset[disabled] .btn-success.focus { background-color: #5cb85c; border-color: #4cae4c; } @@ -3275,9 +3252,6 @@ fieldset[disabled] .btn-success.active { .open > .dropdown-toggle.btn-info { background-image: none; } -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, @@ -3286,13 +3260,7 @@ fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, .btn-info.disabled.focus, .btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { +fieldset[disabled] .btn-info.focus { background-color: #5bc0de; border-color: #46b8da; } @@ -3341,9 +3309,6 @@ fieldset[disabled] .btn-info.active { .open > .dropdown-toggle.btn-warning { background-image: none; } -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, @@ -3352,13 +3317,7 @@ fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled.focus, .btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { +fieldset[disabled] .btn-warning.focus { background-color: #f0ad4e; border-color: #eea236; } @@ -3407,9 +3366,6 @@ fieldset[disabled] .btn-warning.active { .open > .dropdown-toggle.btn-danger { background-image: none; } -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, @@ -3418,13 +3374,7 @@ fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled.focus, .btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { +fieldset[disabled] .btn-danger.focus { background-color: #d9534f; border-color: #d43f3a; } @@ -3795,13 +3745,15 @@ tbody.collapse.in { } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; + border-top-left-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { - border-bottom-left-radius: 4px; border-top-right-radius: 0; border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; @@ -3858,6 +3810,9 @@ tbody.collapse.in { width: 100%; margin-bottom: 0; } +.input-group .form-control:focus { + z-index: 3; +} .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { @@ -4768,7 +4723,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { - z-index: 3; + z-index: 2; color: #23527c; background-color: #eeeeee; border-color: #ddd; @@ -4779,7 +4734,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { - z-index: 2; + z-index: 3; color: #fff; background-color: #337ab7; border-color: #337ab7; @@ -5001,6 +4956,8 @@ a.badge:focus { .container .jumbotron, .container-fluid .jumbotron { border-radius: 6px; + padding-left: 15px; + padding-right: 15px; } .jumbotron .container { max-width: 100%; @@ -5947,7 +5904,6 @@ button.close { .modal-header { padding: 15px; border-bottom: 1px solid #e5e5e5; - min-height: 16.42857143px; } .modal-header .close { margin-top: -2px; @@ -6339,6 +6295,7 @@ button.close { color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0); } .carousel-control.left { background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); @@ -6448,16 +6405,16 @@ button.close { .carousel-control .icon-next { width: 30px; height: 30px; - margin-top: -15px; + margin-top: -10px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { - margin-left: -15px; + margin-left: -10px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { - margin-right: -15px; + margin-right: -10px; } .carousel-caption { left: 20%; @@ -6496,6 +6453,8 @@ button.close { .pager:after, .panel-body:before, .panel-body:after, +.modal-header:before, +.modal-header:after, .modal-footer:before, .modal-footer:after { content: " "; @@ -6515,6 +6474,7 @@ button.close { .navbar-collapse:after, .pager:after, .panel-body:after, +.modal-header:after, .modal-footer:after { clear: both; } diff --git a/mitmproxy/web/static/vendor.js b/mitmproxy/web/static/vendor.js index 59d10445..cc631d27 100644 --- a/mitmproxy/web/static/vendor.js +++ b/mitmproxy/web/static/vendor.js @@ -380,2931 +380,4734 @@ module.exports = invariant; }).call(this,require('_process')) },{"_process":1}],4:[function(require,module,exports){ -/** - * Represents a cancellation caused by navigating away - * before the previous transition has fully resolved. - */ "use strict"; -function Cancellation() {} +exports.__esModule = true; +var _slice = Array.prototype.slice; +exports.loopAsync = loopAsync; +exports.mapAsync = mapAsync; + +function loopAsync(turns, work, callback) { + var currentTurn = 0, + isDone = false; + var sync = false, + hasNext = false, + doneArgs = undefined; + + function done() { + isDone = true; + if (sync) { + // Iterate instead of recursing if possible. + doneArgs = [].concat(_slice.call(arguments)); + return; + } + + callback.apply(this, arguments); + } + + function next() { + if (isDone) { + return; + } + + hasNext = true; + if (sync) { + // Iterate instead of recursing if possible. + return; + } + + sync = true; + + while (!isDone && currentTurn < turns && hasNext) { + hasNext = false; + work.call(this, currentTurn++, next, done); + } + + sync = false; + + if (isDone) { + // This means the loop finished synchronously. + callback.apply(this, doneArgs); + return; + } + + if (currentTurn >= turns && hasNext) { + isDone = true; + callback(); + } + } + + next(); +} + +function mapAsync(array, work, callback) { + var length = array.length; + var values = []; -module.exports = Cancellation; + if (length === 0) return callback(null, values); + + var isDone = false, + doneCount = 0; + + function done(index, error, value) { + if (isDone) return; + + if (error) { + isDone = true; + callback(error); + } else { + values[index] = value; + + isDone = ++doneCount === length; + + if (isDone) callback(null, values); + } + } + + array.forEach(function (item, index) { + work(item, index, function (error, value) { + done(index, error, value); + }); + }); +} },{}],5:[function(require,module,exports){ +(function (process){ 'use strict'; -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +exports.__esModule = true; -var History = { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - /** - * The current number of entries in the history. - * - * Note: This property is read-only. - */ - length: 1, +var _routerWarning = require('./routerWarning'); - /** - * Sends the browser back one entry in the history. - */ - back: function back() { - invariant(canUseDOM, 'Cannot use History.back without a DOM'); +var _routerWarning2 = _interopRequireDefault(_routerWarning); - // Do this first so that History.length will - // be accurate in location change listeners. - History.length -= 1; +var _PropTypes = require('./PropTypes'); + +/** + * A mixin that adds the "history" instance variable to components. + */ +var History = { + + contextTypes: { + history: _PropTypes.history + }, - window.history.back(); + componentWillMount: function componentWillMount() { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'the `History` mixin is deprecated, please access `context.router` with your own `contextTypes`. http://tiny.cc/router-historymixin') : undefined; + this.history = this.context.history; } }; -module.exports = History; -},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],6:[function(require,module,exports){ +exports['default'] = History; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./PropTypes":12,"./routerWarning":34,"_process":1}],6:[function(require,module,exports){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -/* jshint -W084 */ -var PathUtils = require('./PathUtils'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -function deepSearch(route, pathname, query) { - // Check the subtree first to find the most deeply-nested match. - var childRoutes = route.childRoutes; - if (childRoutes) { - var match, childRoute; - for (var i = 0, len = childRoutes.length; i < len; ++i) { - childRoute = childRoutes[i]; +var _react = require('react'); - if (childRoute.isDefault || childRoute.isNotFound) continue; // Check these in order later. +var _react2 = _interopRequireDefault(_react); - if (match = deepSearch(childRoute, pathname, query)) { - // A route in the subtree matched! Add this route and we're done. - match.routes.unshift(route); - return match; +var _Link = require('./Link'); + +var _Link2 = _interopRequireDefault(_Link); + +/** + * An <IndexLink> is used to link to an <IndexRoute>. + */ +var IndexLink = _react2['default'].createClass({ + displayName: 'IndexLink', + + render: function render() { + return _react2['default'].createElement(_Link2['default'], _extends({}, this.props, { onlyActiveOnIndex: true })); + } + +}); + +exports['default'] = IndexLink; +module.exports = exports['default']; +},{"./Link":10,"react":"react"}],7:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _Redirect = require('./Redirect'); + +var _Redirect2 = _interopRequireDefault(_Redirect); + +var _PropTypes = require('./PropTypes'); + +var _React$PropTypes = _react2['default'].PropTypes; +var string = _React$PropTypes.string; +var object = _React$PropTypes.object; + +/** + * An <IndexRedirect> is used to redirect from an indexRoute. + */ +var IndexRedirect = _react2['default'].createClass({ + displayName: 'IndexRedirect', + + statics: { + + createRouteFromReactElement: function createRouteFromReactElement(element, parentRoute) { + /* istanbul ignore else: sanity check */ + if (parentRoute) { + parentRoute.indexRoute = _Redirect2['default'].createRouteFromReactElement(element); + } else { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'An <IndexRedirect> does not make sense at the root of your route config') : undefined; } } - } - // No child routes matched; try the default route. - var defaultRoute = route.defaultRoute; - if (defaultRoute && (params = PathUtils.extractParams(defaultRoute.path, pathname))) { - return new Match(pathname, params, query, [route, defaultRoute]); - } // Does the "not found" route match? - var notFoundRoute = route.notFoundRoute; - if (notFoundRoute && (params = PathUtils.extractParams(notFoundRoute.path, pathname))) { - return new Match(pathname, params, query, [route, notFoundRoute]); - } // Last attempt: check this route. - var params = PathUtils.extractParams(route.path, pathname); - if (params) { - return new Match(pathname, params, query, [route]); - }return null; -} + }, -var Match = (function () { - function Match(pathname, params, query, routes) { - _classCallCheck(this, Match); + propTypes: { + to: string.isRequired, + query: object, + state: object, + onEnter: _PropTypes.falsy, + children: _PropTypes.falsy + }, - this.pathname = pathname; - this.params = params; - this.query = query; - this.routes = routes; + /* istanbul ignore next: sanity check */ + render: function render() { + !false ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRedirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; } - _createClass(Match, null, [{ - key: 'findMatch', +}); - /** - * Attempts to match depth-first a route in the given route's - * subtree against the given path and returns the match if it - * succeeds, null if no match can be made. - */ - value: function findMatch(routes, path) { - var pathname = PathUtils.withoutQuery(path); - var query = PathUtils.extractQuery(path); - var match = null; +exports['default'] = IndexRedirect; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./PropTypes":12,"./Redirect":13,"./routerWarning":34,"_process":1,"invariant":58,"react":"react"}],8:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; - for (var i = 0, len = routes.length; match == null && i < len; ++i) match = deepSearch(routes[i], pathname, query); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - return match; +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _RouteUtils = require('./RouteUtils'); + +var _PropTypes = require('./PropTypes'); + +var func = _react2['default'].PropTypes.func; + +/** + * An <IndexRoute> is used to specify its parent's <Route indexRoute> in + * a JSX route config. + */ +var IndexRoute = _react2['default'].createClass({ + displayName: 'IndexRoute', + + statics: { + + createRouteFromReactElement: function createRouteFromReactElement(element, parentRoute) { + /* istanbul ignore else: sanity check */ + if (parentRoute) { + parentRoute.indexRoute = _RouteUtils.createRouteFromReactElement(element); + } else { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'An <IndexRoute> does not make sense at the root of your route config') : undefined; + } } - }]); - return Match; -})(); + }, + + propTypes: { + path: _PropTypes.falsy, + component: _PropTypes.component, + components: _PropTypes.components, + getComponent: func, + getComponents: func + }, + + /* istanbul ignore next: sanity check */ + render: function render() { + !false ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRoute> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; + } + +}); -module.exports = Match; -},{"./PathUtils":8}],7:[function(require,module,exports){ +exports['default'] = IndexRoute; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./PropTypes":12,"./RouteUtils":16,"./routerWarning":34,"_process":1,"invariant":58,"react":"react"}],9:[function(require,module,exports){ +(function (process){ 'use strict'; -var PropTypes = require('./PropTypes'); +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var object = _react2['default'].PropTypes.object; /** - * A mixin for components that modify the URL. + * The Lifecycle mixin adds the routerWillLeave lifecycle method to a + * component that may be used to cancel a transition or prompt the user + * for confirmation. * - * Example: + * On standard transitions, routerWillLeave receives a single argument: the + * location we're transitioning to. To cancel the transition, return false. + * To prompt the user for confirmation, return a prompt message (string). * - * var MyLink = React.createClass({ - * mixins: [ Router.Navigation ], - * handleClick(event) { - * event.preventDefault(); - * this.transitionTo('aRoute', { the: 'params' }, { the: 'query' }); - * }, - * render() { - * return ( - * <a onClick={this.handleClick}>Click me!</a> - * ); - * } - * }); + * During the beforeunload event (assuming you're using the useBeforeUnload + * history enhancer), routerWillLeave does not receive a location object + * because it isn't possible for us to know the location we're transitioning + * to. In this case routerWillLeave must return a prompt message to prevent + * the user from closing the window/tab. */ -var Navigation = { +var Lifecycle = { contextTypes: { - router: PropTypes.router.isRequired + history: object.isRequired, + // Nested children receive the route as context, either + // set by the route component using the RouteContext mixin + // or by some other ancestor. + route: object }, - /** - * Returns an absolute URL path created from the given route - * name, URL parameters, and query values. - */ - makePath: function makePath(to, params, query) { - return this.context.router.makePath(to, params, query); + propTypes: { + // Route components receive the route object as a prop. + route: object }, - /** - * Returns a string that may safely be used as the href of a - * link to the route with the given name. - */ - makeHref: function makeHref(to, params, query) { - return this.context.router.makeHref(to, params, query); - }, + componentDidMount: function componentDidMount() { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'the `Lifecycle` mixin is deprecated, please use `context.router.setRouteLeaveHook(route, hook)`. http://tiny.cc/router-lifecyclemixin') : undefined; + !this.routerWillLeave ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin requires you to define a routerWillLeave method') : _invariant2['default'](false) : undefined; - /** - * Transitions to the URL specified in the arguments by pushing - * a new URL onto the history stack. - */ - transitionTo: function transitionTo(to, params, query) { - this.context.router.transitionTo(to, params, query); - }, + var route = this.props.route || this.context.route; - /** - * Transitions to the URL specified in the arguments by replacing - * the current URL in the history stack. - */ - replaceWith: function replaceWith(to, params, query) { - this.context.router.replaceWith(to, params, query); + !route ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin must be used on either a) a <Route component> or ' + 'b) a descendant of a <Route component> that uses the RouteContext mixin') : _invariant2['default'](false) : undefined; + + this._unlistenBeforeLeavingRoute = this.context.history.listenBeforeLeavingRoute(route, this.routerWillLeave); }, - /** - * Transitions to the previous URL. - */ - goBack: function goBack() { - return this.context.router.goBack(); + componentWillUnmount: function componentWillUnmount() { + if (this._unlistenBeforeLeavingRoute) this._unlistenBeforeLeavingRoute(); } }; -module.exports = Navigation; -},{"./PropTypes":9}],8:[function(require,module,exports){ +exports['default'] = Lifecycle; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./routerWarning":34,"_process":1,"invariant":58,"react":"react"}],10:[function(require,module,exports){ +(function (process){ 'use strict'; -var invariant = require('react/lib/invariant'); -var assign = require('object-assign'); -var qs = require('qs'); +exports.__esModule = true; -var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; -var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; -var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?\/|\/\?/g; -var queryMatcher = /\?(.*)$/; +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 _compiledPatterns = {}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -function compilePattern(pattern) { - if (!(pattern in _compiledPatterns)) { - var paramNames = []; - var source = pattern.replace(paramCompileMatcher, function (match, paramName) { - if (paramName) { - paramNames.push(paramName); - return '([^/?#]+)'; - } else if (match === '*') { - paramNames.push('splat'); - return '(.*?)'; - } else { - return '\\' + match; - } - }); +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - _compiledPatterns[pattern] = { - matcher: new RegExp('^' + source + '$', 'i'), - paramNames: paramNames - }; +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _React$PropTypes = _react2['default'].PropTypes; +var bool = _React$PropTypes.bool; +var object = _React$PropTypes.object; +var string = _React$PropTypes.string; +var func = _React$PropTypes.func; +var oneOfType = _React$PropTypes.oneOfType; + +function isLeftClickEvent(event) { + return event.button === 0; +} + +function isModifiedEvent(event) { + return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); +} + +function isEmptyObject(object) { + for (var p in object) { + if (object.hasOwnProperty(p)) return false; + }return true; +} + +function createLocationDescriptor(to, _ref) { + var query = _ref.query; + var hash = _ref.hash; + var state = _ref.state; + + if (query || hash || state) { + return { pathname: to, query: query, hash: hash, state: state }; } - return _compiledPatterns[pattern]; + return to; } -var PathUtils = { +/** + * A <Link> is used to create an <a> element that links to a route. + * When that route is active, the link gets the value of its + * activeClassName prop. + * + * For example, assuming you have the following route: + * + * <Route path="/posts/:postID" component={Post} /> + * + * You could use the following component to link to that route: + * + * <Link to={`/posts/${post.id}`} /> + * + * Links may pass along location state and/or query string parameters + * in the state/query props, respectively. + * + * <Link ... query={{ show: true }} state={{ the: 'state' }} /> + */ +var Link = _react2['default'].createClass({ + displayName: 'Link', - /** - * Returns true if the given path is absolute. - */ - isAbsolute: function isAbsolute(path) { - return path.charAt(0) === '/'; + contextTypes: { + router: object }, - /** - * Joins two URL paths together. - */ - join: function join(a, b) { - return a.replace(/\/*$/, '/') + b; + propTypes: { + to: oneOfType([string, object]).isRequired, + query: object, + hash: string, + state: object, + activeStyle: object, + activeClassName: string, + onlyActiveOnIndex: bool.isRequired, + onClick: func }, - /** - * Returns an array of the names of all parameters in the given pattern. - */ - extractParamNames: function extractParamNames(pattern) { - return compilePattern(pattern).paramNames; + getDefaultProps: function getDefaultProps() { + return { + onlyActiveOnIndex: false, + className: '', + style: {} + }; }, - /** - * Extracts the portions of the given URL path that match the given pattern - * and returns an object of param name => value pairs. Returns null if the - * pattern does not match the given path. - */ - extractParams: function extractParams(pattern, path) { - var _compilePattern = compilePattern(pattern); + handleClick: function handleClick(event) { + var allowTransition = true; - var matcher = _compilePattern.matcher; - var paramNames = _compilePattern.paramNames; + if (this.props.onClick) this.props.onClick(event); - var match = path.match(matcher); + if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; - if (!match) { - return null; - }var params = {}; + if (event.defaultPrevented === true) allowTransition = false; - paramNames.forEach(function (paramName, index) { - params[paramName] = match[index + 1]; - }); + // If target prop is set (e.g. to "_blank") let browser handle link. + /* istanbul ignore if: untestable with Karma */ + if (this.props.target) { + if (!allowTransition) event.preventDefault(); - return params; + return; + } + + event.preventDefault(); + + if (allowTransition) { + var _props = this.props; + var to = _props.to; + var query = _props.query; + var hash = _props.hash; + var state = _props.state; + + var _location = createLocationDescriptor(to, { query: query, hash: hash, state: state }); + + this.context.router.push(_location); + } }, - /** - * Returns a version of the given route path with params interpolated. Throws - * if there is a dynamic segment of the route path for which there is no param. - */ - injectParams: function injectParams(pattern, params) { - params = params || {}; + render: function render() { + var _props2 = this.props; + var to = _props2.to; + var query = _props2.query; + var hash = _props2.hash; + var state = _props2.state; + var activeClassName = _props2.activeClassName; + var activeStyle = _props2.activeStyle; + var onlyActiveOnIndex = _props2.onlyActiveOnIndex; - var splatIndex = 0; + var props = _objectWithoutProperties(_props2, ['to', 'query', 'hash', 'state', 'activeClassName', 'activeStyle', 'onlyActiveOnIndex']); - return pattern.replace(paramInjectMatcher, function (match, paramName) { - paramName = paramName || 'splat'; + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](!(query || hash || state), 'the `query`, `hash`, and `state` props on `<Link>` are deprecated, use `<Link to={{ pathname, query, hash, state }}/>. http://tiny.cc/router-isActivedeprecated') : undefined; - // If param is optional don't check for existence - if (paramName.slice(-1) === '?') { - paramName = paramName.slice(0, -1); + // Ignore if rendered outside the context of router, simplifies unit testing. + var router = this.context.router; - if (params[paramName] == null) return ''; - } else { - invariant(params[paramName] != null, 'Missing "%s" parameter for path "%s"', paramName, pattern); - } + if (router) { + var _location2 = createLocationDescriptor(to, { query: query, hash: hash, state: state }); + props.href = router.createHref(_location2); - var segment; - if (paramName === 'splat' && Array.isArray(params[paramName])) { - segment = params[paramName][splatIndex++]; + if (activeClassName || activeStyle != null && !isEmptyObject(activeStyle)) { + if (router.isActive(_location2, onlyActiveOnIndex)) { + if (activeClassName) props.className += props.className === '' ? activeClassName : ' ' + activeClassName; - invariant(segment != null, 'Missing splat # %s for path "%s"', splatIndex, pattern); - } else { - segment = params[paramName]; + if (activeStyle) props.style = _extends({}, props.style, activeStyle); + } } + } - return segment; - }).replace(paramInjectTrailingSlashMatcher, '/'); - }, + return _react2['default'].createElement('a', _extends({}, props, { onClick: this.handleClick })); + } - /** - * Returns an object that is the result of parsing any query string contained - * in the given path, null if the path contains no query string. - */ - extractQuery: function extractQuery(path) { - var match = path.match(queryMatcher); - return match && qs.parse(match[1]); - }, +}); - /** - * Returns a version of the given path without the query string. - */ - withoutQuery: function withoutQuery(path) { - return path.replace(queryMatcher, ''); - }, +exports['default'] = Link; +module.exports = exports['default']; +}).call(this,require('_process')) - /** - * Returns a version of the given path with the parameters in the given - * query merged into the query string. - */ - withQuery: function withQuery(path, query) { - var existingQuery = PathUtils.extractQuery(path); +},{"./routerWarning":34,"_process":1,"react":"react"}],11:[function(require,module,exports){ +(function (process){ +'use strict'; - if (existingQuery) query = query ? assign(existingQuery, query) : existingQuery; +exports.__esModule = true; +exports.compilePattern = compilePattern; +exports.matchPattern = matchPattern; +exports.getParamNames = getParamNames; +exports.getParams = getParams; +exports.formatPattern = formatPattern; - var queryString = qs.stringify(query, { arrayFormat: 'brackets' }); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - if (queryString) { - return PathUtils.withoutQuery(path) + '?' + queryString; - }return PathUtils.withoutQuery(path); - } +var _invariant = require('invariant'); -}; +var _invariant2 = _interopRequireDefault(_invariant); -module.exports = PathUtils; -},{"object-assign":36,"qs":37,"react/lib/invariant":191}],9:[function(require,module,exports){ -'use strict'; +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} -var assign = require('react/lib/Object.assign'); -var ReactPropTypes = require('react').PropTypes; -var Route = require('./Route'); +function escapeSource(string) { + return escapeRegExp(string).replace(/\/+/g, '/+'); +} -var PropTypes = assign({}, ReactPropTypes, { +function _compilePattern(pattern) { + var regexpSource = ''; + var paramNames = []; + var tokens = []; - /** - * Indicates that a prop should be falsy. - */ - falsy: function falsy(props, propName, componentName) { - if (props[propName]) { - return new Error('<' + componentName + '> should not have a "' + propName + '" prop'); + var match = undefined, + lastIndex = 0, + matcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|\*\*|\*|\(|\)/g; + while (match = matcher.exec(pattern)) { + if (match.index !== lastIndex) { + tokens.push(pattern.slice(lastIndex, match.index)); + regexpSource += escapeSource(pattern.slice(lastIndex, match.index)); } - }, - /** - * Indicates that a prop should be a Route object. - */ - route: ReactPropTypes.instanceOf(Route), + if (match[1]) { + regexpSource += '([^/?#]+)'; + paramNames.push(match[1]); + } else if (match[0] === '**') { + regexpSource += '([\\s\\S]*)'; + paramNames.push('splat'); + } else if (match[0] === '*') { + regexpSource += '([\\s\\S]*?)'; + paramNames.push('splat'); + } else if (match[0] === '(') { + regexpSource += '(?:'; + } else if (match[0] === ')') { + regexpSource += ')?'; + } - /** - * Indicates that a prop should be a Router object. - */ - //router: ReactPropTypes.instanceOf(Router) // TODO - router: ReactPropTypes.func + tokens.push(match[0]); -}); + lastIndex = matcher.lastIndex; + } -module.exports = PropTypes; -},{"./Route":11,"react":"react","react/lib/Object.assign":69}],10:[function(require,module,exports){ -/** - * Encapsulates a redirect to the given route. - */ -"use strict"; + if (lastIndex !== pattern.length) { + tokens.push(pattern.slice(lastIndex, pattern.length)); + regexpSource += escapeSource(pattern.slice(lastIndex, pattern.length)); + } -function Redirect(to, params, query) { - this.to = to; - this.params = params; - this.query = query; + return { + pattern: pattern, + regexpSource: regexpSource, + paramNames: paramNames, + tokens: tokens + }; } -module.exports = Redirect; -},{}],11:[function(require,module,exports){ -'use strict'; - -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +var CompiledPatternsCache = {}; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - -var assign = require('react/lib/Object.assign'); -var invariant = require('react/lib/invariant'); -var warning = require('react/lib/warning'); -var PathUtils = require('./PathUtils'); +function compilePattern(pattern) { + if (!(pattern in CompiledPatternsCache)) CompiledPatternsCache[pattern] = _compilePattern(pattern); -var _currentRoute; + return CompiledPatternsCache[pattern]; +} -var Route = (function () { - function Route(name, path, ignoreScrollBehavior, isDefault, isNotFound, onEnter, onLeave, handler) { - _classCallCheck(this, Route); +/** + * Attempts to match a pattern on the given pathname. Patterns may use + * the following special characters: + * + * - :paramName Matches a URL segment up to the next /, ?, or #. The + * captured string is considered a "param" + * - () Wraps a segment of the URL that is optional + * - * Consumes (non-greedy) all characters up to the next + * character in the pattern, or to the end of the URL if + * there is none + * - ** Consumes (greedy) all characters up to the next character + * in the pattern, or to the end of the URL if there is none + * + * The return value is an object with the following properties: + * + * - remainingPathname + * - paramNames + * - paramValues + */ - this.name = name; - this.path = path; - this.paramNames = PathUtils.extractParamNames(this.path); - this.ignoreScrollBehavior = !!ignoreScrollBehavior; - this.isDefault = !!isDefault; - this.isNotFound = !!isNotFound; - this.onEnter = onEnter; - this.onLeave = onLeave; - this.handler = handler; +function matchPattern(pattern, pathname) { + // Make leading slashes consistent between pattern and pathname. + if (pattern.charAt(0) !== '/') { + pattern = '/' + pattern; + } + if (pathname.charAt(0) !== '/') { + pathname = '/' + pathname; } - _createClass(Route, [{ - key: 'appendChild', + var _compilePattern2 = compilePattern(pattern); - /** - * Appends the given route to this route's child routes. - */ - value: function appendChild(route) { - invariant(route instanceof Route, 'route.appendChild must use a valid Route'); + var regexpSource = _compilePattern2.regexpSource; + var paramNames = _compilePattern2.paramNames; + var tokens = _compilePattern2.tokens; - if (!this.childRoutes) this.childRoutes = []; + regexpSource += '/*'; // Capture path separators - this.childRoutes.push(route); - } - }, { - key: 'toString', - value: function toString() { - var string = '<Route'; + // Special-case patterns like '*' for catch-all routes. + var captureRemaining = tokens[tokens.length - 1] !== '*'; - if (this.name) string += ' name="' + this.name + '"'; + if (captureRemaining) { + // This will match newlines in the remaining path. + regexpSource += '([\\s\\S]*?)'; + } - string += ' path="' + this.path + '">'; + var match = pathname.match(new RegExp('^' + regexpSource + '$', 'i')); - return string; + var remainingPathname = undefined, + paramValues = undefined; + if (match != null) { + if (captureRemaining) { + remainingPathname = match.pop(); + var matchedPath = match[0].substr(0, match[0].length - remainingPathname.length); + + // If we didn't match the entire pathname, then make sure that the match + // we did get ends at a path separator (potentially the one we added + // above at the beginning of the path, if the actual match was empty). + if (remainingPathname && matchedPath.charAt(matchedPath.length - 1) !== '/') { + return { + remainingPathname: null, + paramNames: paramNames, + paramValues: null + }; + } + } else { + // If this matched at all, then the match was the entire pathname. + remainingPathname = ''; } - }], [{ - key: 'createRoute', - /** - * Creates and returns a new route. Options may be a URL pathname string - * with placeholders for named params or an object with any of the following - * properties: - * - * - name The name of the route. This is used to lookup a - * route relative to its parent route and should be - * unique among all child routes of the same parent - * - path A URL pathname string with optional placeholders - * that specify the names of params to extract from - * the URL when the path matches. Defaults to `/${name}` - * when there is a name given, or the path of the parent - * route, or / - * - ignoreScrollBehavior True to make this route (and all descendants) ignore - * the scroll behavior of the router - * - isDefault True to make this route the default route among all - * its siblings - * - isNotFound True to make this route the "not found" route among - * all its siblings - * - onEnter A transition hook that will be called when the - * router is going to enter this route - * - onLeave A transition hook that will be called when the - * router is going to leave this route - * - handler A React component that will be rendered when - * this route is active - * - parentRoute The parent route to use for this route. This option - * is automatically supplied when creating routes inside - * the callback to another invocation of createRoute. You - * only ever need to use this when declaring routes - * independently of one another to manually piece together - * the route hierarchy - * - * The callback may be used to structure your route hierarchy. Any call to - * createRoute, createDefaultRoute, createNotFoundRoute, or createRedirect - * inside the callback automatically uses this route as its parent. - */ - value: function createRoute(options, callback) { - options = options || {}; + paramValues = match.slice(1).map(function (v) { + return v != null ? decodeURIComponent(v) : v; + }); + } else { + remainingPathname = paramValues = null; + } - if (typeof options === 'string') options = { path: options }; + return { + remainingPathname: remainingPathname, + paramNames: paramNames, + paramValues: paramValues + }; +} - var parentRoute = _currentRoute; +function getParamNames(pattern) { + return compilePattern(pattern).paramNames; +} - if (parentRoute) { - warning(options.parentRoute == null || options.parentRoute === parentRoute, 'You should not use parentRoute with createRoute inside another route\'s child callback; it is ignored'); - } else { - parentRoute = options.parentRoute; - } +function getParams(pattern, pathname) { + var _matchPattern = matchPattern(pattern, pathname); - var name = options.name; - var path = options.path || name; + var paramNames = _matchPattern.paramNames; + var paramValues = _matchPattern.paramValues; - if (path && !(options.isDefault || options.isNotFound)) { - if (PathUtils.isAbsolute(path)) { - if (parentRoute) { - invariant(path === parentRoute.path || parentRoute.paramNames.length === 0, 'You cannot nest path "%s" inside "%s"; the parent requires URL parameters', path, parentRoute.path); - } - } else if (parentRoute) { - // Relative paths extend their parent. - path = PathUtils.join(parentRoute.path, path); - } else { - path = '/' + path; - } - } else { - path = parentRoute ? parentRoute.path : '/'; - } + if (paramValues != null) { + return paramNames.reduce(function (memo, paramName, index) { + memo[paramName] = paramValues[index]; + return memo; + }, {}); + } - if (options.isNotFound && !/\*$/.test(path)) path += '*'; // Auto-append * to the path of not found routes. + return null; +} - var route = new Route(name, path, options.ignoreScrollBehavior, options.isDefault, options.isNotFound, options.onEnter, options.onLeave, options.handler); +/** + * Returns a version of the given pattern with params interpolated. Throws + * if there is a dynamic segment of the pattern for which there is no param. + */ - if (parentRoute) { - if (route.isDefault) { - invariant(parentRoute.defaultRoute == null, '%s may not have more than one default route', parentRoute); +function formatPattern(pattern, params) { + params = params || {}; - parentRoute.defaultRoute = route; - } else if (route.isNotFound) { - invariant(parentRoute.notFoundRoute == null, '%s may not have more than one not found route', parentRoute); + var _compilePattern3 = compilePattern(pattern); - parentRoute.notFoundRoute = route; - } + var tokens = _compilePattern3.tokens; - parentRoute.appendChild(route); - } + var parenCount = 0, + pathname = '', + splatIndex = 0; - // Any routes created in the callback - // use this route as their parent. - if (typeof callback === 'function') { - var currentRoute = _currentRoute; - _currentRoute = route; - callback.call(route, route); - _currentRoute = currentRoute; - } + var token = undefined, + paramName = undefined, + paramValue = undefined; + for (var i = 0, len = tokens.length; i < len; ++i) { + token = tokens[i]; - return route; - } - }, { - key: 'createDefaultRoute', + if (token === '*' || token === '**') { + paramValue = Array.isArray(params.splat) ? params.splat[splatIndex++] : params.splat; - /** - * Creates and returns a route that is rendered when its parent matches - * the current URL. - */ - value: function createDefaultRoute(options) { - return Route.createRoute(assign({}, options, { isDefault: true })); - } - }, { - key: 'createNotFoundRoute', + !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing splat #%s for path "%s"', splatIndex, pattern) : _invariant2['default'](false) : undefined; - /** - * Creates and returns a route that is rendered when its parent matches - * the current URL but none of its siblings do. - */ - value: function createNotFoundRoute(options) { - return Route.createRoute(assign({}, options, { isNotFound: true })); - } - }, { - key: 'createRedirect', + if (paramValue != null) pathname += encodeURI(paramValue); + } else if (token === '(') { + parenCount += 1; + } else if (token === ')') { + parenCount -= 1; + } else if (token.charAt(0) === ':') { + paramName = token.substring(1); + paramValue = params[paramName]; - /** - * Creates and returns a route that automatically redirects the transition - * to another route. In addition to the normal options to createRoute, this - * function accepts the following options: - * - * - from An alias for the `path` option. Defaults to * - * - to The path/route/route name to redirect to - * - params The params to use in the redirect URL. Defaults - * to using the current params - * - query The query to use in the redirect URL. Defaults - * to using the current query - */ - value: function createRedirect(options) { - return Route.createRoute(assign({}, options, { - path: options.path || options.from || '*', - onEnter: function onEnter(transition, params, query) { - transition.redirect(options.to, options.params || params, options.query || query); - } - })); + !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing "%s" parameter for path "%s"', paramName, pattern) : _invariant2['default'](false) : undefined; + + if (paramValue != null) pathname += encodeURIComponent(paramValue); + } else { + pathname += token; } - }]); + } - return Route; -})(); + return pathname.replace(/\/+/g, '/'); +} +}).call(this,require('_process')) -module.exports = Route; -},{"./PathUtils":8,"react/lib/Object.assign":69,"react/lib/invariant":191,"react/lib/warning":212}],12:[function(require,module,exports){ +},{"_process":1,"invariant":58}],12:[function(require,module,exports){ 'use strict'; -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var getWindowScrollPosition = require('./getWindowScrollPosition'); +exports.__esModule = true; +exports.falsy = falsy; -function shouldUpdateScroll(state, prevState) { - if (!prevState) { - return true; - } // Don't update scroll position when only the query has changed. - if (state.pathname === prevState.pathname) { - return false; - }var routes = state.routes; - var prevRoutes = prevState.routes; +var _react = require('react'); - var sharedAncestorRoutes = routes.filter(function (route) { - return prevRoutes.indexOf(route) !== -1; - }); +var func = _react.PropTypes.func; +var object = _react.PropTypes.object; +var arrayOf = _react.PropTypes.arrayOf; +var oneOfType = _react.PropTypes.oneOfType; +var element = _react.PropTypes.element; +var shape = _react.PropTypes.shape; +var string = _react.PropTypes.string; - return !sharedAncestorRoutes.some(function (route) { - return route.ignoreScrollBehavior; - }); +function falsy(props, propName, componentName) { + if (props[propName]) return new Error('<' + componentName + '> should not have a "' + propName + '" prop'); } +var history = shape({ + listen: func.isRequired, + pushState: func.isRequired, + replaceState: func.isRequired, + go: func.isRequired +}); + +exports.history = history; +var location = shape({ + pathname: string.isRequired, + search: string.isRequired, + state: object, + action: string.isRequired, + key: string +}); + +exports.location = location; +var component = oneOfType([func, string]); +exports.component = component; +var components = oneOfType([component, object]); +exports.components = components; +var route = oneOfType([object, element]); +exports.route = route; +var routes = oneOfType([route, arrayOf(route)]); + +exports.routes = routes; +exports['default'] = { + falsy: falsy, + history: history, + location: location, + component: component, + components: components, + route: route +}; +},{"react":"react"}],13:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _RouteUtils = require('./RouteUtils'); + +var _PatternUtils = require('./PatternUtils'); + +var _PropTypes = require('./PropTypes'); + +var _React$PropTypes = _react2['default'].PropTypes; +var string = _React$PropTypes.string; +var object = _React$PropTypes.object; + /** - * Provides the router with the ability to manage window scroll position - * according to its scroll behavior. + * A <Redirect> is used to declare another URL path a client should + * be sent to when they request a given URL. + * + * Redirects are placed alongside routes in the route configuration + * and are traversed in the same manner. */ -var ScrollHistory = { +var Redirect = _react2['default'].createClass({ + displayName: 'Redirect', statics: { - /** - * Records curent scroll position as the last known position for the given URL path. - */ - recordScrollPosition: function recordScrollPosition(path) { - if (!this.scrollHistory) this.scrollHistory = {}; + createRouteFromReactElement: function createRouteFromReactElement(element) { + var route = _RouteUtils.createRouteFromReactElement(element); + + if (route.from) route.path = route.from; + + route.onEnter = function (nextState, replace) { + var location = nextState.location; + var params = nextState.params; + + var pathname = undefined; + if (route.to.charAt(0) === '/') { + pathname = _PatternUtils.formatPattern(route.to, params); + } else if (!route.to) { + pathname = location.pathname; + } else { + var routeIndex = nextState.routes.indexOf(route); + var parentPattern = Redirect.getRoutePattern(nextState.routes, routeIndex - 1); + var pattern = parentPattern.replace(/\/*$/, '/') + route.to; + pathname = _PatternUtils.formatPattern(pattern, params); + } + + replace({ + pathname: pathname, + query: route.query || location.query, + state: route.state || location.state + }); + }; - this.scrollHistory[path] = getWindowScrollPosition(); + return route; }, - /** - * Returns the last known scroll position for the given URL path. - */ - getScrollPosition: function getScrollPosition(path) { - if (!this.scrollHistory) this.scrollHistory = {}; + getRoutePattern: function getRoutePattern(routes, routeIndex) { + var parentPattern = ''; - return this.scrollHistory[path] || null; - } + for (var i = routeIndex; i >= 0; i--) { + var route = routes[i]; + var pattern = route.path || ''; - }, + parentPattern = pattern.replace(/\/*$/, '/') + parentPattern; - componentWillMount: function componentWillMount() { - invariant(this.constructor.getScrollBehavior() == null || canUseDOM, 'Cannot use scroll behavior without a DOM'); - }, + if (pattern.indexOf('/') === 0) break; + } - componentDidMount: function componentDidMount() { - this._updateScroll(); - }, + return '/' + parentPattern; + } - componentDidUpdate: function componentDidUpdate(prevProps, prevState) { - this._updateScroll(prevState); }, - _updateScroll: function _updateScroll(prevState) { - if (!shouldUpdateScroll(this.state, prevState)) { - return; - }var scrollBehavior = this.constructor.getScrollBehavior(); + propTypes: { + path: string, + from: string, // Alias for path + to: string.isRequired, + query: object, + state: object, + onEnter: _PropTypes.falsy, + children: _PropTypes.falsy + }, - if (scrollBehavior) scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path), this.state.action); + /* istanbul ignore next: sanity check */ + render: function render() { + !false ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Redirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; } -}; +}); + +exports['default'] = Redirect; +module.exports = exports['default']; +}).call(this,require('_process')) -module.exports = ScrollHistory; -},{"./getWindowScrollPosition":27,"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],13:[function(require,module,exports){ +},{"./PatternUtils":11,"./PropTypes":12,"./RouteUtils":16,"_process":1,"invariant":58,"react":"react"}],14:[function(require,module,exports){ +(function (process){ 'use strict'; -var PropTypes = require('./PropTypes'); +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _RouteUtils = require('./RouteUtils'); + +var _PropTypes = require('./PropTypes'); + +var _React$PropTypes = _react2['default'].PropTypes; +var string = _React$PropTypes.string; +var func = _React$PropTypes.func; /** - * A mixin for components that need to know the path, routes, URL - * params and query that are currently active. - * - * Example: - * - * var AboutLink = React.createClass({ - * mixins: [ Router.State ], - * render() { - * var className = this.props.className; + * A <Route> is used to declare which components are rendered to the + * page when the URL matches a given pattern. * - * if (this.isActive('about')) - * className += ' is-active'; - * - * return React.DOM.a({ className: className }, this.props.children); - * } - * }); + * Routes are arranged in a nested tree structure. When a new URL is + * requested, the tree is searched depth-first to find a route whose + * path matches the URL. When one is found, all routes in the tree + * that lead to it are considered "active" and their components are + * rendered into the DOM, nested in the same order as in the tree. */ -var State = { +var Route = _react2['default'].createClass({ + displayName: 'Route', - contextTypes: { - router: PropTypes.router.isRequired + statics: { + createRouteFromReactElement: _RouteUtils.createRouteFromReactElement }, - /** - * Returns the current URL path. - */ - getPath: function getPath() { - return this.context.router.getCurrentPath(); + propTypes: { + path: string, + component: _PropTypes.component, + components: _PropTypes.components, + getComponent: func, + getComponents: func }, - /** - * Returns the current URL path without the query string. - */ - getPathname: function getPathname() { - return this.context.router.getCurrentPathname(); - }, + /* istanbul ignore next: sanity check */ + render: function render() { + !false ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Route> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; + } - /** - * Returns an object of the URL params that are currently active. - */ - getParams: function getParams() { - return this.context.router.getCurrentParams(); +}); + +exports['default'] = Route; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./PropTypes":12,"./RouteUtils":16,"_process":1,"invariant":58,"react":"react"}],15:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var object = _react2['default'].PropTypes.object; + +/** + * The RouteContext mixin provides a convenient way for route + * components to set the route in context. This is needed for + * routes that render elements that want to use the Lifecycle + * mixin to prevent transitions. + */ +var RouteContext = { + + propTypes: { + route: object.isRequired }, - /** - * Returns an object of the query params that are currently active. - */ - getQuery: function getQuery() { - return this.context.router.getCurrentQuery(); + childContextTypes: { + route: object.isRequired }, - /** - * Returns an array of the routes that are currently active. - */ - getRoutes: function getRoutes() { - return this.context.router.getCurrentRoutes(); + getChildContext: function getChildContext() { + return { + route: this.props.route + }; }, - /** - * A helper method to determine if a given route, params, and query - * are active. - */ - isActive: function isActive(to, params, query) { - return this.context.router.isActive(to, params, query); + componentWillMount: function componentWillMount() { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'The `RouteContext` mixin is deprecated. You can provide `this.props.route` on context with your own `contextTypes`. http://tiny.cc/router-routecontextmixin') : undefined; } }; -module.exports = State; -},{"./PropTypes":9}],14:[function(require,module,exports){ -/* jshint -W058 */ +exports['default'] = RouteContext; +module.exports = exports['default']; +}).call(this,require('_process')) +},{"./routerWarning":34,"_process":1,"react":"react"}],16:[function(require,module,exports){ +(function (process){ 'use strict'; -var Cancellation = require('./Cancellation'); -var Redirect = require('./Redirect'); +exports.__esModule = true; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -/** - * Encapsulates a transition to a given path. - * - * The willTransitionTo and willTransitionFrom handlers receive - * an instance of this class as their first argument. - */ -function Transition(path, retry) { - this.path = path; - this.abortReason = null; - // TODO: Change this to router.retryTransition(transition) - this.retry = retry.bind(this); +exports.isReactChildren = isReactChildren; +exports.createRouteFromReactElement = createRouteFromReactElement; +exports.createRoutesFromReactChildren = createRoutesFromReactChildren; +exports.createRoutes = createRoutes; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +function isValidChild(object) { + return object == null || _react2['default'].isValidElement(object); } -Transition.prototype.abort = function (reason) { - if (this.abortReason == null) this.abortReason = reason || 'ABORT'; -}; +function isReactChildren(object) { + return isValidChild(object) || Array.isArray(object) && object.every(isValidChild); +} -Transition.prototype.redirect = function (to, params, query) { - this.abort(new Redirect(to, params, query)); -}; +function checkPropTypes(componentName, propTypes, props) { + componentName = componentName || 'UnknownComponent'; -Transition.prototype.cancel = function () { - this.abort(new Cancellation()); -}; + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error = propTypes[propName](props, propName, componentName); -Transition.from = function (transition, routes, components, callback) { - routes.reduce(function (callback, route, index) { - return function (error) { - if (error || transition.abortReason) { - callback(error); - } else if (route.onLeave) { - try { - route.onLeave(transition, components[index], callback); + /* istanbul ignore if: error logging */ + if (error instanceof Error) process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, error.message) : undefined; + } + } +} - // If there is no callback in the argument list, call it automatically. - if (route.onLeave.length < 3) callback(); - } catch (e) { - callback(e); - } - } else { - callback(); - } - }; - }, callback)(); -}; +function createRoute(defaultProps, props) { + return _extends({}, defaultProps, props); +} -Transition.to = function (transition, routes, params, query, callback) { - routes.reduceRight(function (callback, route) { - return function (error) { - if (error || transition.abortReason) { - callback(error); - } else if (route.onEnter) { - try { - route.onEnter(transition, params, query, callback); +function createRouteFromReactElement(element) { + var type = element.type; + var route = createRoute(type.defaultProps, element.props); - // If there is no callback in the argument list, call it automatically. - if (route.onEnter.length < 4) callback(); - } catch (e) { - callback(e); - } + if (type.propTypes) checkPropTypes(type.displayName || type.name, type.propTypes, route); + + if (route.children) { + var childRoutes = createRoutesFromReactChildren(route.children, route); + + if (childRoutes.length) route.childRoutes = childRoutes; + + delete route.children; + } + + return route; +} + +/** + * Creates and returns a routes object from the given ReactChildren. JSX + * provides a convenient way to visualize how routes in the hierarchy are + * nested. + * + * import { Route, createRoutesFromReactChildren } from 'react-router' + * + * const routes = createRoutesFromReactChildren( + * <Route component={App}> + * <Route path="home" component={Dashboard}/> + * <Route path="news" component={NewsFeed}/> + * </Route> + * ) + * + * Note: This method is automatically used when you provide <Route> children + * to a <Router> component. + */ + +function createRoutesFromReactChildren(children, parentRoute) { + var routes = []; + + _react2['default'].Children.forEach(children, function (element) { + if (_react2['default'].isValidElement(element)) { + // Component classes may have a static create* method. + if (element.type.createRouteFromReactElement) { + var route = element.type.createRouteFromReactElement(element, parentRoute); + + if (route) routes.push(route); } else { - callback(); + routes.push(createRouteFromReactElement(element)); } - }; - }, callback)(); -}; + } + }); + + return routes; +} -module.exports = Transition; -},{"./Cancellation":4,"./Redirect":10}],15:[function(require,module,exports){ /** - * Actions that modify the URL. + * Creates and returns an array of routes from the given object which + * may be a JSX route, a plain object route, or an array of either. */ + +function createRoutes(routes) { + if (isReactChildren(routes)) { + routes = createRoutesFromReactChildren(routes); + } else if (routes && !Array.isArray(routes)) { + routes = [routes]; + } + + return routes; +} +}).call(this,require('_process')) + +},{"./routerWarning":34,"_process":1,"react":"react"}],17:[function(require,module,exports){ +(function (process){ 'use strict'; -var LocationActions = { +exports.__esModule = true; - /** - * Indicates a new location is being pushed to the history stack. - */ - PUSH: 'push', +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; }; - /** - * Indicates the current location should be replaced. - */ - REPLACE: 'replace', +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - /** - * Indicates the most recent entry should be removed from the history stack. - */ - POP: 'pop' +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } -}; +var _historyLibCreateHashHistory = require('history/lib/createHashHistory'); -module.exports = LocationActions; -},{}],16:[function(require,module,exports){ -'use strict'; +var _historyLibCreateHashHistory2 = _interopRequireDefault(_historyLibCreateHashHistory); + +var _historyLibUseQueries = require('history/lib/useQueries'); + +var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _createTransitionManager = require('./createTransitionManager'); + +var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); + +var _PropTypes = require('./PropTypes'); + +var _RouterContext = require('./RouterContext'); + +var _RouterContext2 = _interopRequireDefault(_RouterContext); + +var _RouteUtils = require('./RouteUtils'); -var LocationActions = require('../actions/LocationActions'); +var _RouterUtils = require('./RouterUtils'); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +function isDeprecatedHistory(history) { + return !history || !history.__v2_compatible__; +} + +var _React$PropTypes = _react2['default'].PropTypes; +var func = _React$PropTypes.func; +var object = _React$PropTypes.object; /** - * A scroll behavior that attempts to imitate the default behavior - * of modern browsers. + * A <Router> is a high-level API for automatically setting up + * a router that renders a <RouterContext> with all the props + * it needs each time the URL changes. */ -var ImitateBrowserBehavior = { +var Router = _react2['default'].createClass({ + displayName: 'Router', - updateScrollPosition: function updateScrollPosition(position, actionType) { - switch (actionType) { - case LocationActions.PUSH: - case LocationActions.REPLACE: - window.scrollTo(0, 0); - break; - case LocationActions.POP: - if (position) { - window.scrollTo(position.x, position.y); - } else { - window.scrollTo(0, 0); - } - break; + propTypes: { + history: object, + children: _PropTypes.routes, + routes: _PropTypes.routes, // alias for children + render: func, + createElement: func, + onError: func, + onUpdate: func, + + // PRIVATE: For client-side rehydration of server match. + matchContext: object + }, + + getDefaultProps: function getDefaultProps() { + return { + render: function render(props) { + return _react2['default'].createElement(_RouterContext2['default'], props); + } + }; + }, + + getInitialState: function getInitialState() { + return { + location: null, + routes: null, + params: null, + components: null + }; + }, + + handleError: function handleError(error) { + if (this.props.onError) { + this.props.onError.call(this, error); + } else { + // Throw errors by default so we don't silently swallow them! + throw error; // This error probably occurred in getChildRoutes or getComponents. } - } + }, -}; + componentWillMount: function componentWillMount() { + var _this = this; -module.exports = ImitateBrowserBehavior; -},{"../actions/LocationActions":15}],17:[function(require,module,exports){ -/** - * A scroll behavior that always scrolls to the top of the page - * after a transition. - */ -"use strict"; + var _props = this.props; + var parseQueryString = _props.parseQueryString; + var stringifyQuery = _props.stringifyQuery; + + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](!(parseQueryString || stringifyQuery), '`parseQueryString` and `stringifyQuery` are deprecated. Please create a custom history. http://tiny.cc/router-customquerystring') : undefined; + + var _createRouterObjects = this.createRouterObjects(); + + var history = _createRouterObjects.history; + var transitionManager = _createRouterObjects.transitionManager; + var router = _createRouterObjects.router; + + this._unlisten = transitionManager.listen(function (error, state) { + if (error) { + _this.handleError(error); + } else { + _this.setState(state, _this.props.onUpdate); + } + }); + + this.history = history; + this.router = router; + }, + + createRouterObjects: function createRouterObjects() { + var matchContext = this.props.matchContext; + + if (matchContext) { + return matchContext; + } + + var history = this.props.history; + var _props2 = this.props; + var routes = _props2.routes; + var children = _props2.children; + + if (isDeprecatedHistory(history)) { + history = this.wrapDeprecatedHistory(history); + } + + var transitionManager = _createTransitionManager2['default'](history, _RouteUtils.createRoutes(routes || children)); + var router = _RouterUtils.createRouterObject(history, transitionManager); + var routingHistory = _RouterUtils.createRoutingHistory(history, transitionManager); + + return { history: routingHistory, transitionManager: transitionManager, router: router }; + }, + + wrapDeprecatedHistory: function wrapDeprecatedHistory(history) { + var _props3 = this.props; + var parseQueryString = _props3.parseQueryString; + var stringifyQuery = _props3.stringifyQuery; + + var createHistory = undefined; + if (history) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'It appears you have provided a deprecated history object to `<Router/>`, please use a history provided by ' + 'React Router with `import { browserHistory } from \'react-router\'` or `import { hashHistory } from \'react-router\'`. ' + 'If you are using a custom history please create it with `useRouterHistory`, see http://tiny.cc/router-usinghistory for details.') : undefined; + createHistory = function () { + return history; + }; + } else { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`Router` no longer defaults the history prop to hash history. Please use the `hashHistory` singleton instead. http://tiny.cc/router-defaulthistory') : undefined; + createHistory = _historyLibCreateHashHistory2['default']; + } + + return _historyLibUseQueries2['default'](createHistory)({ parseQueryString: parseQueryString, stringifyQuery: stringifyQuery }); + }, + + /* istanbul ignore next: sanity check */ + componentWillReceiveProps: function componentWillReceiveProps(nextProps) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](nextProps.history === this.props.history, 'You cannot change <Router history>; it will be ignored') : undefined; + + process.env.NODE_ENV !== 'production' ? _routerWarning2['default']((nextProps.routes || nextProps.children) === (this.props.routes || this.props.children), 'You cannot change <Router routes>; it will be ignored') : undefined; + }, -var ScrollToTopBehavior = { + componentWillUnmount: function componentWillUnmount() { + if (this._unlisten) this._unlisten(); + }, + + render: function render() { + var _state = this.state; + var location = _state.location; + var routes = _state.routes; + var params = _state.params; + var components = _state.components; + var _props4 = this.props; + var createElement = _props4.createElement; + var render = _props4.render; + + var props = _objectWithoutProperties(_props4, ['createElement', 'render']); + + if (location == null) return null; // Async match + + // Only forward non-Router-specific props to routing context, as those are + // the only ones that might be custom routing context props. + Object.keys(Router.propTypes).forEach(function (propType) { + return delete props[propType]; + }); - updateScrollPosition: function updateScrollPosition() { - window.scrollTo(0, 0); + return render(_extends({}, props, { + history: this.history, + router: this.router, + location: location, + routes: routes, + params: params, + components: components, + createElement: createElement + })); } -}; +}); -module.exports = ScrollToTopBehavior; -},{}],18:[function(require,module,exports){ +exports['default'] = Router; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./PropTypes":12,"./RouteUtils":16,"./RouterContext":18,"./RouterUtils":19,"./createTransitionManager":26,"./routerWarning":34,"_process":1,"history/lib/createHashHistory":45,"history/lib/useQueries":52,"react":"react"}],18:[function(require,module,exports){ +(function (process){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +var _deprecateObjectProperties = require('./deprecateObjectProperties'); -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +var _deprecateObjectProperties2 = _interopRequireDefault(_deprecateObjectProperties); + +var _getRouteParams = require('./getRouteParams'); + +var _getRouteParams2 = _interopRequireDefault(_getRouteParams); + +var _RouteUtils = require('./RouteUtils'); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var _React$PropTypes = _react2['default'].PropTypes; +var array = _React$PropTypes.array; +var func = _React$PropTypes.func; +var object = _React$PropTypes.object; /** - * This component is necessary to get around a context warning - * present in React 0.13.0. It sovles this by providing a separation - * between the "owner" and "parent" contexts. + * A <RouterContext> renders the component tree for a given router state + * and sets the history object and the current location in context. */ +var RouterContext = _react2['default'].createClass({ + displayName: 'RouterContext', + + propTypes: { + history: object, + router: object.isRequired, + location: object.isRequired, + routes: array.isRequired, + params: object.isRequired, + components: array.isRequired, + createElement: func.isRequired + }, + + getDefaultProps: function getDefaultProps() { + return { + createElement: _react2['default'].createElement + }; + }, -var React = require('react'); + childContextTypes: { + history: object, + location: object.isRequired, + router: object.isRequired + }, + + getChildContext: function getChildContext() { + var _props = this.props; + var router = _props.router; + var history = _props.history; + var location = _props.location; -var ContextWrapper = (function (_React$Component) { - function ContextWrapper() { - _classCallCheck(this, ContextWrapper); + if (!router) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`<RouterContext>` expects a `router` rather than a `history`') : undefined; - if (_React$Component != null) { - _React$Component.apply(this, arguments); + router = _extends({}, history, { + setRouteLeaveHook: history.listenBeforeLeavingRoute + }); + delete router.listenBeforeLeavingRoute; } - } - _inherits(ContextWrapper, _React$Component); + if (process.env.NODE_ENV !== 'production') { + location = _deprecateObjectProperties2['default'](location, '`context.location` is deprecated, please use a route component\'s `props.location` instead. http://tiny.cc/router-accessinglocation'); + } + + return { history: history, location: location, router: router }; + }, + + createElement: function createElement(component, props) { + return component == null ? null : this.props.createElement(component, props); + }, + + render: function render() { + var _this = this; + + var _props2 = this.props; + var history = _props2.history; + var location = _props2.location; + var routes = _props2.routes; + var params = _props2.params; + var components = _props2.components; + + var element = null; + + if (components) { + element = components.reduceRight(function (element, components, index) { + if (components == null) return element; // Don't create new children; use the grandchildren. - _createClass(ContextWrapper, [{ - key: 'render', - value: function render() { - return this.props.children; + var route = routes[index]; + var routeParams = _getRouteParams2['default'](route, params); + var props = { + history: history, + location: location, + params: params, + route: route, + routeParams: routeParams, + routes: routes + }; + + if (_RouteUtils.isReactChildren(element)) { + props.children = element; + } else if (element) { + for (var prop in element) { + if (element.hasOwnProperty(prop)) props[prop] = element[prop]; + } + } + + if (typeof components === 'object') { + var elements = {}; + + for (var key in components) { + if (components.hasOwnProperty(key)) { + // Pass through the key as a prop to createElement to allow + // custom createElement functions to know which named component + // they're rendering, for e.g. matching up to fetched data. + elements[key] = _this.createElement(components[key], _extends({ + key: key }, props)); + } + } + + return elements; + } + + return _this.createElement(components, props); + }, element); } - }]); - return ContextWrapper; -})(React.Component); + !(element === null || element === false || _react2['default'].isValidElement(element)) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The root route must render a single element') : _invariant2['default'](false) : undefined; + + return element; + } + +}); -module.exports = ContextWrapper; -},{"react":"react"}],19:[function(require,module,exports){ +exports['default'] = RouterContext; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./RouteUtils":16,"./deprecateObjectProperties":27,"./getRouteParams":29,"./routerWarning":34,"_process":1,"invariant":58,"react":"react"}],19:[function(require,module,exports){ +(function (process){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +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 PropTypes = require('../PropTypes'); -var RouteHandler = require('./RouteHandler'); -var Route = require('./Route'); +exports.createRouterObject = createRouterObject; +exports.createRoutingHistory = createRoutingHistory; -/** - * A <DefaultRoute> component is a special kind of <Route> that - * renders when its parent matches but none of its siblings do. - * Only one such route may be used at any given level in the - * route hierarchy. - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -var DefaultRoute = (function (_Route) { - function DefaultRoute() { - _classCallCheck(this, DefaultRoute); +var _deprecateObjectProperties = require('./deprecateObjectProperties'); - if (_Route != null) { - _Route.apply(this, arguments); - } +var _deprecateObjectProperties2 = _interopRequireDefault(_deprecateObjectProperties); + +function createRouterObject(history, transitionManager) { + return _extends({}, history, { + setRouteLeaveHook: transitionManager.listenBeforeLeavingRoute, + isActive: transitionManager.isActive + }); +} + +// deprecated + +function createRoutingHistory(history, transitionManager) { + history = _extends({}, history, transitionManager); + + if (process.env.NODE_ENV !== 'production') { + history = _deprecateObjectProperties2['default'](history, '`props.history` and `context.history` are deprecated. Please use `context.router`. http://tiny.cc/router-contextchanges'); } - _inherits(DefaultRoute, _Route); + return history; +} +}).call(this,require('_process')) - return DefaultRoute; -})(Route); +},{"./deprecateObjectProperties":27,"_process":1}],20:[function(require,module,exports){ +(function (process){ +'use strict'; -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 +exports.__esModule = true; -DefaultRoute.propTypes = { - name: PropTypes.string, - path: PropTypes.falsy, - children: PropTypes.falsy, - handler: PropTypes.func.isRequired -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -DefaultRoute.defaultProps = { - handler: RouteHandler -}; +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _RouterContext = require('./RouterContext'); -module.exports = DefaultRoute; -},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],20:[function(require,module,exports){ +var _RouterContext2 = _interopRequireDefault(_RouterContext); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var RoutingContext = _react2['default'].createClass({ + displayName: 'RoutingContext', + + componentWillMount: function componentWillMount() { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`RoutingContext` has been renamed to `RouterContext`. Please use `import { RouterContext } from \'react-router\'`. http://tiny.cc/router-routercontext') : undefined; + }, + + render: function render() { + return _react2['default'].createElement(_RouterContext2['default'], this.props); + } +}); + +exports['default'] = RoutingContext; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./RouterContext":18,"./routerWarning":34,"_process":1,"react":"react"}],21:[function(require,module,exports){ +(function (process){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; +exports.runEnterHooks = runEnterHooks; +exports.runLeaveHooks = runLeaveHooks; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +var _AsyncUtils = require('./AsyncUtils'); -var React = require('react'); -var assign = require('react/lib/Object.assign'); -var PropTypes = require('../PropTypes'); +var _routerWarning = require('./routerWarning'); -function isLeftClickEvent(event) { - return event.button === 0; +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +function createEnterHook(hook, route) { + return function (a, b, callback) { + hook.apply(route, arguments); + + if (hook.length < 3) { + // Assume hook executes synchronously and + // automatically call the callback. + callback(); + } + }; } -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); +function getEnterHooks(routes) { + return routes.reduce(function (hooks, route) { + if (route.onEnter) hooks.push(createEnterHook(route.onEnter, route)); + + return hooks; + }, []); } /** - * <Link> components are used to create an <a> element that links to a route. - * When that route is active, the link gets an "active" class name (or the - * value of its `activeClassName` prop). - * - * For example, assuming you have the following route: - * - * <Route name="showPost" path="/posts/:postID" handler={Post}/> + * Runs all onEnter hooks in the given array of routes in order + * with onEnter(nextState, replace, callback) and calls + * callback(error, redirectInfo) when finished. The first hook + * to use replace short-circuits the loop. * - * You could use the following component to link to that route: - * - * <Link to="showPost" params={{ postID: "123" }} /> - * - * In addition to params, links may pass along query string parameters - * using the `query` prop. - * - * <Link to="showPost" params={{ postID: "123" }} query={{ show:true }}/> + * If a hook needs to run asynchronously, it may use the callback + * function. However, doing so will cause the transition to pause, + * which could lead to a non-responsive UI if the hook is slow. */ -var Link = (function (_React$Component) { - function Link() { - _classCallCheck(this, Link); +function runEnterHooks(routes, nextState, callback) { + var hooks = getEnterHooks(routes); + + if (!hooks.length) { + callback(); + return; + } - if (_React$Component != null) { - _React$Component.apply(this, arguments); + var redirectInfo = undefined; + function replace(location, deprecatedPathname, deprecatedQuery) { + if (deprecatedPathname) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`replaceState(state, pathname, query) is deprecated; use `replace(location)` with a location descriptor instead. http://tiny.cc/router-isActivedeprecated') : undefined; + redirectInfo = { + pathname: deprecatedPathname, + query: deprecatedQuery, + state: location + }; + + return; } + + redirectInfo = location; } - _inherits(Link, _React$Component); + _AsyncUtils.loopAsync(hooks.length, function (index, next, done) { + hooks[index](nextState, replace, function (error) { + if (error || redirectInfo) { + done(error, redirectInfo); // No need to continue. + } else { + next(); + } + }); + }, callback); +} - _createClass(Link, [{ - key: 'handleClick', - value: function handleClick(event) { - var allowTransition = true; - var clickResult; +/** + * Runs all onLeave hooks in the given array of routes in order. + */ - if (this.props.onClick) clickResult = this.props.onClick(event); +function runLeaveHooks(routes) { + for (var i = 0, len = routes.length; i < len; ++i) { + if (routes[i].onLeave) routes[i].onLeave.call(routes[i]); + } +} +}).call(this,require('_process')) - if (isModifiedEvent(event) || !isLeftClickEvent(event)) { - return; - }if (clickResult === false || event.defaultPrevented === true) allowTransition = false; +},{"./AsyncUtils":4,"./routerWarning":34,"_process":1}],22:[function(require,module,exports){ +'use strict'; - event.preventDefault(); +exports.__esModule = true; - if (allowTransition) this.context.router.transitionTo(this.props.to, this.props.params, this.props.query); - } - }, { - key: 'getHref', +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - /** - * Returns the value of the "href" attribute to use on the DOM element. - */ - value: function getHref() { - return this.context.router.makeHref(this.props.to, this.props.params, this.props.query); - } - }, { - key: 'getClassName', +var _historyLibCreateBrowserHistory = require('history/lib/createBrowserHistory'); - /** - * Returns the value of the "class" attribute to use on the DOM element, which contains - * the value of the activeClassName property when this <Link> is active. - */ - value: function getClassName() { - var className = this.props.className; +var _historyLibCreateBrowserHistory2 = _interopRequireDefault(_historyLibCreateBrowserHistory); - if (this.getActiveState()) className += ' ' + this.props.activeClassName; +var _createRouterHistory = require('./createRouterHistory'); - return className; - } - }, { - key: 'getActiveState', - value: function getActiveState() { - return this.context.router.isActive(this.props.to, this.props.params, this.props.query); - } - }, { - key: 'render', - value: function render() { - var props = assign({}, this.props, { - href: this.getHref(), - className: this.getClassName(), - onClick: this.handleClick.bind(this) - }); +var _createRouterHistory2 = _interopRequireDefault(_createRouterHistory); - if (props.activeStyle && this.getActiveState()) props.style = props.activeStyle; +exports['default'] = _createRouterHistory2['default'](_historyLibCreateBrowserHistory2['default']); +module.exports = exports['default']; +},{"./createRouterHistory":25,"history/lib/createBrowserHistory":43}],23:[function(require,module,exports){ +'use strict'; - return React.DOM.a(props, this.props.children); - } - }]); +exports.__esModule = true; - return Link; -})(React.Component); +var _PatternUtils = require('./PatternUtils'); -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 +function routeParamsChanged(route, prevState, nextState) { + if (!route.path) return false; -Link.contextTypes = { - router: PropTypes.router.isRequired -}; + var paramNames = _PatternUtils.getParamNames(route.path); -Link.propTypes = { - activeClassName: PropTypes.string.isRequired, - to: PropTypes.oneOfType([PropTypes.string, PropTypes.route]).isRequired, - params: PropTypes.object, - query: PropTypes.object, - activeStyle: PropTypes.object, - onClick: PropTypes.func -}; + return paramNames.some(function (paramName) { + return prevState.params[paramName] !== nextState.params[paramName]; + }); +} -Link.defaultProps = { - activeClassName: 'active', - className: '' -}; +/** + * Returns an object of { leaveRoutes, enterRoutes } determined by + * the change from prevState to nextState. We leave routes if either + * 1) they are not in the next state or 2) they are in the next state + * but their params have changed (i.e. /users/123 => /users/456). + * + * leaveRoutes are ordered starting at the leaf route of the tree + * we're leaving up to the common parent route. enterRoutes are ordered + * from the top of the tree we're entering down to the leaf route. + */ +function computeChangedRoutes(prevState, nextState) { + var prevRoutes = prevState && prevState.routes; + var nextRoutes = nextState.routes; + + var leaveRoutes = undefined, + enterRoutes = undefined; + if (prevRoutes) { + leaveRoutes = prevRoutes.filter(function (route) { + return nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState); + }); + + // onLeave hooks start at the leaf route. + leaveRoutes.reverse(); + + enterRoutes = nextRoutes.filter(function (route) { + return prevRoutes.indexOf(route) === -1 || leaveRoutes.indexOf(route) !== -1; + }); + } else { + leaveRoutes = []; + enterRoutes = nextRoutes; + } -module.exports = Link; -},{"../PropTypes":9,"react":"react","react/lib/Object.assign":69}],21:[function(require,module,exports){ + return { + leaveRoutes: leaveRoutes, + enterRoutes: enterRoutes + }; +} + +exports['default'] = computeChangedRoutes; +module.exports = exports['default']; +},{"./PatternUtils":11}],24:[function(require,module,exports){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; +exports['default'] = createMemoryHistory; -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -var PropTypes = require('../PropTypes'); -var RouteHandler = require('./RouteHandler'); -var Route = require('./Route'); +var _historyLibUseQueries = require('history/lib/useQueries'); -/** - * A <NotFoundRoute> is a special kind of <Route> that - * renders when the beginning of its parent's path matches - * but none of its siblings do, including any <DefaultRoute>. - * Only one such route may be used at any given level in the - * route hierarchy. - */ +var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); -var NotFoundRoute = (function (_Route) { - function NotFoundRoute() { - _classCallCheck(this, NotFoundRoute); +var _historyLibUseBasename = require('history/lib/useBasename'); - if (_Route != null) { - _Route.apply(this, arguments); - } - } +var _historyLibUseBasename2 = _interopRequireDefault(_historyLibUseBasename); - _inherits(NotFoundRoute, _Route); +var _historyLibCreateMemoryHistory = require('history/lib/createMemoryHistory'); - return NotFoundRoute; -})(Route); +var _historyLibCreateMemoryHistory2 = _interopRequireDefault(_historyLibCreateMemoryHistory); -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 +function createMemoryHistory(options) { + // signatures and type checking differ between `useRoutes` and + // `createMemoryHistory`, have to create `memoryHistory` first because + // `useQueries` doesn't understand the signature + var memoryHistory = _historyLibCreateMemoryHistory2['default'](options); + var createHistory = function createHistory() { + return memoryHistory; + }; + var history = _historyLibUseQueries2['default'](_historyLibUseBasename2['default'](createHistory))(options); + history.__v2_compatible__ = true; + return history; +} -NotFoundRoute.propTypes = { - name: PropTypes.string, - path: PropTypes.falsy, - children: PropTypes.falsy, - handler: PropTypes.func.isRequired -}; +module.exports = exports['default']; +},{"history/lib/createMemoryHistory":48,"history/lib/useBasename":51,"history/lib/useQueries":52}],25:[function(require,module,exports){ +'use strict'; -NotFoundRoute.defaultProps = { - handler: RouteHandler +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _useRouterHistory = require('./useRouterHistory'); + +var _useRouterHistory2 = _interopRequireDefault(_useRouterHistory); + +var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); + +exports['default'] = function (createHistory) { + var history = undefined; + if (canUseDOM) history = _useRouterHistory2['default'](createHistory)(); + return history; }; -module.exports = NotFoundRoute; -},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],22:[function(require,module,exports){ +module.exports = exports['default']; +},{"./useRouterHistory":35}],26:[function(require,module,exports){ +(function (process){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +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 PropTypes = require('../PropTypes'); -var Route = require('./Route'); +exports['default'] = createTransitionManager; -/** - * A <Redirect> component is a special kind of <Route> that always - * redirects to another route when it matches. - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -var Redirect = (function (_Route) { - function Redirect() { - _classCallCheck(this, Redirect); +var _routerWarning = require('./routerWarning'); - if (_Route != null) { - _Route.apply(this, arguments); - } - } +var _routerWarning2 = _interopRequireDefault(_routerWarning); - _inherits(Redirect, _Route); +var _historyLibActions = require('history/lib/Actions'); - return Redirect; -})(Route); +var _computeChangedRoutes2 = require('./computeChangedRoutes'); -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 +var _computeChangedRoutes3 = _interopRequireDefault(_computeChangedRoutes2); -Redirect.propTypes = { - path: PropTypes.string, - from: PropTypes.string, // Alias for path. - to: PropTypes.string, - handler: PropTypes.falsy -}; +var _TransitionUtils = require('./TransitionUtils'); -// Redirects should not have a default handler -Redirect.defaultProps = {}; +var _isActive2 = require('./isActive'); -module.exports = Redirect; -},{"../PropTypes":9,"./Route":23}],23:[function(require,module,exports){ -'use strict'; +var _isActive3 = _interopRequireDefault(_isActive2); -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +var _getComponents = require('./getComponents'); -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +var _getComponents2 = _interopRequireDefault(_getComponents); -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; +var _matchRoutes = require('./matchRoutes'); -var React = require('react'); -var invariant = require('react/lib/invariant'); -var PropTypes = require('../PropTypes'); -var RouteHandler = require('./RouteHandler'); +var _matchRoutes2 = _interopRequireDefault(_matchRoutes); -/** - * <Route> components specify components that are rendered to the page when the - * URL matches a given pattern. - * - * Routes are arranged in a nested tree structure. When a new URL is requested, - * the tree is searched depth-first to find a route whose path matches the URL. - * When one is found, all routes in the tree that lead to it are considered - * "active" and their components are rendered into the DOM, nested in the same - * order as they are in the tree. - * - * The preferred way to configure a router is using JSX. The XML-like syntax is - * a great way to visualize how routes are laid out in an application. - * - * var routes = [ - * <Route handler={App}> - * <Route name="login" handler={Login}/> - * <Route name="logout" handler={Logout}/> - * <Route name="about" handler={About}/> - * </Route> - * ]; - * - * Router.run(routes, function (Handler) { - * React.render(<Handler/>, document.body); - * }); - * - * Handlers for Route components that contain children can render their active - * child route using a <RouteHandler> element. - * - * var App = React.createClass({ - * render: function () { - * return ( - * <div class="application"> - * <RouteHandler/> - * </div> - * ); - * } - * }); - * - * If no handler is provided for the route, it will render a matched child route. - */ +function hasAnyProperties(object) { + for (var p in object) { + if (object.hasOwnProperty(p)) return true; + }return false; +} -var Route = (function (_React$Component) { - function Route() { - _classCallCheck(this, Route); +function createTransitionManager(history, routes) { + var state = {}; - if (_React$Component != null) { - _React$Component.apply(this, arguments); + // Signature should be (location, indexOnly), but needs to support (path, + // query, indexOnly) + function isActive(location) { + var indexOnlyOrDeprecatedQuery = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + var deprecatedIndexOnly = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; + + var indexOnly = undefined; + if (indexOnlyOrDeprecatedQuery && indexOnlyOrDeprecatedQuery !== true || deprecatedIndexOnly !== null) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`isActive(pathname, query, indexOnly) is deprecated; use `isActive(location, indexOnly)` with a location descriptor instead. http://tiny.cc/router-isActivedeprecated') : undefined; + location = { pathname: location, query: indexOnlyOrDeprecatedQuery }; + indexOnly = deprecatedIndexOnly || false; + } else { + location = history.createLocation(location); + indexOnly = indexOnlyOrDeprecatedQuery; } + + return _isActive3['default'](location, indexOnly, state.location, state.routes, state.params); + } + + function createLocationFromRedirectInfo(location) { + return history.createLocation(location, _historyLibActions.REPLACE); } - _inherits(Route, _React$Component); + var partialNextState = undefined; - _createClass(Route, [{ - key: 'render', - value: function render() { - invariant(false, '%s elements are for router configuration only and should not be rendered', this.constructor.name); + function match(location, callback) { + if (partialNextState && partialNextState.location === location) { + // Continue from where we left off. + finishMatch(partialNextState, callback); + } else { + _matchRoutes2['default'](routes, location, function (error, nextState) { + if (error) { + callback(error); + } else if (nextState) { + finishMatch(_extends({}, nextState, { location: location }), callback); + } else { + callback(); + } + }); } - }]); + } - return Route; -})(React.Component); + function finishMatch(nextState, callback) { + var _computeChangedRoutes = _computeChangedRoutes3['default'](state, nextState); -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 + var leaveRoutes = _computeChangedRoutes.leaveRoutes; + var enterRoutes = _computeChangedRoutes.enterRoutes; -Route.propTypes = { - name: PropTypes.string, - path: PropTypes.string, - handler: PropTypes.func, - ignoreScrollBehavior: PropTypes.bool -}; + _TransitionUtils.runLeaveHooks(leaveRoutes); -Route.defaultProps = { - handler: RouteHandler -}; + // Tear down confirmation hooks for left routes + leaveRoutes.forEach(removeListenBeforeHooksForRoute); -module.exports = Route; -},{"../PropTypes":9,"./RouteHandler":24,"react":"react","react/lib/invariant":191}],24:[function(require,module,exports){ -'use strict'; + _TransitionUtils.runEnterHooks(enterRoutes, nextState, function (error, redirectInfo) { + if (error) { + callback(error); + } else if (redirectInfo) { + callback(null, createLocationFromRedirectInfo(redirectInfo)); + } else { + // TODO: Fetch components after state is updated. + _getComponents2['default'](nextState, function (error, components) { + if (error) { + callback(error); + } else { + // TODO: Make match a pure function and have some other API + // for "match and update state". + callback(null, null, state = _extends({}, nextState, { components: components })); + } + }); + } + }); + } -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + var RouteGuid = 1; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + function getRouteID(route) { + var create = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; -var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + return route.__id__ || create && (route.__id__ = RouteGuid++); + } -var React = require('react'); -var ContextWrapper = require('./ContextWrapper'); -var assign = require('react/lib/Object.assign'); -var PropTypes = require('../PropTypes'); + var RouteHooks = {}; -var REF_NAME = '__routeHandler__'; + function getRouteHooksForRoutes(routes) { + return routes.reduce(function (hooks, route) { + hooks.push.apply(hooks, RouteHooks[getRouteID(route)]); + return hooks; + }, []); + } -/** - * A <RouteHandler> component renders the active child route handler - * when routes are nested. - */ + function transitionHook(location, callback) { + _matchRoutes2['default'](routes, location, function (error, nextState) { + if (nextState == null) { + // TODO: We didn't actually match anything, but hang + // onto error/nextState so we don't have to matchRoutes + // again in the listen callback. + callback(); + return; + } + + // Cache some state here so we don't have to + // matchRoutes() again in the listen callback. + partialNextState = _extends({}, nextState, { location: location }); + + var hooks = getRouteHooksForRoutes(_computeChangedRoutes3['default'](state, partialNextState).leaveRoutes); + + var result = undefined; + for (var i = 0, len = hooks.length; result == null && i < len; ++i) { + // Passing the location arg here indicates to + // the user that this is a transition hook. + result = hooks[i](location); + } + + callback(result); + }); + } -var RouteHandler = (function (_React$Component) { - function RouteHandler() { - _classCallCheck(this, RouteHandler); + /* istanbul ignore next: untestable with Karma */ + function beforeUnloadHook() { + // Synchronously check to see if any route hooks want + // to prevent the current window/tab from closing. + if (state.routes) { + var hooks = getRouteHooksForRoutes(state.routes); + + var message = undefined; + for (var i = 0, len = hooks.length; typeof message !== 'string' && i < len; ++i) { + // Passing no args indicates to the user that this is a + // beforeunload hook. We don't know the next location. + message = hooks[i](); + } - if (_React$Component != null) { - _React$Component.apply(this, arguments); + return message; } } - _inherits(RouteHandler, _React$Component); + var unlistenBefore = undefined, + unlistenBeforeUnload = undefined; - _createClass(RouteHandler, [{ - key: 'getChildContext', - value: function getChildContext() { - return { - routeDepth: this.context.routeDepth + 1 - }; + function removeListenBeforeHooksForRoute(route) { + var routeID = getRouteID(route, false); + if (!routeID) { + return; } - }, { - key: 'componentDidMount', - value: function componentDidMount() { - this._updateRouteComponent(this.refs[REF_NAME]); - } - }, { - key: 'componentDidUpdate', - value: function componentDidUpdate() { - this._updateRouteComponent(this.refs[REF_NAME]); - } - }, { - key: 'componentWillUnmount', - value: function componentWillUnmount() { - this._updateRouteComponent(null); - } - }, { - key: '_updateRouteComponent', - value: function _updateRouteComponent(component) { - this.context.router.setRouteComponentAtDepth(this.getRouteDepth(), component); - } - }, { - key: 'getRouteDepth', - value: function getRouteDepth() { - return this.context.routeDepth; - } - }, { - key: 'createChildRouteHandler', - value: function createChildRouteHandler(props) { - var route = this.context.router.getRouteAtDepth(this.getRouteDepth()); - - if (route == null) { - return null; - }var childProps = assign({}, props || this.props, { - ref: REF_NAME, - params: this.context.router.getCurrentParams(), - query: this.context.router.getCurrentQuery() - }); - return React.createElement(route.handler, childProps); + delete RouteHooks[routeID]; + + if (!hasAnyProperties(RouteHooks)) { + // teardown transition & beforeunload hooks + if (unlistenBefore) { + unlistenBefore(); + unlistenBefore = null; + } + + if (unlistenBeforeUnload) { + unlistenBeforeUnload(); + unlistenBeforeUnload = null; + } } - }, { - key: 'render', - value: function render() { - var handler = this.createChildRouteHandler(); - // <script/> for things like <CSSTransitionGroup/> that don't like null - return handler ? React.createElement( - ContextWrapper, - null, - handler - ) : React.createElement('script', null); + } + + /** + * Registers the given hook function to run before leaving the given route. + * + * During a normal transition, the hook function receives the next location + * as its only argument and must return either a) a prompt message to show + * the user, to make sure they want to leave the page or b) false, to prevent + * the transition. + * + * During the beforeunload event (in browsers) the hook receives no arguments. + * In this case it must return a prompt message to prevent the transition. + * + * Returns a function that may be used to unbind the listener. + */ + function listenBeforeLeavingRoute(route, hook) { + // TODO: Warn if they register for a route that isn't currently + // active. They're probably doing something wrong, like re-creating + // route objects on every location change. + var routeID = getRouteID(route); + var hooks = RouteHooks[routeID]; + + if (!hooks) { + var thereWereNoRouteHooks = !hasAnyProperties(RouteHooks); + + RouteHooks[routeID] = [hook]; + + if (thereWereNoRouteHooks) { + // setup transition & beforeunload hooks + unlistenBefore = history.listenBefore(transitionHook); + + if (history.listenBeforeUnload) unlistenBeforeUnload = history.listenBeforeUnload(beforeUnloadHook); + } + } else { + if (hooks.indexOf(hook) === -1) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'adding multiple leave hooks for the same route is deprecated; manage multiple confirmations in your own code instead') : undefined; + + hooks.push(hook); + } } - }]); - return RouteHandler; -})(React.Component); + return function () { + var hooks = RouteHooks[routeID]; -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 + if (hooks) { + var newHooks = hooks.filter(function (item) { + return item !== hook; + }); -RouteHandler.contextTypes = { - routeDepth: PropTypes.number.isRequired, - router: PropTypes.router.isRequired -}; + if (newHooks.length === 0) { + removeListenBeforeHooksForRoute(route); + } else { + RouteHooks[routeID] = newHooks; + } + } + }; + } -RouteHandler.childContextTypes = { - routeDepth: PropTypes.number.isRequired -}; + /** + * This is the API for stateful environments. As the location + * changes, we update state and call the listener. We can also + * gracefully handle errors and redirects. + */ + function listen(listener) { + // TODO: Only use a single history listener. Otherwise we'll + // end up with multiple concurrent calls to match. + return history.listen(function (location) { + if (state.location === location) { + listener(null, state); + } else { + match(location, function (error, redirectLocation, nextState) { + if (error) { + listener(error); + } else if (redirectLocation) { + history.transitionTo(redirectLocation); + } else if (nextState) { + listener(null, nextState); + } else { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, 'Location "%s" did not match any routes', location.pathname + location.search + location.hash) : undefined; + } + }); + } + }); + } -module.exports = RouteHandler; -},{"../PropTypes":9,"./ContextWrapper":18,"react":"react","react/lib/Object.assign":69}],25:[function(require,module,exports){ + return { + isActive: isActive, + match: match, + listenBeforeLeavingRoute: listenBeforeLeavingRoute, + listen: listen + }; +} + +//export default useRoutes +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./TransitionUtils":21,"./computeChangedRoutes":23,"./getComponents":28,"./isActive":31,"./matchRoutes":33,"./routerWarning":34,"_process":1,"history/lib/Actions":37}],27:[function(require,module,exports){ (function (process){ -/* jshint -W058 */ +/*eslint no-empty: 0*/ 'use strict'; -var React = require('react'); -var warning = require('react/lib/warning'); -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var LocationActions = require('./actions/LocationActions'); -var ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior'); -var HashLocation = require('./locations/HashLocation'); -var HistoryLocation = require('./locations/HistoryLocation'); -var RefreshLocation = require('./locations/RefreshLocation'); -var StaticLocation = require('./locations/StaticLocation'); -var ScrollHistory = require('./ScrollHistory'); -var createRoutesFromReactChildren = require('./createRoutesFromReactChildren'); -var isReactChildren = require('./isReactChildren'); -var Transition = require('./Transition'); -var PropTypes = require('./PropTypes'); -var Redirect = require('./Redirect'); -var History = require('./History'); -var Cancellation = require('./Cancellation'); -var Match = require('./Match'); -var Route = require('./Route'); -var supportsHistory = require('./supportsHistory'); -var PathUtils = require('./PathUtils'); - -/** - * The default location for new routers. - */ -var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; - -/** - * The default scroll behavior for new routers. - */ -var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; - -function hasProperties(object, properties) { - for (var propertyName in properties) if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) { - return false; - }return true; +exports.__esModule = true; +exports['default'] = deprecateObjectProperties; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +var useMembrane = false; + +if (process.env.NODE_ENV !== 'production') { + try { + if (Object.defineProperty({}, 'x', { get: function get() { + return true; + } }).x) { + useMembrane = true; + } + } catch (e) {} } -function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) { - return routes.some(function (r) { - if (r !== route) return false; +// wraps an object in a membrane to warn about deprecated property access - var paramNames = route.paramNames; - var paramName; +function deprecateObjectProperties(object, message) { + if (!useMembrane) return object; - // Ensure that all params the route cares about did not change. - for (var i = 0, len = paramNames.length; i < len; ++i) { - paramName = paramNames[i]; + var membrane = {}; - if (nextParams[paramName] !== prevParams[paramName]) return false; + var _loop = function (prop) { + if (typeof object[prop] === 'function') { + membrane[prop] = function () { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, message) : undefined; + return object[prop].apply(object, arguments); + }; + } else { + Object.defineProperty(membrane, prop, { + configurable: false, + enumerable: false, + get: function get() { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, message) : undefined; + return object[prop]; + } + }); } + }; - // Ensure the query hasn't changed. - return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery); - }); + for (var prop in object) { + _loop(prop); + } + + return membrane; } -function addRoutesToNamedRoutes(routes, namedRoutes) { - var route; - for (var i = 0, len = routes.length; i < len; ++i) { - route = routes[i]; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./routerWarning":34,"_process":1}],28:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _AsyncUtils = require('./AsyncUtils'); + +function getComponentsForRoute(location, route, callback) { + if (route.component || route.components) { + callback(null, route.component || route.components); + } else if (route.getComponent) { + route.getComponent(location, callback); + } else if (route.getComponents) { + route.getComponents(location, callback); + } else { + callback(); + } +} + +/** + * Asynchronously fetches all components needed for the given router + * state and calls callback(error, components) when finished. + * + * Note: This operation may finish synchronously if no routes have an + * asynchronous getComponents method. + */ +function getComponents(nextState, callback) { + _AsyncUtils.mapAsync(nextState.routes, function (route, index, callback) { + getComponentsForRoute(nextState.location, route, callback); + }, callback); +} + +exports['default'] = getComponents; +module.exports = exports['default']; +},{"./AsyncUtils":4}],29:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _PatternUtils = require('./PatternUtils'); + +/** + * Extracts an object of params the given route cares about from + * the given params object. + */ +function getRouteParams(route, params) { + var routeParams = {}; + + if (!route.path) return routeParams; + + var paramNames = _PatternUtils.getParamNames(route.path); + + for (var p in params) { + if (params.hasOwnProperty(p) && paramNames.indexOf(p) !== -1) routeParams[p] = params[p]; + }return routeParams; +} + +exports['default'] = getRouteParams; +module.exports = exports['default']; +},{"./PatternUtils":11}],30:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; - if (route.name) { - invariant(namedRoutes[route.name] == null, 'You may not have more than one route named "%s"', route.name); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - namedRoutes[route.name] = route; +var _historyLibCreateHashHistory = require('history/lib/createHashHistory'); + +var _historyLibCreateHashHistory2 = _interopRequireDefault(_historyLibCreateHashHistory); + +var _createRouterHistory = require('./createRouterHistory'); + +var _createRouterHistory2 = _interopRequireDefault(_createRouterHistory); + +exports['default'] = _createRouterHistory2['default'](_historyLibCreateHashHistory2['default']); +module.exports = exports['default']; +},{"./createRouterHistory":25,"history/lib/createHashHistory":45}],31:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports['default'] = isActive; + +var _PatternUtils = require('./PatternUtils'); + +function deepEqual(a, b) { + if (a == b) return true; + + if (a == null || b == null) return false; + + if (Array.isArray(a)) { + return Array.isArray(b) && a.length === b.length && a.every(function (item, index) { + return deepEqual(item, b[index]); + }); + } + + if (typeof a === 'object') { + for (var p in a) { + if (!a.hasOwnProperty(p)) { + continue; + } + + if (a[p] === undefined) { + if (b[p] !== undefined) { + return false; + } + } else if (!b.hasOwnProperty(p)) { + return false; + } else if (!deepEqual(a[p], b[p])) { + return false; + } } - if (route.childRoutes) addRoutesToNamedRoutes(route.childRoutes, namedRoutes); + return true; } + + return String(a) === String(b); } -function routeIsActive(activeRoutes, routeName) { - return activeRoutes.some(function (route) { - return route.name === routeName; +function paramsAreActive(paramNames, paramValues, activeParams) { + // FIXME: This doesn't work on repeated params in activeParams. + return paramNames.every(function (paramName, index) { + return String(paramValues[index]) === String(activeParams[paramName]); }); } -function paramsAreActive(activeParams, params) { - for (var property in params) if (String(activeParams[property]) !== String(params[property])) { - return false; - }return true; +function getMatchingRouteIndex(pathname, activeRoutes, activeParams) { + var remainingPathname = pathname, + paramNames = [], + paramValues = []; + + for (var i = 0, len = activeRoutes.length; i < len; ++i) { + var route = activeRoutes[i]; + var pattern = route.path || ''; + + if (pattern.charAt(0) === '/') { + remainingPathname = pathname; + paramNames = []; + paramValues = []; + } + + if (remainingPathname !== null) { + var matched = _PatternUtils.matchPattern(pattern, remainingPathname); + remainingPathname = matched.remainingPathname; + paramNames = [].concat(paramNames, matched.paramNames); + paramValues = [].concat(paramValues, matched.paramValues); + } + + if (remainingPathname === '' && route.path && paramsAreActive(paramNames, paramValues, activeParams)) return i; + } + + return null; } -function queryIsActive(activeQuery, query) { - for (var property in query) if (String(activeQuery[property]) !== String(query[property])) { +/** + * Returns true if the given pathname matches the active routes + * and params. + */ +function routeIsActive(pathname, routes, params, indexOnly) { + var i = getMatchingRouteIndex(pathname, routes, params); + + if (i === null) { + // No match. return false; - }return true; + } else if (!indexOnly) { + // Any match is good enough. + return true; + } + + // If any remaining routes past the match index have paths, then we can't + // be on the index route. + return routes.slice(i + 1).every(function (route) { + return !route.path; + }); } /** - * Creates and returns a new router using the given options. A router - * is a ReactComponent class that knows how to react to changes in the - * URL and keep the contents of the page in sync. - * - * Options may be any of the following: - * - * - routes (required) The route config - * - location The location to use. Defaults to HashLocation when - * the DOM is available, "/" otherwise - * - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior - * when the DOM is available, null otherwise - * - onError A function that is used to handle errors - * - onAbort A function that is used to handle aborted transitions - * - * When rendering in a server-side environment, the location should simply - * be the URL path that was used in the request, including the query string. + * Returns true if all key/value pairs in the given query are + * currently active. */ -function createRouter(options) { - options = options || {}; +function queryIsActive(query, activeQuery) { + if (activeQuery == null) return query == null; - if (isReactChildren(options)) options = { routes: options }; + if (query == null) return true; - var mountedComponents = []; - var location = options.location || DEFAULT_LOCATION; - var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR; - var state = {}; - var nextState = {}; - var pendingTransition = null; - var dispatchHandler = null; - - if (typeof location === 'string') location = new StaticLocation(location); + return deepEqual(query, activeQuery); +} - if (location instanceof StaticLocation) { - warning(!canUseDOM || process.env.NODE_ENV === 'test', 'You should not use a static location in a DOM environment because ' + 'the router will not be kept in sync with the current URL'); - } else { - invariant(canUseDOM || location.needsDOM === false, 'You cannot use %s without a DOM', location); - } +/** + * Returns true if a <Link> to the given pathname/query combination is + * currently active. + */ - // Automatically fall back to full page refreshes in - // browsers that don't support the HTML history API. - if (location === HistoryLocation && !supportsHistory()) location = RefreshLocation; +function isActive(_ref, indexOnly, currentLocation, routes, params) { + var pathname = _ref.pathname; + var query = _ref.query; - var Router = React.createClass({ + if (currentLocation == null) return false; - displayName: 'Router', + if (!routeIsActive(pathname, routes, params, indexOnly)) return false; - statics: { + return queryIsActive(query, currentLocation.query); +} - isRunning: false, +module.exports = exports['default']; +},{"./PatternUtils":11}],32:[function(require,module,exports){ +(function (process){ +'use strict'; - cancelPendingTransition: function cancelPendingTransition() { - if (pendingTransition) { - pendingTransition.cancel(); - pendingTransition = null; - } - }, +exports.__esModule = true; - clearAllRoutes: function clearAllRoutes() { - Router.cancelPendingTransition(); - Router.namedRoutes = {}; - Router.routes = []; - }, +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; }; - /** - * Adds routes to this router from the given children object (see ReactChildren). - */ - addRoutes: function addRoutes(routes) { - if (isReactChildren(routes)) routes = createRoutesFromReactChildren(routes); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - addRoutesToNamedRoutes(routes, Router.namedRoutes); +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - Router.routes.push.apply(Router.routes, routes); - }, +var _invariant = require('invariant'); - /** - * Replaces routes of this router from the given children object (see ReactChildren). - */ - replaceRoutes: function replaceRoutes(routes) { - Router.clearAllRoutes(); - Router.addRoutes(routes); - Router.refresh(); - }, +var _invariant2 = _interopRequireDefault(_invariant); - /** - * Performs a match of the given path against this router and returns an object - * with the { routes, params, pathname, query } that match. Returns null if no - * match can be made. - */ - match: function match(path) { - return Match.findMatch(Router.routes, path); - }, +var _createMemoryHistory = require('./createMemoryHistory'); - /** - * Returns an absolute URL path created from the given route - * name, URL parameters, and query. - */ - makePath: function makePath(to, params, query) { - var path; - if (PathUtils.isAbsolute(to)) { - path = to; - } else { - var route = to instanceof Route ? to : Router.namedRoutes[to]; +var _createMemoryHistory2 = _interopRequireDefault(_createMemoryHistory); - invariant(route instanceof Route, 'Cannot find a route named "%s"', to); +var _createTransitionManager = require('./createTransitionManager'); - path = route.path; - } +var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); - return PathUtils.withQuery(PathUtils.injectParams(path, params), query); - }, +var _RouteUtils = require('./RouteUtils'); - /** - * Returns a string that may safely be used as the href of a link - * to the route with the given name, URL parameters, and query. - */ - makeHref: function makeHref(to, params, query) { - var path = Router.makePath(to, params, query); - return location === HashLocation ? '#' + path : path; - }, +var _RouterUtils = require('./RouterUtils'); - /** - * Transitions to the URL specified in the arguments by pushing - * a new URL onto the history stack. - */ - transitionTo: function transitionTo(to, params, query) { - var path = Router.makePath(to, params, query); +/** + * A high-level API to be used for server-side rendering. + * + * This function matches a location to a set of routes and calls + * callback(error, redirectLocation, renderProps) when finished. + * + * Note: You probably don't want to use this in a browser unless you're using + * server-side rendering with async routes. + */ +function match(_ref, callback) { + var history = _ref.history; + var routes = _ref.routes; + var location = _ref.location; - if (pendingTransition) { - // Replace so pending location does not stay in history. - location.replace(path); - } else { - location.push(path); - } - }, + var options = _objectWithoutProperties(_ref, ['history', 'routes', 'location']); - /** - * Transitions to the URL specified in the arguments by replacing - * the current URL in the history stack. - */ - replaceWith: function replaceWith(to, params, query) { - location.replace(Router.makePath(to, params, query)); - }, + !(history || location) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'match needs a history or a location') : _invariant2['default'](false) : undefined; - /** - * Transitions to the previous URL if one is available. Returns true if the - * router was able to go back, false otherwise. - * - * Note: The router only tracks history entries in your application, not the - * current browser session, so you can safely call this function without guarding - * against sending the user back to some other site. However, when using - * RefreshLocation (which is the fallback for HistoryLocation in browsers that - * don't support HTML5 history) this method will *always* send the client back - * because we cannot reliably track history length. - */ - goBack: function goBack() { - if (History.length > 1 || location === RefreshLocation) { - location.pop(); - return true; - } + history = history ? history : _createMemoryHistory2['default'](options); + var transitionManager = _createTransitionManager2['default'](history, _RouteUtils.createRoutes(routes)); - warning(false, 'goBack() was ignored because there is no router history'); + var unlisten = undefined; - return false; - }, + if (location) { + // Allow match({ location: '/the/path', ... }) + location = history.createLocation(location); + } else { + // Pick up the location from the history via synchronous history.listen + // call if needed. + unlisten = history.listen(function (historyLocation) { + location = historyLocation; + }); + } - handleAbort: options.onAbort || function (abortReason) { - if (location instanceof StaticLocation) throw new Error('Unhandled aborted transition! Reason: ' + abortReason); + var router = _RouterUtils.createRouterObject(history, transitionManager); + history = _RouterUtils.createRoutingHistory(history, transitionManager); - if (abortReason instanceof Cancellation) { - return; - } else if (abortReason instanceof Redirect) { - location.replace(Router.makePath(abortReason.to, abortReason.params, abortReason.query)); - } else { - location.pop(); - } - }, + transitionManager.match(location, function (error, redirectLocation, nextState) { + callback(error, redirectLocation, nextState && _extends({}, nextState, { + history: history, + router: router, + matchContext: { history: history, transitionManager: transitionManager, router: router } + })); - handleError: options.onError || function (error) { - // Throw so we don't silently swallow async errors. - throw error; // This error probably originated in a transition hook. - }, + // Defer removing the listener to here to prevent DOM histories from having + // to unwind DOM event listeners unnecessarily, in case callback renders a + // <Router> and attaches another history listener. + if (unlisten) { + unlisten(); + } + }); +} - handleLocationChange: function handleLocationChange(change) { - Router.dispatch(change.path, change.type); - }, +exports['default'] = match; +module.exports = exports['default']; +}).call(this,require('_process')) - /** - * Performs a transition to the given path and calls callback(error, abortReason) - * when the transition is finished. If both arguments are null the router's state - * was updated. Otherwise the transition did not complete. - * - * In a transition, a router first determines which routes are involved by beginning - * with the current route, up the route tree to the first parent route that is shared - * with the destination route, and back down the tree to the destination route. The - * willTransitionFrom hook is invoked on all route handlers we're transitioning away - * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on - * all route handlers we're transitioning to. - * - * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the - * transition. To resolve asynchronously, they may use the callback argument. If no - * hooks wait, the transition is fully synchronous. - */ - dispatch: function dispatch(path, action) { - Router.cancelPendingTransition(); +},{"./RouteUtils":16,"./RouterUtils":19,"./createMemoryHistory":24,"./createTransitionManager":26,"_process":1,"invariant":58}],33:[function(require,module,exports){ +(function (process){ +'use strict'; - var prevPath = state.path; - var isRefreshing = action == null; +exports.__esModule = true; - if (prevPath === path && !isRefreshing) { - return; - } // Nothing to do! +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - // Record the scroll position as early as possible to - // get it before browsers try update it automatically. - if (prevPath && action === LocationActions.PUSH) Router.recordScrollPosition(prevPath); +var _routerWarning = require('./routerWarning'); - var match = Router.match(path); +var _routerWarning2 = _interopRequireDefault(_routerWarning); - warning(match != null, 'No route matches path "%s". Make sure you have <Route path="%s"> somewhere in your routes', path, path); +var _AsyncUtils = require('./AsyncUtils'); - if (match == null) match = {}; +var _PatternUtils = require('./PatternUtils'); - var prevRoutes = state.routes || []; - var prevParams = state.params || {}; - var prevQuery = state.query || {}; +var _RouteUtils = require('./RouteUtils'); - var nextRoutes = match.routes || []; - var nextParams = match.params || {}; - var nextQuery = match.query || {}; +function getChildRoutes(route, location, callback) { + if (route.childRoutes) { + return [null, route.childRoutes]; + } + if (!route.getChildRoutes) { + return []; + } - var fromRoutes, toRoutes; - if (prevRoutes.length) { - fromRoutes = prevRoutes.filter(function (route) { - return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery); - }); + var sync = true, + result = undefined; - toRoutes = nextRoutes.filter(function (route) { - return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery); - }); - } else { - fromRoutes = []; - toRoutes = nextRoutes; - } + route.getChildRoutes(location, function (error, childRoutes) { + childRoutes = !error && _RouteUtils.createRoutes(childRoutes); + if (sync) { + result = [error, childRoutes]; + return; + } - var transition = new Transition(path, Router.replaceWith.bind(Router, path)); - pendingTransition = transition; + callback(error, childRoutes); + }); - var fromComponents = mountedComponents.slice(prevRoutes.length - fromRoutes.length); + sync = false; + return result; // Might be undefined. +} - Transition.from(transition, fromRoutes, fromComponents, function (error) { - if (error || transition.abortReason) return dispatchHandler.call(Router, error, transition); // No need to continue. +function getIndexRoute(route, location, callback) { + if (route.indexRoute) { + callback(null, route.indexRoute); + } else if (route.getIndexRoute) { + route.getIndexRoute(location, function (error, indexRoute) { + callback(error, !error && _RouteUtils.createRoutes(indexRoute)[0]); + }); + } else if (route.childRoutes) { + (function () { + var pathless = route.childRoutes.filter(function (obj) { + return !obj.hasOwnProperty('path'); + }); - Transition.to(transition, toRoutes, nextParams, nextQuery, function (error) { - dispatchHandler.call(Router, error, transition, { - path: path, - action: action, - pathname: match.pathname, - routes: nextRoutes, - params: nextParams, - query: nextQuery - }); - }); + _AsyncUtils.loopAsync(pathless.length, function (index, next, done) { + getIndexRoute(pathless[index], location, function (error, indexRoute) { + if (error || indexRoute) { + var routes = [pathless[index]].concat(Array.isArray(indexRoute) ? indexRoute : [indexRoute]); + done(error, routes); + } else { + next(); + } }); - }, + }, function (err, routes) { + callback(null, routes); + }); + })(); + } else { + callback(); + } +} - /** - * Starts this router and calls callback(router, state) when the route changes. - * - * If the router's location is static (i.e. a URL path in a server environment) - * the callback is called only once. Otherwise, the location should be one of the - * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation). - */ - run: function run(callback) { - invariant(!Router.isRunning, 'Router is already running'); +function assignParams(params, paramNames, paramValues) { + return paramNames.reduce(function (params, paramName, index) { + var paramValue = paramValues && paramValues[index]; + + if (Array.isArray(params[paramName])) { + params[paramName].push(paramValue); + } else if (paramName in params) { + params[paramName] = [params[paramName], paramValue]; + } else { + params[paramName] = paramValue; + } + + return params; + }, params); +} - dispatchHandler = function (error, transition, newState) { - if (error) Router.handleError(error); +function createParams(paramNames, paramValues) { + return assignParams({}, paramNames, paramValues); +} - if (pendingTransition !== transition) return; +function matchRouteDeep(route, location, remainingPathname, paramNames, paramValues, callback) { + var pattern = route.path || ''; - pendingTransition = null; + if (pattern.charAt(0) === '/') { + remainingPathname = location.pathname; + paramNames = []; + paramValues = []; + } + + if (remainingPathname !== null) { + var matched = _PatternUtils.matchPattern(pattern, remainingPathname); + remainingPathname = matched.remainingPathname; + paramNames = [].concat(paramNames, matched.paramNames); + paramValues = [].concat(paramValues, matched.paramValues); + + if (remainingPathname === '' && route.path) { + var _ret2 = (function () { + var match = { + routes: [route], + params: createParams(paramNames, paramValues) + }; - if (transition.abortReason) { - Router.handleAbort(transition.abortReason); + getIndexRoute(route, location, function (error, indexRoute) { + if (error) { + callback(error); } else { - callback.call(Router, Router, nextState = newState); + if (Array.isArray(indexRoute)) { + var _match$routes; + + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](indexRoute.every(function (route) { + return !route.path; + }), 'Index routes should not have paths') : undefined; + (_match$routes = match.routes).push.apply(_match$routes, indexRoute); + } else if (indexRoute) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](!indexRoute.path, 'Index routes should not have paths') : undefined; + match.routes.push(indexRoute); + } + + callback(null, match); } + }); + return { + v: undefined }; + })(); + + if (typeof _ret2 === 'object') return _ret2.v; + } + } - if (!(location instanceof StaticLocation)) { - if (location.addChangeListener) location.addChangeListener(Router.handleLocationChange); + if (remainingPathname != null || route.childRoutes) { + // Either a) this route matched at least some of the path or b) + // we don't have to load this route's children asynchronously. In + // either case continue checking for matches in the subtree. + var onChildRoutes = function onChildRoutes(error, childRoutes) { + if (error) { + callback(error); + } else if (childRoutes) { + // Check the child routes to see if any of them match. + matchRoutes(childRoutes, location, function (error, match) { + if (error) { + callback(error); + } else if (match) { + // A child route matched! Augment the match and pass it up the stack. + match.routes.unshift(route); + callback(null, match); + } else { + callback(); + } + }, remainingPathname, paramNames, paramValues); + } else { + callback(); + } + }; + + var result = getChildRoutes(route, location, onChildRoutes); + if (result) { + onChildRoutes.apply(undefined, result); + } + } else { + callback(); + } +} - Router.isRunning = true; +/** + * Asynchronously matches the given location to a set of routes and calls + * callback(error, state) when finished. The state object will have the + * following properties: + * + * - routes An array of routes that matched, in hierarchical order + * - params An object of URL parameters + * + * Note: This operation may finish synchronously if no routes have an + * asynchronous getChildRoutes method. + */ +function matchRoutes(routes, location, callback) { + var remainingPathname = arguments.length <= 3 || arguments[3] === undefined ? location.pathname : arguments[3]; + var paramNames = arguments.length <= 4 || arguments[4] === undefined ? [] : arguments[4]; + var paramValues = arguments.length <= 5 || arguments[5] === undefined ? [] : arguments[5]; + return (function () { + _AsyncUtils.loopAsync(routes.length, function (index, next, done) { + matchRouteDeep(routes[index], location, remainingPathname, paramNames, paramValues, function (error, match) { + if (error || match) { + done(error, match); + } else { + next(); } + }); + }, callback); + })(); +} - // Bootstrap using the current path. - Router.refresh(); - }, +exports['default'] = matchRoutes; +module.exports = exports['default']; +}).call(this,require('_process')) - refresh: function refresh() { - Router.dispatch(location.getCurrentPath(), null); - }, +},{"./AsyncUtils":4,"./PatternUtils":11,"./RouteUtils":16,"./routerWarning":34,"_process":1}],34:[function(require,module,exports){ +(function (process){ +'use strict'; - stop: function stop() { - Router.cancelPendingTransition(); +exports.__esModule = true; +exports['default'] = routerWarning; - if (location.removeChangeListener) location.removeChangeListener(Router.handleLocationChange); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - Router.isRunning = false; - }, +var _warning = require('warning'); - getLocation: function getLocation() { - return location; - }, +var _warning2 = _interopRequireDefault(_warning); - getScrollBehavior: function getScrollBehavior() { - return scrollBehavior; - }, +function routerWarning(falseToWarn, message) { + message = '[react-router] ' + message; - getRouteAtDepth: function getRouteAtDepth(routeDepth) { - var routes = state.routes; - return routes && routes[routeDepth]; - }, + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } - setRouteComponentAtDepth: function setRouteComponentAtDepth(routeDepth, component) { - mountedComponents[routeDepth] = component; - }, + process.env.NODE_ENV !== 'production' ? _warning2['default'].apply(undefined, [falseToWarn, message].concat(args)) : undefined; +} - /** - * Returns the current URL path + query string. - */ - getCurrentPath: function getCurrentPath() { - return state.path; - }, +module.exports = exports['default']; +}).call(this,require('_process')) - /** - * Returns the current URL path without the query string. - */ - getCurrentPathname: function getCurrentPathname() { - return state.pathname; - }, +},{"_process":1,"warning":59}],35:[function(require,module,exports){ +'use strict'; - /** - * Returns an object of the currently active URL parameters. - */ - getCurrentParams: function getCurrentParams() { - return state.params; - }, +exports.__esModule = true; +exports['default'] = useRouterHistory; - /** - * Returns an object of the currently active query parameters. - */ - getCurrentQuery: function getCurrentQuery() { - return state.query; - }, +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - /** - * Returns an array of the currently active routes. - */ - getCurrentRoutes: function getCurrentRoutes() { - return state.routes; - }, +var _historyLibUseQueries = require('history/lib/useQueries'); - /** - * Returns true if the given route, params, and query are active. - */ - isActive: function isActive(to, params, query) { - if (PathUtils.isAbsolute(to)) { - return to === state.path; - }return routeIsActive(state.routes, to) && paramsAreActive(state.params, params) && (query == null || queryIsActive(state.query, query)); - } +var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); - }, +var _historyLibUseBasename = require('history/lib/useBasename'); - mixins: [ScrollHistory], +var _historyLibUseBasename2 = _interopRequireDefault(_historyLibUseBasename); - propTypes: { - children: PropTypes.falsy - }, +function useRouterHistory(createHistory) { + return function (options) { + var history = _historyLibUseQueries2['default'](_historyLibUseBasename2['default'](createHistory))(options); + history.__v2_compatible__ = true; + return history; + }; +} - childContextTypes: { - routeDepth: PropTypes.number.isRequired, - router: PropTypes.router.isRequired - }, +module.exports = exports['default']; +},{"history/lib/useBasename":51,"history/lib/useQueries":52}],36:[function(require,module,exports){ +(function (process){ +'use strict'; - getChildContext: function getChildContext() { - return { - routeDepth: 1, - router: Router - }; - }, +exports.__esModule = true; - getInitialState: function getInitialState() { - return state = nextState; - }, +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; }; - componentWillReceiveProps: function componentWillReceiveProps() { - this.setState(state = nextState); - }, +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - componentWillUnmount: function componentWillUnmount() { - Router.stop(); - }, +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - render: function render() { - var route = Router.getRouteAtDepth(0); - return route ? React.createElement(route.handler, this.props) : null; - } +var _historyLibUseQueries = require('history/lib/useQueries'); - }); +var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); + +var _createTransitionManager = require('./createTransitionManager'); + +var _createTransitionManager2 = _interopRequireDefault(_createTransitionManager); + +var _routerWarning = require('./routerWarning'); + +var _routerWarning2 = _interopRequireDefault(_routerWarning); + +/** + * Returns a new createHistory function that may be used to create + * history objects that know about routing. + * + * Enhances history objects with the following methods: + * + * - listen((error, nextState) => {}) + * - listenBeforeLeavingRoute(route, (nextLocation) => {}) + * - match(location, (error, redirectLocation, nextState) => {}) + * - isActive(pathname, query, indexOnly=false) + */ +function useRoutes(createHistory) { + process.env.NODE_ENV !== 'production' ? _routerWarning2['default'](false, '`useRoutes` is deprecated. Please use `createTransitionManager` instead.') : undefined; - Router.clearAllRoutes(); + return function () { + var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - if (options.routes) Router.addRoutes(options.routes); + var routes = _ref.routes; - return Router; + var options = _objectWithoutProperties(_ref, ['routes']); + + var history = _historyLibUseQueries2['default'](createHistory)(options); + var transitionManager = _createTransitionManager2['default'](history, routes); + return _extends({}, history, transitionManager); + }; } -module.exports = createRouter; +exports['default'] = useRoutes; +module.exports = exports['default']; }).call(this,require('_process')) -},{"./Cancellation":4,"./History":5,"./Match":6,"./PathUtils":8,"./PropTypes":9,"./Redirect":10,"./Route":11,"./ScrollHistory":12,"./Transition":14,"./actions/LocationActions":15,"./behaviors/ImitateBrowserBehavior":16,"./createRoutesFromReactChildren":26,"./isReactChildren":28,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./supportsHistory":35,"_process":1,"react":"react","react/lib/ExecutionEnvironment":62,"react/lib/invariant":191,"react/lib/warning":212}],26:[function(require,module,exports){ -/* jshint -W084 */ +},{"./createTransitionManager":26,"./routerWarning":34,"_process":1,"history/lib/useQueries":52}],37:[function(require,module,exports){ +/** + * Indicates that navigation was caused by a call to history.push. + */ 'use strict'; -var React = require('react'); -var assign = require('react/lib/Object.assign'); -var warning = require('react/lib/warning'); -var DefaultRoute = require('./components/DefaultRoute'); -var NotFoundRoute = require('./components/NotFoundRoute'); -var Redirect = require('./components/Redirect'); -var Route = require('./Route'); +exports.__esModule = true; +var PUSH = 'PUSH'; -function checkPropTypes(componentName, propTypes, props) { - componentName = componentName || 'UnknownComponent'; +exports.PUSH = PUSH; +/** + * Indicates that navigation was caused by a call to history.replace. + */ +var REPLACE = 'REPLACE'; - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, componentName); +exports.REPLACE = REPLACE; +/** + * Indicates that navigation was caused by some other action such + * as using a browser's back/forward buttons and/or manually manipulating + * the URL in a browser's location bar. This is the default. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate + * for more information. + */ +var POP = 'POP'; + +exports.POP = POP; +exports['default'] = { + PUSH: PUSH, + REPLACE: REPLACE, + POP: POP +}; +},{}],38:[function(require,module,exports){ +"use strict"; + +exports.__esModule = true; +exports.loopAsync = loopAsync; + +function loopAsync(turns, work, callback) { + var currentTurn = 0; + var isDone = false; + + function done() { + isDone = true; + callback.apply(this, arguments); + } + + function next() { + if (isDone) return; - if (error instanceof Error) warning(false, error.message); + if (currentTurn < turns) { + work.call(this, currentTurn++, next, done); + } else { + done.apply(this, arguments); } } + + next(); } +},{}],39:[function(require,module,exports){ +(function (process){ +/*eslint-disable no-empty */ +'use strict'; -function createRouteOptions(props) { - var options = assign({}, props); - var handler = options.handler; +exports.__esModule = true; +exports.saveState = saveState; +exports.readState = readState; - if (handler) { - options.onEnter = handler.willTransitionTo; - options.onLeave = handler.willTransitionFrom; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _warning = require('warning'); + +var _warning2 = _interopRequireDefault(_warning); - return options; +var KeyPrefix = '@@History/'; +var QuotaExceededErrors = ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR']; + +var SecurityError = 'SecurityError'; + +function createKey(key) { + return KeyPrefix + key; } -function createRouteFromReactElement(element) { - if (!React.isValidElement(element)) { - return; - }var type = element.type; - var props = assign({}, type.defaultProps, element.props); - - if (type.propTypes) checkPropTypes(type.displayName, type.propTypes, props); - - if (type === DefaultRoute) { - return Route.createDefaultRoute(createRouteOptions(props)); - }if (type === NotFoundRoute) { - return Route.createNotFoundRoute(createRouteOptions(props)); - }if (type === Redirect) { - return Route.createRedirect(createRouteOptions(props)); - }return Route.createRoute(createRouteOptions(props), function () { - if (props.children) createRoutesFromReactChildren(props.children); - }); +function saveState(key, state) { + try { + if (state == null) { + window.sessionStorage.removeItem(createKey(key)); + } else { + window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); + } + } catch (error) { + if (error.name === SecurityError) { + // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any + // attempt to access window.sessionStorage. + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available due to security settings') : undefined; + + return; + } + + if (QuotaExceededErrors.indexOf(error.name) >= 0 && window.sessionStorage.length === 0) { + // Safari "private mode" throws QuotaExceededError. + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : undefined; + + return; + } + + throw error; + } } -/** - * Creates and returns an array of routes created from the given - * ReactChildren, all of which should be one of <Route>, <DefaultRoute>, - * <NotFoundRoute>, or <Redirect>, e.g.: - * - * var { createRoutesFromReactChildren, Route, Redirect } = require('react-router'); - * - * var routes = createRoutesFromReactChildren( - * <Route path="/" handler={App}> - * <Route name="user" path="/user/:userId" handler={User}> - * <Route name="task" path="tasks/:taskId" handler={Task}/> - * <Redirect from="todos/:taskId" to="task"/> - * </Route> - * </Route> - * ); - */ -function createRoutesFromReactChildren(children) { - var routes = []; +function readState(key) { + var json = undefined; + try { + json = window.sessionStorage.getItem(createKey(key)); + } catch (error) { + if (error.name === SecurityError) { + // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any + // attempt to access window.sessionStorage. + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to read state; sessionStorage is not available due to security settings') : undefined; - React.Children.forEach(children, function (child) { - if (child = createRouteFromReactElement(child)) routes.push(child); - }); + return null; + } + } - return routes; + if (json) { + try { + return JSON.parse(json); + } catch (error) { + // Ignore invalid JSON. + } + } + + return null; } +}).call(this,require('_process')) -module.exports = createRoutesFromReactChildren; -},{"./Route":11,"./components/DefaultRoute":19,"./components/NotFoundRoute":21,"./components/Redirect":22,"react":"react","react/lib/Object.assign":69,"react/lib/warning":212}],27:[function(require,module,exports){ +},{"_process":1,"warning":59}],40:[function(require,module,exports){ 'use strict'; -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +exports.__esModule = true; +exports.addEventListener = addEventListener; +exports.removeEventListener = removeEventListener; +exports.getHashPath = getHashPath; +exports.replaceHashPath = replaceHashPath; +exports.getWindowPath = getWindowPath; +exports.go = go; +exports.getUserConfirmation = getUserConfirmation; +exports.supportsHistory = supportsHistory; +exports.supportsGoWithoutReloadUsingHash = supportsGoWithoutReloadUsingHash; + +function addEventListener(node, event, listener) { + if (node.addEventListener) { + node.addEventListener(event, listener, false); + } else { + node.attachEvent('on' + event, listener); + } +} -/** - * Returns the current scroll position of the window as { x, y }. - */ -function getWindowScrollPosition() { - invariant(canUseDOM, 'Cannot get current scroll position without a DOM'); +function removeEventListener(node, event, listener) { + if (node.removeEventListener) { + node.removeEventListener(event, listener, false); + } else { + node.detachEvent('on' + event, listener); + } +} - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; +function getHashPath() { + // We can't use window.location.hash here because it's not + // consistent across browsers - Firefox will pre-decode it! + return window.location.href.split('#')[1] || ''; } -module.exports = getWindowScrollPosition; -},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],28:[function(require,module,exports){ -'use strict'; +function replaceHashPath(path) { + window.location.replace(window.location.pathname + window.location.search + '#' + path); +} -var React = require('react'); +function getWindowPath() { + return window.location.pathname + window.location.search + window.location.hash; +} -function isValidChild(object) { - return object == null || React.isValidElement(object); +function go(n) { + if (n) window.history.go(n); } -function isReactChildren(object) { - return isValidChild(object) || Array.isArray(object) && object.every(isValidChild); +function getUserConfirmation(message, callback) { + callback(window.confirm(message)); +} + +/** + * Returns true if the HTML5 history API is supported. Taken from Modernizr. + * + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 + */ + +function supportsHistory() { + var ua = navigator.userAgent; + if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) { + return false; + } + return window.history && 'pushState' in window.history; +} + +/** + * Returns false if using go(n) with hash history causes a full page reload. + */ + +function supportsGoWithoutReloadUsingHash() { + var ua = navigator.userAgent; + return ua.indexOf('Firefox') === -1; } +},{}],41:[function(require,module,exports){ +'use strict'; -module.exports = isReactChildren; -},{"react":"react"}],29:[function(require,module,exports){ +exports.__esModule = true; +var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); +exports.canUseDOM = canUseDOM; +},{}],42:[function(require,module,exports){ +(function (process){ 'use strict'; -var LocationActions = require('../actions/LocationActions'); -var History = require('../History'); +exports.__esModule = true; +exports.extractPath = extractPath; +exports.parsePath = parsePath; -var _listeners = []; -var _isListening = false; -var _actionType; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -function notifyChange(type) { - if (type === LocationActions.PUSH) History.length += 1; +var _warning = require('warning'); - var change = { - path: HashLocation.getCurrentPath(), - type: type - }; +var _warning2 = _interopRequireDefault(_warning); - _listeners.forEach(function (listener) { - listener.call(HashLocation, change); - }); +function extractPath(string) { + var match = string.match(/^https?:\/\/[^\/]*/); + + if (match == null) return string; + + return string.substring(match[0].length); } -function ensureSlash() { - var path = HashLocation.getCurrentPath(); +function parsePath(path) { + var pathname = extractPath(path); + var search = ''; + var hash = ''; - if (path.charAt(0) === '/') { - return true; - }HashLocation.replace('/' + path); + process.env.NODE_ENV !== 'production' ? _warning2['default'](path === pathname, 'A path must be pathname + search + hash only, not a fully qualified URL like "%s"', path) : undefined; - return false; -} + var hashIndex = pathname.indexOf('#'); + if (hashIndex !== -1) { + hash = pathname.substring(hashIndex); + pathname = pathname.substring(0, hashIndex); + } -function onHashChange() { - if (ensureSlash()) { - // If we don't have an _actionType then all we know is the hash - // changed. It was probably caused by the user clicking the Back - // button, but may have also been the Forward button or manual - // manipulation. So just guess 'pop'. - var curActionType = _actionType; - _actionType = null; - notifyChange(curActionType || LocationActions.POP); + var searchIndex = pathname.indexOf('?'); + if (searchIndex !== -1) { + search = pathname.substring(searchIndex); + pathname = pathname.substring(0, searchIndex); } + + if (pathname === '') pathname = '/'; + + return { + pathname: pathname, + search: search, + hash: hash + }; } +}).call(this,require('_process')) + +},{"_process":1,"warning":59}],43:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _Actions = require('./Actions'); + +var _PathUtils = require('./PathUtils'); + +var _ExecutionEnvironment = require('./ExecutionEnvironment'); + +var _DOMUtils = require('./DOMUtils'); + +var _DOMStateStorage = require('./DOMStateStorage'); + +var _createDOMHistory = require('./createDOMHistory'); + +var _createDOMHistory2 = _interopRequireDefault(_createDOMHistory); /** - * A Location that uses `window.location.hash`. + * Creates and returns a history object that uses HTML5's history API + * (pushState, replaceState, and the popstate event) to manage history. + * This is the recommended method of managing history in browsers because + * it provides the cleanest URLs. + * + * Note: In browsers that do not support the HTML5 history API full + * page reloads will be used to preserve URLs. */ -var HashLocation = { +function createBrowserHistory() { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - addChangeListener: function addChangeListener(listener) { - _listeners.push(listener); + !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Browser history needs a DOM') : _invariant2['default'](false) : undefined; - // Do this BEFORE listening for hashchange. - ensureSlash(); + var forceRefresh = options.forceRefresh; - if (!_isListening) { - if (window.addEventListener) { - window.addEventListener('hashchange', onHashChange, false); - } else { - window.attachEvent('onhashchange', onHashChange); - } + var isSupported = _DOMUtils.supportsHistory(); + var useRefresh = !isSupported || forceRefresh; - _isListening = true; + function getCurrentLocation(historyState) { + historyState = historyState || window.history.state || {}; + + var path = _DOMUtils.getWindowPath(); + var _historyState = historyState; + var key = _historyState.key; + + var state = undefined; + if (key) { + state = _DOMStateStorage.readState(key); + } else { + state = null; + key = history.createKey(); + + if (isSupported) window.history.replaceState(_extends({}, historyState, { key: key }), null, path); } - }, - removeChangeListener: function removeChangeListener(listener) { - _listeners = _listeners.filter(function (l) { - return l !== listener; - }); + var location = _PathUtils.parsePath(path); - if (_listeners.length === 0) { - if (window.removeEventListener) { - window.removeEventListener('hashchange', onHashChange, false); - } else { - window.removeEvent('onhashchange', onHashChange); - } + return history.createLocation(_extends({}, location, { state: state }), undefined, key); + } - _isListening = false; + function startPopStateListener(_ref) { + var transitionTo = _ref.transitionTo; + + function popStateListener(event) { + if (event.state === undefined) return; // Ignore extraneous popstate events in WebKit. + + transitionTo(getCurrentLocation(event.state)); } - }, - push: function push(path) { - _actionType = LocationActions.PUSH; - window.location.hash = path; - }, + _DOMUtils.addEventListener(window, 'popstate', popStateListener); - replace: function replace(path) { - _actionType = LocationActions.REPLACE; - window.location.replace(window.location.pathname + window.location.search + '#' + path); - }, + return function () { + _DOMUtils.removeEventListener(window, 'popstate', popStateListener); + }; + } - pop: function pop() { - _actionType = LocationActions.POP; - History.back(); - }, + function finishTransition(location) { + var basename = location.basename; + var pathname = location.pathname; + var search = location.search; + var hash = location.hash; + var state = location.state; + var action = location.action; + var key = location.key; - getCurrentPath: function getCurrentPath() { - return decodeURI( - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - window.location.href.split('#')[1] || ''); - }, + if (action === _Actions.POP) return; // Nothing to do. + + _DOMStateStorage.saveState(key, state); - toString: function toString() { - return '<HashLocation>'; + var path = (basename || '') + pathname + search + hash; + var historyState = { + key: key + }; + + if (action === _Actions.PUSH) { + if (useRefresh) { + window.location.href = path; + return false; // Prevent location update. + } else { + window.history.pushState(historyState, null, path); + } + } else { + // REPLACE + if (useRefresh) { + window.location.replace(path); + return false; // Prevent location update. + } else { + window.history.replaceState(historyState, null, path); + } + } } -}; + var history = _createDOMHistory2['default'](_extends({}, options, { + getCurrentLocation: getCurrentLocation, + finishTransition: finishTransition, + saveState: _DOMStateStorage.saveState + })); + + var listenerCount = 0, + stopPopStateListener = undefined; + + function listenBefore(listener) { + if (++listenerCount === 1) stopPopStateListener = startPopStateListener(history); + + var unlisten = history.listenBefore(listener); + + return function () { + unlisten(); + + if (--listenerCount === 0) stopPopStateListener(); + }; + } -module.exports = HashLocation; -},{"../History":5,"../actions/LocationActions":15}],30:[function(require,module,exports){ + function listen(listener) { + if (++listenerCount === 1) stopPopStateListener = startPopStateListener(history); + + var unlisten = history.listen(listener); + + return function () { + unlisten(); + + if (--listenerCount === 0) stopPopStateListener(); + }; + } + + // deprecated + function registerTransitionHook(hook) { + if (++listenerCount === 1) stopPopStateListener = startPopStateListener(history); + + history.registerTransitionHook(hook); + } + + // deprecated + function unregisterTransitionHook(hook) { + history.unregisterTransitionHook(hook); + + if (--listenerCount === 0) stopPopStateListener(); + } + + return _extends({}, history, { + listenBefore: listenBefore, + listen: listen, + registerTransitionHook: registerTransitionHook, + unregisterTransitionHook: unregisterTransitionHook + }); +} + +exports['default'] = createBrowserHistory; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./Actions":37,"./DOMStateStorage":39,"./DOMUtils":40,"./ExecutionEnvironment":41,"./PathUtils":42,"./createDOMHistory":44,"_process":1,"invariant":58}],44:[function(require,module,exports){ +(function (process){ 'use strict'; -var LocationActions = require('../actions/LocationActions'); -var History = require('../History'); +exports.__esModule = true; -var _listeners = []; -var _isListening = false; +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; }; -function notifyChange(type) { - var change = { - path: HistoryLocation.getCurrentPath(), - type: type - }; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _ExecutionEnvironment = require('./ExecutionEnvironment'); + +var _DOMUtils = require('./DOMUtils'); + +var _createHistory = require('./createHistory'); + +var _createHistory2 = _interopRequireDefault(_createHistory); - _listeners.forEach(function (listener) { - listener.call(HistoryLocation, change); +function createDOMHistory(options) { + var history = _createHistory2['default'](_extends({ + getUserConfirmation: _DOMUtils.getUserConfirmation + }, options, { + go: _DOMUtils.go + })); + + function listen(listener) { + !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'DOM history needs a DOM') : _invariant2['default'](false) : undefined; + + return history.listen(listener); + } + + return _extends({}, history, { + listen: listen }); } -function onPopState(event) { - if (event.state === undefined) { - return; - } // Ignore extraneous popstate events in WebKit. +exports['default'] = createDOMHistory; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./DOMUtils":40,"./ExecutionEnvironment":41,"./createHistory":46,"_process":1,"invariant":58}],45:[function(require,module,exports){ +(function (process){ +'use strict'; + +exports.__esModule = true; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - notifyChange(LocationActions.POP); +var _warning = require('warning'); + +var _warning2 = _interopRequireDefault(_warning); + +var _invariant = require('invariant'); + +var _invariant2 = _interopRequireDefault(_invariant); + +var _Actions = require('./Actions'); + +var _PathUtils = require('./PathUtils'); + +var _ExecutionEnvironment = require('./ExecutionEnvironment'); + +var _DOMUtils = require('./DOMUtils'); + +var _DOMStateStorage = require('./DOMStateStorage'); + +var _createDOMHistory = require('./createDOMHistory'); + +var _createDOMHistory2 = _interopRequireDefault(_createDOMHistory); + +function isAbsolutePath(path) { + return typeof path === 'string' && path.charAt(0) === '/'; } -/** - * A Location that uses HTML5 history. - */ -var HistoryLocation = { +function ensureSlash() { + var path = _DOMUtils.getHashPath(); + + if (isAbsolutePath(path)) return true; + + _DOMUtils.replaceHashPath('/' + path); + + return false; +} + +function addQueryStringValueToPath(path, key, value) { + return path + (path.indexOf('?') === -1 ? '?' : '&') + (key + '=' + value); +} + +function stripQueryStringValueFromPath(path, key) { + return path.replace(new RegExp('[?&]?' + key + '=[a-zA-Z0-9]+'), ''); +} + +function getQueryStringValueFromPath(path, key) { + var match = path.match(new RegExp('\\?.*?\\b' + key + '=(.+?)\\b')); + return match && match[1]; +} + +var DefaultQueryKey = '_k'; - addChangeListener: function addChangeListener(listener) { - _listeners.push(listener); +function createHashHistory() { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - if (!_isListening) { - if (window.addEventListener) { - window.addEventListener('popstate', onPopState, false); + !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Hash history needs a DOM') : _invariant2['default'](false) : undefined; + + var queryKey = options.queryKey; + + if (queryKey === undefined || !!queryKey) queryKey = typeof queryKey === 'string' ? queryKey : DefaultQueryKey; + + function getCurrentLocation() { + var path = _DOMUtils.getHashPath(); + + var key = undefined, + state = undefined; + if (queryKey) { + key = getQueryStringValueFromPath(path, queryKey); + path = stripQueryStringValueFromPath(path, queryKey); + + if (key) { + state = _DOMStateStorage.readState(key); } else { - window.attachEvent('onpopstate', onPopState); + state = null; + key = history.createKey(); + _DOMUtils.replaceHashPath(addQueryStringValueToPath(path, queryKey, key)); } + } else { + key = state = null; + } - _isListening = true; + var location = _PathUtils.parsePath(path); + + return history.createLocation(_extends({}, location, { state: state }), undefined, key); + } + + function startHashChangeListener(_ref) { + var transitionTo = _ref.transitionTo; + + function hashChangeListener() { + if (!ensureSlash()) return; // Always make sure hashes are preceeded with a /. + + transitionTo(getCurrentLocation()); } - }, - removeChangeListener: function removeChangeListener(listener) { - _listeners = _listeners.filter(function (l) { - return l !== listener; - }); + ensureSlash(); + _DOMUtils.addEventListener(window, 'hashchange', hashChangeListener); + + return function () { + _DOMUtils.removeEventListener(window, 'hashchange', hashChangeListener); + }; + } + + function finishTransition(location) { + var basename = location.basename; + var pathname = location.pathname; + var search = location.search; + var state = location.state; + var action = location.action; + var key = location.key; + + if (action === _Actions.POP) return; // Nothing to do. - if (_listeners.length === 0) { - if (window.addEventListener) { - window.removeEventListener('popstate', onPopState, false); + var path = (basename || '') + pathname + search; + + if (queryKey) { + path = addQueryStringValueToPath(path, queryKey, key); + _DOMStateStorage.saveState(key, state); + } else { + // Drop key and state. + location.key = location.state = null; + } + + var currentHash = _DOMUtils.getHashPath(); + + if (action === _Actions.PUSH) { + if (currentHash !== path) { + window.location.hash = path; } else { - window.removeEvent('onpopstate', onPopState); + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'You cannot PUSH the same path using hash history') : undefined; } - - _isListening = false; + } else if (currentHash !== path) { + // REPLACE + _DOMUtils.replaceHashPath(path); } - }, + } - push: function push(path) { - window.history.pushState({ path: path }, '', path); - History.length += 1; - notifyChange(LocationActions.PUSH); - }, + var history = _createDOMHistory2['default'](_extends({}, options, { + getCurrentLocation: getCurrentLocation, + finishTransition: finishTransition, + saveState: _DOMStateStorage.saveState + })); - replace: function replace(path) { - window.history.replaceState({ path: path }, '', path); - notifyChange(LocationActions.REPLACE); - }, + var listenerCount = 0, + stopHashChangeListener = undefined; - pop: History.back, + function listenBefore(listener) { + if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - getCurrentPath: function getCurrentPath() { - return decodeURI(window.location.pathname + window.location.search); - }, + var unlisten = history.listenBefore(listener); - toString: function toString() { - return '<HistoryLocation>'; - } + return function () { + unlisten(); -}; + if (--listenerCount === 0) stopHashChangeListener(); + }; + } -module.exports = HistoryLocation; -},{"../History":5,"../actions/LocationActions":15}],31:[function(require,module,exports){ -'use strict'; + function listen(listener) { + if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); -var HistoryLocation = require('./HistoryLocation'); -var History = require('../History'); + var unlisten = history.listen(listener); -/** - * A Location that uses full page refreshes. This is used as - * the fallback for HistoryLocation in browsers that do not - * support the HTML5 history API. - */ -var RefreshLocation = { + return function () { + unlisten(); - push: function push(path) { - window.location = path; - }, + if (--listenerCount === 0) stopHashChangeListener(); + }; + } - replace: function replace(path) { - window.location.replace(path); - }, + function push(location) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - pop: History.back, + history.push(location); + } - getCurrentPath: HistoryLocation.getCurrentPath, + function replace(location) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - toString: function toString() { - return '<RefreshLocation>'; + history.replace(location); } -}; + var goIsSupportedWithoutReload = _DOMUtils.supportsGoWithoutReloadUsingHash(); -module.exports = RefreshLocation; -},{"../History":5,"./HistoryLocation":30}],32:[function(require,module,exports){ -'use strict'; + function go(n) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](goIsSupportedWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : undefined; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; + history.go(n); + } -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + function createHref(path) { + return '#' + history.createHref(path); + } -var invariant = require('react/lib/invariant'); + // deprecated + function registerTransitionHook(hook) { + if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); -function throwCannotModify() { - invariant(false, 'You cannot modify a static location'); -} + history.registerTransitionHook(hook); + } -/** - * A location that only ever contains a single path. Useful in - * stateless environments like servers where there is no path history, - * only the path that was used in the request. - */ + // deprecated + function unregisterTransitionHook(hook) { + history.unregisterTransitionHook(hook); + + if (--listenerCount === 0) stopHashChangeListener(); + } -var StaticLocation = (function () { - function StaticLocation(path) { - _classCallCheck(this, StaticLocation); + // deprecated + function pushState(state, path) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - this.path = path; + history.pushState(state, path); } - _createClass(StaticLocation, [{ - key: 'getCurrentPath', - value: function getCurrentPath() { - return this.path; - } - }, { - key: 'toString', - value: function toString() { - return '<StaticLocation path="' + this.path + '">'; - } - }]); + // deprecated + function replaceState(state, path) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - return StaticLocation; -})(); + history.replaceState(state, path); + } -// TODO: Include these in the above class definition -// once we can use ES7 property initializers. -// https://github.com/babel/babel/issues/619 + return _extends({}, history, { + listenBefore: listenBefore, + listen: listen, + push: push, + replace: replace, + go: go, + createHref: createHref, -StaticLocation.prototype.push = throwCannotModify; -StaticLocation.prototype.replace = throwCannotModify; -StaticLocation.prototype.pop = throwCannotModify; + registerTransitionHook: registerTransitionHook, // deprecated - warning is in createHistory + unregisterTransitionHook: unregisterTransitionHook, // deprecated - warning is in createHistory + pushState: pushState, // deprecated - warning is in createHistory + replaceState: replaceState // deprecated - warning is in createHistory + }); +} -module.exports = StaticLocation; -},{"react/lib/invariant":191}],33:[function(require,module,exports){ +exports['default'] = createHashHistory; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./Actions":37,"./DOMStateStorage":39,"./DOMUtils":40,"./ExecutionEnvironment":41,"./PathUtils":42,"./createDOMHistory":44,"_process":1,"invariant":58,"warning":59}],46:[function(require,module,exports){ +(function (process){ 'use strict'; -var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; +exports.__esModule = true; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var invariant = require('react/lib/invariant'); -var LocationActions = require('../actions/LocationActions'); -var History = require('../History'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -/** - * A location that is convenient for testing and does not require a DOM. - */ +var _warning = require('warning'); -var TestLocation = (function () { - function TestLocation(history) { - _classCallCheck(this, TestLocation); +var _warning2 = _interopRequireDefault(_warning); - this.history = history || []; - this.listeners = []; - this._updateHistoryLength(); +var _deepEqual = require('deep-equal'); + +var _deepEqual2 = _interopRequireDefault(_deepEqual); + +var _PathUtils = require('./PathUtils'); + +var _AsyncUtils = require('./AsyncUtils'); + +var _Actions = require('./Actions'); + +var _createLocation2 = require('./createLocation'); + +var _createLocation3 = _interopRequireDefault(_createLocation2); + +var _runTransitionHook = require('./runTransitionHook'); + +var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); + +var _deprecate = require('./deprecate'); + +var _deprecate2 = _interopRequireDefault(_deprecate); + +function createRandomKey(length) { + return Math.random().toString(36).substr(2, length); +} + +function locationsAreEqual(a, b) { + return a.pathname === b.pathname && a.search === b.search && + //a.action === b.action && // Different action !== location change. + a.key === b.key && _deepEqual2['default'](a.state, b.state); +} + +var DefaultKeyLength = 6; + +function createHistory() { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + var getCurrentLocation = options.getCurrentLocation; + var finishTransition = options.finishTransition; + var saveState = options.saveState; + var go = options.go; + var keyLength = options.keyLength; + var getUserConfirmation = options.getUserConfirmation; + + if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; + + var transitionHooks = []; + + function listenBefore(hook) { + transitionHooks.push(hook); + + return function () { + transitionHooks = transitionHooks.filter(function (item) { + return item !== hook; + }); + }; } - _createClass(TestLocation, [{ - key: 'needsDOM', - get: function () { - return false; + var allKeys = []; + var changeListeners = []; + var location = undefined; + + function getCurrent() { + if (pendingLocation && pendingLocation.action === _Actions.POP) { + return allKeys.indexOf(pendingLocation.key); + } else if (location) { + return allKeys.indexOf(location.key); + } else { + return -1; } - }, { - key: '_updateHistoryLength', - value: function _updateHistoryLength() { - History.length = this.history.length; - } - }, { - key: '_notifyChange', - value: function _notifyChange(type) { - var change = { - path: this.getCurrentPath(), - type: type - }; + } + + function updateLocation(newLocation) { + var current = getCurrent(); + + location = newLocation; - for (var i = 0, len = this.listeners.length; i < len; ++i) this.listeners[i].call(this, change); + if (location.action === _Actions.PUSH) { + allKeys = [].concat(allKeys.slice(0, current + 1), [location.key]); + } else if (location.action === _Actions.REPLACE) { + allKeys[current] = location.key; } - }, { - key: 'addChangeListener', - value: function addChangeListener(listener) { - this.listeners.push(listener); + + changeListeners.forEach(function (listener) { + listener(location); + }); + } + + function listen(listener) { + changeListeners.push(listener); + + if (location) { + listener(location); + } else { + var _location = getCurrentLocation(); + allKeys = [_location.key]; + updateLocation(_location); } - }, { - key: 'removeChangeListener', - value: function removeChangeListener(listener) { - this.listeners = this.listeners.filter(function (l) { - return l !== listener; + + return function () { + changeListeners = changeListeners.filter(function (item) { + return item !== listener; }); - } - }, { - key: 'push', - value: function push(path) { - this.history.push(path); - this._updateHistoryLength(); - this._notifyChange(LocationActions.PUSH); - } - }, { - key: 'replace', - value: function replace(path) { - invariant(this.history.length, 'You cannot replace the current path with no history'); + }; + } - this.history[this.history.length - 1] = path; + function confirmTransitionTo(location, callback) { + _AsyncUtils.loopAsync(transitionHooks.length, function (index, next, done) { + _runTransitionHook2['default'](transitionHooks[index], location, function (result) { + if (result != null) { + done(result); + } else { + next(); + } + }); + }, function (message) { + if (getUserConfirmation && typeof message === 'string') { + getUserConfirmation(message, function (ok) { + callback(ok !== false); + }); + } else { + callback(message !== false); + } + }); + } - this._notifyChange(LocationActions.REPLACE); - } - }, { - key: 'pop', - value: function pop() { - this.history.pop(); - this._updateHistoryLength(); - this._notifyChange(LocationActions.POP); - } - }, { - key: 'getCurrentPath', - value: function getCurrentPath() { - return this.history[this.history.length - 1]; + var pendingLocation = undefined; + + function transitionTo(nextLocation) { + if (location && locationsAreEqual(location, nextLocation)) return; // Nothing to do. + + pendingLocation = nextLocation; + + confirmTransitionTo(nextLocation, function (ok) { + if (pendingLocation !== nextLocation) return; // Transition was interrupted. + + if (ok) { + // treat PUSH to current path like REPLACE to be consistent with browsers + if (nextLocation.action === _Actions.PUSH) { + var prevPath = createPath(location); + var nextPath = createPath(nextLocation); + + if (nextPath === prevPath && _deepEqual2['default'](location.state, nextLocation.state)) nextLocation.action = _Actions.REPLACE; + } + + if (finishTransition(nextLocation) !== false) updateLocation(nextLocation); + } else if (location && nextLocation.action === _Actions.POP) { + var prevIndex = allKeys.indexOf(location.key); + var nextIndex = allKeys.indexOf(nextLocation.key); + + if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); // Restore the URL. + } + }); + } + + function push(location) { + transitionTo(createLocation(location, _Actions.PUSH, createKey())); + } + + function replace(location) { + transitionTo(createLocation(location, _Actions.REPLACE, createKey())); + } + + function goBack() { + go(-1); + } + + function goForward() { + go(1); + } + + function createKey() { + return createRandomKey(keyLength); + } + + function createPath(location) { + if (location == null || typeof location === 'string') return location; + + var pathname = location.pathname; + var search = location.search; + var hash = location.hash; + + var result = pathname; + + if (search) result += search; + + if (hash) result += hash; + + return result; + } + + function createHref(location) { + return createPath(location); + } + + function createLocation(location, action) { + var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2]; + + if (typeof action === 'object') { + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'The state (2nd) argument to history.createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; + + if (typeof location === 'string') location = _PathUtils.parsePath(location); + + location = _extends({}, location, { state: action }); + + action = key; + key = arguments[3] || createKey(); } - }, { - key: 'toString', - value: function toString() { - return '<TestLocation>'; + + return _createLocation3['default'](location, action, key); + } + + // deprecated + function setState(state) { + if (location) { + updateLocationState(location, state); + updateLocation(location); + } else { + updateLocationState(getCurrentLocation(), state); } - }]); + } - return TestLocation; -})(); + function updateLocationState(location, state) { + location.state = _extends({}, location.state, state); + saveState(location.key, location.state); + } -module.exports = TestLocation; -},{"../History":5,"../actions/LocationActions":15,"react/lib/invariant":191}],34:[function(require,module,exports){ -'use strict'; + // deprecated + function registerTransitionHook(hook) { + if (transitionHooks.indexOf(hook) === -1) transitionHooks.push(hook); + } -var createRouter = require('./createRouter'); + // deprecated + function unregisterTransitionHook(hook) { + transitionHooks = transitionHooks.filter(function (item) { + return item !== hook; + }); + } -/** - * A high-level convenience method that creates, configures, and - * runs a router in one shot. The method signature is: - * - * Router.run(routes[, location ], callback); - * - * Using `window.location.hash` to manage the URL, you could do: - * - * Router.run(routes, function (Handler) { - * React.render(<Handler/>, document.body); - * }); - * - * Using HTML5 history and a custom "cursor" prop: - * - * Router.run(routes, Router.HistoryLocation, function (Handler) { - * React.render(<Handler cursor={cursor}/>, document.body); - * }); - * - * Returns the newly created router. - * - * Note: If you need to specify further options for your router such - * as error/abort handling or custom scroll behavior, use Router.create - * instead. - * - * var router = Router.create(options); - * router.run(function (Handler) { - * // ... - * }); - */ -function runRouter(routes, location, callback) { - if (typeof location === 'function') { - callback = location; - location = null; + // deprecated + function pushState(state, path) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); + + push(_extends({ state: state }, path)); } - var router = createRouter({ - routes: routes, - location: location - }); + // deprecated + function replaceState(state, path) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); - router.run(callback); + replace(_extends({ state: state }, path)); + } - return router; + return { + listenBefore: listenBefore, + listen: listen, + transitionTo: transitionTo, + push: push, + replace: replace, + go: go, + goBack: goBack, + goForward: goForward, + createKey: createKey, + createPath: createPath, + createHref: createHref, + createLocation: createLocation, + + setState: _deprecate2['default'](setState, 'setState is deprecated; use location.key to save state instead'), + registerTransitionHook: _deprecate2['default'](registerTransitionHook, 'registerTransitionHook is deprecated; use listenBefore instead'), + unregisterTransitionHook: _deprecate2['default'](unregisterTransitionHook, 'unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead'), + pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), + replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') + }; } -module.exports = runRouter; -},{"./createRouter":25}],35:[function(require,module,exports){ +exports['default'] = createHistory; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./Actions":37,"./AsyncUtils":38,"./PathUtils":42,"./createLocation":47,"./deprecate":49,"./runTransitionHook":50,"_process":1,"deep-equal":53,"warning":59}],47:[function(require,module,exports){ +(function (process){ 'use strict'; -function supportsHistory() { - /*! taken from modernizr - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 - */ - var ua = navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) { - return false; +exports.__esModule = true; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _warning = require('warning'); + +var _warning2 = _interopRequireDefault(_warning); + +var _Actions = require('./Actions'); + +var _PathUtils = require('./PathUtils'); + +function createLocation() { + var location = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0]; + var action = arguments.length <= 1 || arguments[1] === undefined ? _Actions.POP : arguments[1]; + var key = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; + + var _fourthArg = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; + + if (typeof location === 'string') location = _PathUtils.parsePath(location); + + if (typeof action === 'object') { + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'The state (2nd) argument to createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; + + location = _extends({}, location, { state: action }); + + action = key || _Actions.POP; + key = _fourthArg; } - return window.history && 'pushState' in window.history; + + var pathname = location.pathname || '/'; + var search = location.search || ''; + var hash = location.hash || ''; + var state = location.state || null; + + return { + pathname: pathname, + search: search, + hash: hash, + state: state, + action: action, + key: key + }; } -module.exports = supportsHistory; -},{}],36:[function(require,module,exports){ +exports['default'] = createLocation; +module.exports = exports['default']; +}).call(this,require('_process')) + +},{"./Actions":37,"./PathUtils":42,"_process":1,"warning":59}],48:[function(require,module,exports){ +(function (process){ 'use strict'; -function ToObject(val) { - if (val == null) { - throw new TypeError('Object.assign cannot be called with null or undefined'); - } +exports.__esModule = true; - return Object(val); -} +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; }; -module.exports = Object.assign || function (target, source) { - var from; - var keys; - var to = ToObject(target); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - for (var s = 1; s < arguments.length; s++) { - from = arguments[s]; - keys = Object.keys(Object(from)); +var _warning = require('warning'); - for (var i = 0; i < keys.length; i++) { - to[keys[i]] = from[keys[i]]; - } - } +var _warning2 = _interopRequireDefault(_warning); - return to; -}; +var _invariant = require('invariant'); -},{}],37:[function(require,module,exports){ -module.exports = require('./lib/'); +var _invariant2 = _interopRequireDefault(_invariant); -},{"./lib/":38}],38:[function(require,module,exports){ -// Load modules +var _PathUtils = require('./PathUtils'); -var Stringify = require('./stringify'); -var Parse = require('./parse'); +var _Actions = require('./Actions'); +var _createHistory = require('./createHistory'); -// Declare internals +var _createHistory2 = _interopRequireDefault(_createHistory); -var internals = {}; +function createStateStorage(entries) { + return entries.filter(function (entry) { + return entry.state; + }).reduce(function (memo, entry) { + memo[entry.key] = entry.state; + return memo; + }, {}); +} +function createMemoryHistory() { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; -module.exports = { - stringify: Stringify, - parse: Parse -}; + if (Array.isArray(options)) { + options = { entries: options }; + } else if (typeof options === 'string') { + options = { entries: [options] }; + } + + var history = _createHistory2['default'](_extends({}, options, { + getCurrentLocation: getCurrentLocation, + finishTransition: finishTransition, + saveState: saveState, + go: go + })); -},{"./parse":39,"./stringify":40}],39:[function(require,module,exports){ -// Load modules + var _options = options; + var entries = _options.entries; + var current = _options.current; -var Utils = require('./utils'); + if (typeof entries === 'string') { + entries = [entries]; + } else if (!Array.isArray(entries)) { + entries = ['/']; + } + entries = entries.map(function (entry) { + var key = history.createKey(); -// Declare internals + if (typeof entry === 'string') return { pathname: entry, key: key }; -var internals = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000 -}; + if (typeof entry === 'object' && entry) return _extends({}, entry, { key: key }); + !false ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Unable to create history entry from %s', entry) : _invariant2['default'](false) : undefined; + }); -internals.parseValues = function (str, options) { + if (current == null) { + current = entries.length - 1; + } else { + !(current >= 0 && current < entries.length) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Current index must be >= 0 and < %s, was %s', entries.length, current) : _invariant2['default'](false) : undefined; + } - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + var storage = createStateStorage(entries); - for (var i = 0, il = parts.length; i < il; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + function saveState(key, state) { + storage[key] = state; + } - if (pos === -1) { - obj[Utils.decode(part)] = ''; - } - else { - var key = Utils.decode(part.slice(0, pos)); - var val = Utils.decode(part.slice(pos + 1)); + function readState(key) { + return storage[key]; + } - if (Object.prototype.hasOwnProperty(key)) { - continue; - } + function getCurrentLocation() { + var entry = entries[current]; + var key = entry.key; + var basename = entry.basename; + var pathname = entry.pathname; + var search = entry.search; - if (!obj.hasOwnProperty(key)) { - obj[key] = val; - } - else { - obj[key] = [].concat(obj[key]).concat(val); - } - } + var path = (basename || '') + pathname + (search || ''); + + var state = undefined; + if (key) { + state = readState(key); + } else { + state = null; + key = history.createKey(); + entry.key = key; } - return obj; -}; + var location = _PathUtils.parsePath(path); + return history.createLocation(_extends({}, location, { state: state }), undefined, key); + } -internals.parseObject = function (chain, val, options) { + function canGo(n) { + var index = current + n; + return index >= 0 && index < entries.length; + } - if (!chain.length) { - return val; - } + function go(n) { + if (n) { + if (!canGo(n)) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'Cannot go(%s) there is not enough history', n) : undefined; + return; + } + + current += n; - var root = chain.shift(); + var currentLocation = getCurrentLocation(); - var obj = {}; - if (root === '[]') { - obj = []; - obj = obj.concat(internals.parseObject(chain, val, options)); + // change action to POP + history.transitionTo(_extends({}, currentLocation, { action: _Actions.POP })); } - else { - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; - var index = parseInt(cleanRoot, 10); - var indexString = '' + index; - if (!isNaN(index) && - root !== cleanRoot && - indexString === cleanRoot && - index >= 0 && - index <= options.arrayLimit) { + } - obj = []; - obj[index] = internals.parseObject(chain, val, options); - } - else { - obj[cleanRoot] = internals.parseObject(chain, val, options); - } + function finishTransition(location) { + switch (location.action) { + case _Actions.PUSH: + current += 1; + + // if we are not on the top of stack + // remove rest and push new + if (current < entries.length) entries.splice(current); + + entries.push(location); + saveState(location.key, location.state); + break; + case _Actions.REPLACE: + entries[current] = location; + saveState(location.key, location.state); + break; } + } - return obj; -}; + return history; +} +exports['default'] = createMemoryHistory; +module.exports = exports['default']; +}).call(this,require('_process')) -internals.parseKeys = function (key, val, options) { +},{"./Actions":37,"./PathUtils":42,"./createHistory":46,"_process":1,"invariant":58,"warning":59}],49:[function(require,module,exports){ +(function (process){ +'use strict'; - if (!key) { - return; - } +exports.__esModule = true; - // The regex chunks +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; +var _warning = require('warning'); - // Get the parent +var _warning2 = _interopRequireDefault(_warning); - var segment = parent.exec(key); +function deprecate(fn, message) { + return function () { + process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] ' + message) : undefined; + return fn.apply(this, arguments); + }; +} - // Don't allow them to overwrite object prototype properties +exports['default'] = deprecate; +module.exports = exports['default']; +}).call(this,require('_process')) - if (Object.prototype.hasOwnProperty(segment[1])) { - return; - } +},{"_process":1,"warning":59}],50:[function(require,module,exports){ +(function (process){ +'use strict'; - // Stash the parent if it exists +exports.__esModule = true; - var keys = []; - if (segment[1]) { - keys.push(segment[1]); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - // Loop through children appending to the array until we hit depth +var _warning = require('warning'); - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { +var _warning2 = _interopRequireDefault(_warning); - ++i; - if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - keys.push(segment[1]); - } - } +function runTransitionHook(hook, location, callback) { + var result = hook(location, callback); - // If there's a remainder, just add whatever is left + if (hook.length < 2) { + // Assume the hook runs synchronously and automatically + // call the callback with the return value. + callback(result); + } else { + process.env.NODE_ENV !== 'production' ? _warning2['default'](result === undefined, 'You should not "return" in a transition hook with a callback argument; call the callback instead') : undefined; + } +} - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } +exports['default'] = runTransitionHook; +module.exports = exports['default']; +}).call(this,require('_process')) - return internals.parseObject(keys, val, options); -}; +},{"_process":1,"warning":59}],51:[function(require,module,exports){ +'use strict'; +exports.__esModule = true; -module.exports = function (str, options) { +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; }; - if (str === '' || - str === null || - typeof str === 'undefined') { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - return {}; - } +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - options = options || {}; - options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; +var _ExecutionEnvironment = require('./ExecutionEnvironment'); - var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; - var obj = {}; +var _PathUtils = require('./PathUtils'); - // Iterate over the keys and setup the new object +var _runTransitionHook = require('./runTransitionHook'); - var keys = Object.keys(tempObj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - var newObj = internals.parseKeys(key, tempObj[key], options); - obj = Utils.merge(obj, newObj); - } +var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - return Utils.compact(obj); -}; +var _deprecate = require('./deprecate'); + +var _deprecate2 = _interopRequireDefault(_deprecate); + +function useBasename(createHistory) { + return function () { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + var basename = options.basename; -},{"./utils":41}],40:[function(require,module,exports){ -// Load modules + var historyOptions = _objectWithoutProperties(options, ['basename']); -var Utils = require('./utils'); + var history = createHistory(historyOptions); + // Automatically use the value of <base href> in HTML + // documents as basename if it's not explicitly given. + if (basename == null && _ExecutionEnvironment.canUseDOM) { + var base = document.getElementsByTagName('base')[0]; -// Declare internals + if (base) basename = _PathUtils.extractPath(base.href); + } + + function addBasename(location) { + if (basename && location.basename == null) { + if (location.pathname.indexOf(basename) === 0) { + location.pathname = location.pathname.substring(basename.length); + location.basename = basename; -var internals = { - delimiter: '&', - arrayPrefixGenerators: { - brackets: function (prefix, key) { - return prefix + '[]'; - }, - indices: function (prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function (prefix, key) { - return prefix; + if (location.pathname === '') location.pathname = '/'; + } else { + location.basename = ''; } + } + + return location; + } + + function prependBasename(location) { + if (!basename) return location; + + if (typeof location === 'string') location = _PathUtils.parsePath(location); + + var pname = location.pathname; + var normalizedBasename = basename.slice(-1) === '/' ? basename : basename + '/'; + var normalizedPathname = pname.charAt(0) === '/' ? pname.slice(1) : pname; + var pathname = normalizedBasename + normalizedPathname; + + return _extends({}, location, { + pathname: pathname + }); + } + + // Override all read methods with basename-aware versions. + function listenBefore(hook) { + return history.listenBefore(function (location, callback) { + _runTransitionHook2['default'](hook, addBasename(location), callback); + }); } -}; + function listen(listener) { + return history.listen(function (location) { + listener(addBasename(location)); + }); + } -internals.stringify = function (obj, prefix, generateArrayPrefix) { + // Override all write methods with basename-aware versions. + function push(location) { + history.push(prependBasename(location)); + } - if (Utils.isBuffer(obj)) { - obj = obj.toString(); + function replace(location) { + history.replace(prependBasename(location)); } - else if (obj instanceof Date) { - obj = obj.toISOString(); + + function createPath(location) { + return history.createPath(prependBasename(location)); } - else if (obj === null) { - obj = ''; + + function createHref(location) { + return history.createHref(prependBasename(location)); } - if (typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean') { + function createLocation(location) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; + return addBasename(history.createLocation.apply(history, [prependBasename(location)].concat(args))); } - var values = []; + // deprecated + function pushState(state, path) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); - if (typeof obj === 'undefined') { - return values; + push(_extends({ state: state }, path)); } - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - if (Array.isArray(obj)) { - values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix)); - } - else { - values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix)); - } + // deprecated + function replaceState(state, path) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); + + replace(_extends({ state: state }, path)); } - return values; -}; + return _extends({}, history, { + listenBefore: listenBefore, + listen: listen, + push: push, + replace: replace, + createPath: createPath, + createHref: createHref, + createLocation: createLocation, + pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), + replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') + }); + }; +} -module.exports = function (obj, options) { +exports['default'] = useBasename; +module.exports = exports['default']; +},{"./ExecutionEnvironment":41,"./PathUtils":42,"./deprecate":49,"./runTransitionHook":50}],52:[function(require,module,exports){ +(function (process){ +'use strict'; - options = options || {}; - var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; +exports.__esModule = true; - var keys = []; +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; }; - if (typeof obj !== 'object' || - obj === null) { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - return ''; - } +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - var arrayFormat; - if (options.arrayFormat in internals.arrayPrefixGenerators) { - arrayFormat = options.arrayFormat; - } - else if ('indices' in options) { - arrayFormat = options.indices ? 'indices' : 'repeat'; - } - else { - arrayFormat = 'indices'; - } +var _warning = require('warning'); + +var _warning2 = _interopRequireDefault(_warning); + +var _queryString = require('query-string'); - var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat]; +var _runTransitionHook = require('./runTransitionHook'); - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix)); +var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); + +var _PathUtils = require('./PathUtils'); + +var _deprecate = require('./deprecate'); + +var _deprecate2 = _interopRequireDefault(_deprecate); + +var SEARCH_BASE_KEY = '$searchBase'; + +function defaultStringifyQuery(query) { + return _queryString.stringify(query).replace(/%20/g, '+'); +} + +var defaultParseQueryString = _queryString.parse; + +function isNestedObject(object) { + for (var p in object) { + if (object.hasOwnProperty(p) && typeof object[p] === 'object' && !Array.isArray(object[p]) && object[p] !== null) return true; + }return false; +} + +/** + * Returns a new createHistory function that may be used to create + * history objects that know how to handle URL queries. + */ +function useQueries(createHistory) { + return function () { + var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + var stringifyQuery = options.stringifyQuery; + var parseQueryString = options.parseQueryString; + + var historyOptions = _objectWithoutProperties(options, ['stringifyQuery', 'parseQueryString']); + + var history = createHistory(historyOptions); + + if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; + + if (typeof parseQueryString !== 'function') parseQueryString = defaultParseQueryString; + + function addQuery(location) { + if (location.query == null) { + var search = location.search; + + location.query = parseQueryString(search.substring(1)); + location[SEARCH_BASE_KEY] = { search: search, searchBase: '' }; + } + + // TODO: Instead of all the book-keeping here, this should just strip the + // stringified query from the search. + + return location; } - return keys.join(delimiter); -}; + function appendQuery(location, query) { + var _extends2; -},{"./utils":41}],41:[function(require,module,exports){ -// Load modules + var searchBaseSpec = location[SEARCH_BASE_KEY]; + var queryString = query ? stringifyQuery(query) : ''; + if (!searchBaseSpec && !queryString) { + return location; + } + process.env.NODE_ENV !== 'production' ? _warning2['default'](stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), 'useQueries does not stringify nested query objects by default; ' + 'use a custom stringifyQuery function') : undefined; -// Declare internals + if (typeof location === 'string') location = _PathUtils.parsePath(location); -var internals = {}; + var searchBase = undefined; + if (searchBaseSpec && location.search === searchBaseSpec.search) { + searchBase = searchBaseSpec.searchBase; + } else { + searchBase = location.search || ''; + } + var search = searchBase; + if (queryString) { + search += (search ? '&' : '?') + queryString; + } -exports.arrayToObject = function (source) { + return _extends({}, location, (_extends2 = { + search: search + }, _extends2[SEARCH_BASE_KEY] = { search: search, searchBase: searchBase }, _extends2)); + } - var obj = {}; - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { + // Override all read methods with query-aware versions. + function listenBefore(hook) { + return history.listenBefore(function (location, callback) { + _runTransitionHook2['default'](hook, addQuery(location), callback); + }); + } - obj[i] = source[i]; - } + function listen(listener) { + return history.listen(function (location) { + listener(addQuery(location)); + }); } - return obj; -}; + // Override all write methods with query-aware versions. + function push(location) { + history.push(appendQuery(location, location.query)); + } + function replace(location) { + history.replace(appendQuery(location, location.query)); + } -exports.merge = function (target, source) { + function createPath(location, query) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](!query, 'the query argument to createPath is deprecated; use a location descriptor instead') : undefined; - if (!source) { - return target; + return history.createPath(appendQuery(location, query || location.query)); } - if (typeof source !== 'object') { - if (Array.isArray(target)) { - target.push(source); - } - else { - target[source] = true; - } + function createHref(location, query) { + process.env.NODE_ENV !== 'production' ? _warning2['default'](!query, 'the query argument to createHref is deprecated; use a location descriptor instead') : undefined; - return target; + return history.createHref(appendQuery(location, query || location.query)); } - if (typeof target !== 'object') { - target = [target].concat(source); - return target; + function createLocation(location) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var fullLocation = history.createLocation.apply(history, [appendQuery(location, location.query)].concat(args)); + if (location.query) { + fullLocation.query = location.query; + } + return addQuery(fullLocation); } - if (Array.isArray(target) && - !Array.isArray(source)) { + // deprecated + function pushState(state, path, query) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); - target = exports.arrayToObject(target); + push(_extends({ state: state }, path, { query: query })); } - var keys = Object.keys(source); - for (var k = 0, kl = keys.length; k < kl; ++k) { - var key = keys[k]; - var value = source[key]; + // deprecated + function replaceState(state, path, query) { + if (typeof path === 'string') path = _PathUtils.parsePath(path); - if (!target[key]) { - target[key] = value; - } - else { - target[key] = exports.merge(target[key], value); - } + replace(_extends({ state: state }, path, { query: query })); } - return target; -}; + return _extends({}, history, { + listenBefore: listenBefore, + listen: listen, + push: push, + replace: replace, + createPath: createPath, + createHref: createHref, + createLocation: createLocation, + pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), + replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') + }); + }; +} + +exports['default'] = useQueries; +module.exports = exports['default']; +}).call(this,require('_process')) -exports.decode = function (str) { +},{"./PathUtils":42,"./deprecate":49,"./runTransitionHook":50,"_process":1,"query-string":56,"warning":59}],53:[function(require,module,exports){ +var pSlice = Array.prototype.slice; +var objectKeys = require('./lib/keys.js'); +var isArguments = require('./lib/is_arguments.js'); - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; +var deepEqual = module.exports = function (actual, expected, opts) { + if (!opts) opts = {}; + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { + return opts.strict ? actual === expected : actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected, opts); + } +} + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isBuffer (x) { + if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; + if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { + return false; + } + if (x.length > 0 && typeof x[0] !== 'number') return false; + return true; +} + +function objEquiv(a, b, opts) { + var i, key; + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return deepEqual(a, b, opts); + } + if (isBuffer(a)) { + if (!isBuffer(b)) { + return false; } + if (a.length !== b.length) return false; + for (i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; + } + try { + var ka = objectKeys(a), + kb = objectKeys(b); + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!deepEqual(a[key], b[key], opts)) return false; + } + return typeof a === typeof b; +} + +},{"./lib/is_arguments.js":54,"./lib/keys.js":55}],54:[function(require,module,exports){ +var supportsArgumentsClass = (function(){ + return Object.prototype.toString.call(arguments) +})() == '[object Arguments]'; + +exports = module.exports = supportsArgumentsClass ? supported : unsupported; + +exports.supported = supported; +function supported(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; }; +exports.unsupported = unsupported; +function unsupported(object){ + return object && + typeof object == 'object' && + typeof object.length == 'number' && + Object.prototype.hasOwnProperty.call(object, 'callee') && + !Object.prototype.propertyIsEnumerable.call(object, 'callee') || + false; +}; -exports.compact = function (obj, refs) { +},{}],55:[function(require,module,exports){ +exports = module.exports = typeof Object.keys === 'function' + ? Object.keys : shim; - if (typeof obj !== 'object' || - obj === null) { +exports.shim = shim; +function shim (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} - return obj; - } +},{}],56:[function(require,module,exports){ +'use strict'; +var strictUriEncode = require('strict-uri-encode'); - refs = refs || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; - } +exports.extract = function (str) { + return str.split('?')[1] || ''; +}; - refs.push(obj); +exports.parse = function (str) { + if (typeof str !== 'string') { + return {}; + } - if (Array.isArray(obj)) { - var compacted = []; + str = str.trim().replace(/^(\?|#|&)/, ''); - for (var i = 0, il = obj.length; i < il; ++i) { - if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } + if (!str) { + return {}; + } - return compacted; - } + return str.split('&').reduce(function (ret, param) { + var parts = param.replace(/\+/g, ' ').split('='); + // Firefox (pre 40) decodes `%3D` to `=` + // https://github.com/sindresorhus/query-string/pull/37 + var key = parts.shift(); + var val = parts.length > 0 ? parts.join('=') : undefined; - var keys = Object.keys(obj); - for (i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - obj[key] = exports.compact(obj[key], refs); - } + key = decodeURIComponent(key); + + // missing `=` should be `null`: + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + val = val === undefined ? null : decodeURIComponent(val); + + if (!ret.hasOwnProperty(key)) { + ret[key] = val; + } else if (Array.isArray(ret[key])) { + ret[key].push(val); + } else { + ret[key] = [ret[key], val]; + } - return obj; + return ret; + }, {}); }; +exports.stringify = function (obj) { + return obj ? Object.keys(obj).sort().map(function (key) { + var val = obj[key]; -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; + if (val === undefined) { + return ''; + } + + if (val === null) { + return key; + } + + if (Array.isArray(val)) { + return val.slice().sort().map(function (val2) { + return strictUriEncode(key) + '=' + strictUriEncode(val2); + }).join('&'); + } + + return strictUriEncode(key) + '=' + strictUriEncode(val); + }).filter(function (x) { + return x.length > 0; + }).join('&') : ''; }; +},{"strict-uri-encode":57}],57:[function(require,module,exports){ +'use strict'; +module.exports = function (str) { + return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase(); + }); +}; -exports.isBuffer = function (obj) { +},{}],58:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ - if (obj === null || - typeof obj === 'undefined') { +'use strict'; - return false; +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var invariant = function(condition, format, a, b, c, d, e, f) { + if (process.env.NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; } - return !!(obj.constructor && - obj.constructor.isBuffer && - obj.constructor.isBuffer(obj)); + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } }; -},{}],42:[function(require,module,exports){ +module.exports = invariant; + +}).call(this,require('_process')) + +},{"_process":1}],59:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +/** + * 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 = function() {}; + +if (process.env.NODE_ENV !== 'production') { + warning = function(condition, format, args) { + var len = arguments.length; + args = new Array(len > 2 ? len - 2 : 0); + for (var key = 2; key < len; key++) { + args[key - 2] = arguments[key]; + } + 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 (!condition) { + var argIndex = 0; + var message = 'Warning: ' + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch(x) {} + } + }; +} + +module.exports = warning; + +}).call(this,require('_process')) + +},{"_process":1}],60:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -3313,25 +5116,35 @@ exports.isBuffer = function (obj) { * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule AutoFocusMixin + * @providesModule AutoFocusUtils * @typechecks static-only */ 'use strict'; -var focusNode = require("./focusNode"); +var ReactMount = require('./ReactMount'); + +var findDOMNode = require('./findDOMNode'); +var focusNode = require('fbjs/lib/focusNode'); -var AutoFocusMixin = { - componentDidMount: function() { +var Mixin = { + componentDidMount: function () { if (this.props.autoFocus) { - focusNode(this.getDOMNode()); + focusNode(findDOMNode(this)); } } }; -module.exports = AutoFocusMixin; +var AutoFocusUtils = { + Mixin: Mixin, + + focusDOMComponent: function () { + focusNode(ReactMount.getNode(this._rootNodeID)); + } +}; -},{"./focusNode":175}],43:[function(require,module,exports){ +module.exports = AutoFocusUtils; +},{"./ReactMount":130,"./findDOMNode":181,"fbjs/lib/focusNode":214}],61:[function(require,module,exports){ /** * Copyright 2013-2015 Facebook, Inc. * All rights reserved. @@ -3346,22 +5159,19 @@ module.exports = AutoFocusMixin; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var FallbackCompositionState = require("./FallbackCompositionState"); -var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); -var SyntheticInputEvent = require("./SyntheticInputEvent"); +var EventConstants = require('./EventConstants'); +var EventPropagators = require('./EventPropagators'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var FallbackCompositionState = require('./FallbackCompositionState'); +var SyntheticCompositionEvent = require('./SyntheticCompositionEvent'); +var SyntheticInputEvent = require('./SyntheticInputEvent'); -var keyOf = require("./keyOf"); +var keyOf = require('fbjs/lib/keyOf'); var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229; -var canUseCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); +var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; var documentMode = null; if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { @@ -3371,22 +5181,12 @@ if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { // Webkit offers a very useful `textInput` event that can be used to // directly represent `beforeInput`. The IE `textinput` event is not as // useful, so we don't use it. -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !documentMode && - !isPresto() -); +var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); // In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. Japanese ideographic // spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ( - ExecutionEnvironment.canUseDOM && - ( - (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) - ) -); +var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); /** * Opera <= 12 includes TextEvent in window, but does not fire @@ -3394,11 +5194,7 @@ var useFallbackCompositionData = ( */ function isPresto() { var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); + return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; } var SPACEBAR_CODE = 32; @@ -3410,57 +5206,31 @@ var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { beforeInput: { phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) + bubbled: keyOf({ onBeforeInput: null }), + captured: keyOf({ onBeforeInputCapture: null }) }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] + dependencies: [topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste] }, compositionEnd: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) + bubbled: keyOf({ onCompositionEnd: null }), + captured: keyOf({ onCompositionEndCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] }, compositionStart: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) + bubbled: keyOf({ onCompositionStart: null }), + captured: keyOf({ onCompositionStartCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] }, compositionUpdate: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) + bubbled: keyOf({ onCompositionUpdate: null }), + captured: keyOf({ onCompositionUpdateCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] } }; @@ -3473,14 +5243,11 @@ var hasSpaceKeypress = false; * (cut, copy, select-all, etc.) even though no character is inserted. */ function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); + return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && + // ctrlKey && altKey is equivalent to AltGr, and is not a command. + !(nativeEvent.ctrlKey && nativeEvent.altKey); } - /** * Translate native top level events into event types. * @@ -3507,10 +5274,7 @@ function getCompositionEventType(topLevelType) { * @return {boolean} */ function isFallbackCompositionStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); + return topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE; } /** @@ -3524,11 +5288,11 @@ function isFallbackCompositionEnd(topLevelType, nativeEvent) { switch (topLevelType) { case topLevelTypes.topKeyUp: // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); + return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; case topLevelTypes.topKeyDown: // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); + return nativeEvent.keyCode !== START_KEYCODE; case topLevelTypes.topKeyPress: case topLevelTypes.topMouseDown: case topLevelTypes.topBlur: @@ -3566,12 +5330,7 @@ var currentComposition = null; * @param {object} nativeEvent Native browser event. * @return {?object} A SyntheticCompositionEvent. */ -function extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { +function extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var eventType; var fallbackData; @@ -3601,11 +5360,7 @@ function extractCompositionEvent( } } - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); + var event = SyntheticCompositionEvent.getPooled(eventType, topLevelTargetID, nativeEvent, nativeEventTarget); if (fallbackData) { // Inject data generated from fallback path into the synthetic event. @@ -3685,10 +5440,7 @@ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { // If we are currently composing (IME) and using a fallback to do so, // try to extract the composed characters from the fallback object. if (currentComposition) { - if ( - topLevelType === topLevelTypes.topCompositionEnd || - isFallbackCompositionEnd(topLevelType, nativeEvent) - ) { + if (topLevelType === topLevelTypes.topCompositionEnd || isFallbackCompositionEnd(topLevelType, nativeEvent)) { var chars = currentComposition.getData(); FallbackCompositionState.release(currentComposition); currentComposition = null; @@ -3740,12 +5492,7 @@ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { * @param {object} nativeEvent Native browser event. * @return {?object} A SyntheticInputEvent. */ -function extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { +function extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var chars; if (canUseTextInputEvent) { @@ -3760,11 +5507,7 @@ function extractBeforeInputEvent( return null; } - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); + var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, topLevelTargetID, nativeEvent, nativeEventTarget); event.data = chars; EventPropagators.accumulateTwoPhaseDispatches(event); @@ -3801,145 +5544,13 @@ var BeforeInputEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) { - return [ - extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ), - extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) - ]; + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + return [extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget)]; } }; module.exports = BeforeInputEventPlugin; - -},{"./EventConstants":56,"./EventPropagators":61,"./ExecutionEnvironment":62,"./FallbackCompositionState":63,"./SyntheticCompositionEvent":147,"./SyntheticInputEvent":151,"./keyOf":198}],44:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSCore - * @typechecks - */ - -var invariant = require("./invariant"); - -/** - * The CSSCore module specifies the API (and implements most of the methods) - * that should be used when dealing with the display of elements (via their - * CSS classes and visibility on screen. It is an API focused on mutating the - * display and not reading it as no logical state should be encoded in the - * display of elements. - */ - -var CSSCore = { - - /** - * Adds the class passed in to the element if it doesn't already have it. - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @return {DOMElement} the element passed in - */ - addClass: function(element, className) { - ("production" !== process.env.NODE_ENV ? invariant( - !/\s/.test(className), - 'CSSCore.addClass takes only a single class name. "%s" contains ' + - 'multiple classes.', className - ) : invariant(!/\s/.test(className))); - - if (className) { - if (element.classList) { - element.classList.add(className); - } else if (!CSSCore.hasClass(element, className)) { - element.className = element.className + ' ' + className; - } - } - return element; - }, - - /** - * Removes the class passed in from the element - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @return {DOMElement} the element passed in - */ - removeClass: function(element, className) { - ("production" !== process.env.NODE_ENV ? invariant( - !/\s/.test(className), - 'CSSCore.removeClass takes only a single class name. "%s" contains ' + - 'multiple classes.', className - ) : invariant(!/\s/.test(className))); - - if (className) { - if (element.classList) { - element.classList.remove(className); - } else if (CSSCore.hasClass(element, className)) { - element.className = element.className - .replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1') - .replace(/\s+/g, ' ') // multiple spaces to one - .replace(/^\s*|\s*$/g, ''); // trim the ends - } - } - return element; - }, - - /** - * Helper to add or remove a class from an element based on a condition. - * - * @param {DOMElement} element the element to set the class on - * @param {string} className the CSS className - * @param {*} bool condition to whether to add or remove the class - * @return {DOMElement} the element passed in - */ - conditionClass: function(element, className, bool) { - return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); - }, - - /** - * Tests whether the element has the class specified. - * - * @param {DOMNode|DOMWindow} element the element to set the class on - * @param {string} className the CSS className - * @return {boolean} true if the element has the class, false if not - */ - hasClass: function(element, className) { - ("production" !== process.env.NODE_ENV ? invariant( - !/\s/.test(className), - 'CSS.hasClass takes only a single class name.' - ) : invariant(!/\s/.test(className))); - if (element.classList) { - return !!className && element.classList.contains(className); - } - return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; - } - -}; - -module.exports = CSSCore; - -}).call(this,require('_process')) - -},{"./invariant":191,"_process":1}],45:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPropagators":77,"./FallbackCompositionState":78,"./SyntheticCompositionEvent":162,"./SyntheticInputEvent":166,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/keyOf":225}],62:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -3957,26 +5568,31 @@ module.exports = CSSCore; * CSS properties which accept numbers but are not in units of "px". */ var isUnitlessNumber = { + animationIterationCount: true, boxFlex: true, boxFlexGroup: true, + boxOrdinalGroup: true, columnCount: true, flex: true, flexGrow: true, flexPositive: true, flexShrink: true, flexNegative: true, + flexOrder: 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, + stopOpacity: true, strokeDashoffset: true, strokeOpacity: true, strokeWidth: true @@ -4000,8 +5616,8 @@ var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an // infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { +Object.keys(isUnitlessNumber).forEach(function (prop) { + prefixes.forEach(function (prefix) { isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; }); }); @@ -4017,10 +5633,16 @@ Object.keys(isUnitlessNumber).forEach(function(prop) { */ var shorthandPropertyExpansions = { background: { + backgroundAttachment: true, + backgroundColor: true, backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true + backgroundPositionX: true, + backgroundPositionY: true, + backgroundRepeat: true + }, + backgroundPosition: { + backgroundPositionX: true, + backgroundPositionY: true }, border: { borderWidth: true, @@ -4054,6 +5676,11 @@ var shorthandPropertyExpansions = { fontSize: true, lineHeight: true, fontFamily: true + }, + outline: { + outlineWidth: true, + outlineStyle: true, + outlineColor: true } }; @@ -4063,8 +5690,7 @@ var CSSProperty = { }; module.exports = CSSProperty; - -},{}],46:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -4080,28 +5706,37 @@ module.exports = CSSProperty; 'use strict'; -var CSSProperty = require("./CSSProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var CSSProperty = require('./CSSProperty'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var ReactPerf = require('./ReactPerf'); -var camelizeStyleName = require("./camelizeStyleName"); -var dangerousStyleValue = require("./dangerousStyleValue"); -var hyphenateStyleName = require("./hyphenateStyleName"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); +var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); +var dangerousStyleValue = require('./dangerousStyleValue'); +var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName'); +var memoizeStringOnly = require('fbjs/lib/memoizeStringOnly'); +var warning = require('fbjs/lib/warning'); -var processStyleName = memoizeStringOnly(function(styleName) { +var processStyleName = memoizeStringOnly(function (styleName) { return hyphenateStyleName(styleName); }); +var hasShorthandPropertyBug = false; var styleFloatAccessor = 'cssFloat'; if (ExecutionEnvironment.canUseDOM) { + var tempStyle = document.createElement('div').style; + try { + // IE8 throws "Invalid argument." if resetting shorthand style properties. + tempStyle.font = ''; + } catch (e) { + hasShorthandPropertyBug = true; + } // IE8 only supports accessing cssFloat (standard) as styleFloat if (document.documentElement.style.cssFloat === undefined) { styleFloatAccessor = 'styleFloat'; } } -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { // 'msTransform' is correct, but the other prefixes should be capitalized var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; @@ -4111,54 +5746,38 @@ if ("production" !== process.env.NODE_ENV) { var warnedStyleNames = {}; var warnedStyleValues = {}; - var warnHyphenatedStyleName = function(name) { + var warnHyphenatedStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?', name, camelizeStyleName(name)) : undefined; }; - var warnBadVendoredStyleName = function(name) { + var warnBadVendoredStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)) : undefined; }; - var warnStyleValueWithSemicolon = function(name, value) { + var warnStyleValueWithSemicolon = function (name, value) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { return; } warnedStyleValues[value] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon. ' + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')) : undefined; }; /** * @param {string} name * @param {*} value */ - var warnValidStyle = function(name, value) { + var warnValidStyle = function (name, value) { if (name.indexOf('-') > -1) { warnHyphenatedStyleName(name); } else if (badVendoredStyleNamePattern.test(name)) { @@ -4186,14 +5805,14 @@ var CSSPropertyOperations = { * @param {object} styles * @return {?string} */ - createMarkupForStyles: function(styles) { + createMarkupForStyles: function (styles) { var serialized = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var styleValue = styles[styleName]; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { warnValidStyle(styleName, styleValue); } if (styleValue != null) { @@ -4211,13 +5830,13 @@ var CSSPropertyOperations = { * @param {DOMElement} node * @param {object} styles */ - setValueForStyles: function(node, styles) { + setValueForStyles: function (node, styles) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { warnValidStyle(styleName, styles[styleName]); } var styleValue = dangerousStyleValue(styleName, styles[styleName]); @@ -4227,7 +5846,7 @@ var CSSPropertyOperations = { if (styleValue) { style[styleName] = styleValue; } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; + var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName]; if (expansion) { // Shorthand property that IE8 won't like unsetting, so unset each // component to placate it @@ -4243,11 +5862,14 @@ var CSSPropertyOperations = { }; -module.exports = CSSPropertyOperations; +ReactPerf.measureMethods(CSSPropertyOperations, 'CSSPropertyOperations', { + setValueForStyles: 'setValueForStyles' +}); +module.exports = CSSPropertyOperations; }).call(this,require('_process')) -},{"./CSSProperty":45,"./ExecutionEnvironment":62,"./camelizeStyleName":162,"./dangerousStyleValue":169,"./hyphenateStyleName":189,"./memoizeStringOnly":200,"./warning":212,"_process":1}],47:[function(require,module,exports){ +},{"./CSSProperty":62,"./ReactPerf":136,"./dangerousStyleValue":178,"_process":1,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/camelizeStyleName":208,"fbjs/lib/hyphenateStyleName":219,"fbjs/lib/memoizeStringOnly":227,"fbjs/lib/warning":232}],64:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -4262,10 +5884,10 @@ module.exports = CSSPropertyOperations; 'use strict'; -var PooledClass = require("./PooledClass"); +var PooledClass = require('./PooledClass'); -var assign = require("./Object.assign"); -var invariant = require("./invariant"); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); /** * A specialized pseudo-event module to help keep track of components waiting to @@ -4292,7 +5914,7 @@ assign(CallbackQueue.prototype, { * @param {?object} context Context to call `callback` with. * @internal */ - enqueue: function(callback, context) { + enqueue: function (callback, context) { this._callbacks = this._callbacks || []; this._contexts = this._contexts || []; this._callbacks.push(callback); @@ -4305,17 +5927,14 @@ assign(CallbackQueue.prototype, { * * @internal */ - notifyAll: function() { + notifyAll: function () { var callbacks = this._callbacks; var contexts = this._contexts; if (callbacks) { - ("production" !== process.env.NODE_ENV ? invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ) : invariant(callbacks.length === contexts.length)); + !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : undefined; this._callbacks = null; this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { + for (var i = 0; i < callbacks.length; i++) { callbacks[i].call(contexts[i]); } callbacks.length = 0; @@ -4328,7 +5947,7 @@ assign(CallbackQueue.prototype, { * * @internal */ - reset: function() { + reset: function () { this._callbacks = null; this._contexts = null; }, @@ -4336,7 +5955,7 @@ assign(CallbackQueue.prototype, { /** * `PooledClass` looks for this. */ - destructor: function() { + destructor: function () { this.reset(); } @@ -4345,10 +5964,9 @@ assign(CallbackQueue.prototype, { PooledClass.addPoolingTo(CallbackQueue); module.exports = CallbackQueue; - }).call(this,require('_process')) -},{"./Object.assign":69,"./PooledClass":70,"./invariant":191,"_process":1}],48:[function(require,module,exports){ +},{"./Object.assign":82,"./PooledClass":83,"_process":1,"fbjs/lib/invariant":220}],65:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -4362,35 +5980,27 @@ module.exports = CallbackQueue; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); +var EventConstants = require('./EventConstants'); +var EventPluginHub = require('./EventPluginHub'); +var EventPropagators = require('./EventPropagators'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var ReactUpdates = require('./ReactUpdates'); +var SyntheticEvent = require('./SyntheticEvent'); -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); +var getEventTarget = require('./getEventTarget'); +var isEventSupported = require('./isEventSupported'); +var isTextInputElement = require('./isTextInputElement'); +var keyOf = require('fbjs/lib/keyOf'); var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { change: { phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) + bubbled: keyOf({ onChange: null }), + captured: keyOf({ onChangeCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange] } }; @@ -4406,26 +6016,18 @@ var activeElementValueProp = null; * SECTION: handle `change` event */ function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); + var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); + return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; } var doesChangeEventBubble = false; if (ExecutionEnvironment.canUseDOM) { // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - (!('documentMode' in document) || document.documentMode > 8) - ); + doesChangeEventBubble = isEventSupported('change') && (!('documentMode' in document) || document.documentMode > 8); } function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); + var event = SyntheticEvent.getPooled(eventTypes.change, activeElementID, nativeEvent, getEventTarget(nativeEvent)); EventPropagators.accumulateTwoPhaseDispatches(event); // If change and propertychange bubbled, we'd just bind to it like all the @@ -4444,7 +6046,7 @@ function manualDispatchChangeEvent(nativeEvent) { function runEventInBatch(event) { EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); + EventPluginHub.processEventQueue(false); } function startWatchingForChangeEventIE8(target, targetID) { @@ -4462,18 +6064,12 @@ function stopWatchingForChangeEventIE8() { activeElementID = null; } -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForChangeEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topChange) { return topLevelTargetID; } } -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. @@ -4484,7 +6080,6 @@ function handleEventsForChangeEventIE8( } } - /** * SECTION: handle `input` event */ @@ -4492,20 +6087,18 @@ var isInputEventSupported = false; if (ExecutionEnvironment.canUseDOM) { // IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - (!('documentMode' in document) || document.documentMode > 9) - ); + isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 9); } /** * (For old IE.) Replacement getter/setter for the `value` property that gets * set on the active element. */ -var newValueProp = { - get: function() { +var newValueProp = { + get: function () { return activeElementValueProp.get.call(this); }, - set: function(val) { + set: function (val) { // Cast to a string so we can do equality checks. activeElementValue = '' + val; activeElementValueProp.set.call(this, val); @@ -4521,11 +6114,10 @@ function startWatchingForValueChange(target, targetID) { activeElement = target; activeElementID = targetID; activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); + activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); + // Not guarded in a canDefineProperty check: IE8 supports defineProperty only + // on DOM elements Object.defineProperty(activeElement, 'value', newValueProp); activeElement.attachEvent('onpropertychange', handlePropertyChange); } @@ -4569,10 +6161,7 @@ function handlePropertyChange(nativeEvent) { /** * If a `change` event should be fired, returns the target's ID. */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForInputEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topInput) { // In modern browsers (i.e., not IE8 or IE9), the input event is exactly // what we want so fall through here and trigger an abstract event @@ -4581,10 +6170,7 @@ function getTargetIDForInputEvent( } // For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // In IE8, we can capture almost all .value changes by adding a // propertychange handler and looking for events with propertyName @@ -4607,13 +6193,8 @@ function handleEventsForInputEventIE( } // For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { +function getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { + if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // @@ -4631,7 +6212,6 @@ function getTargetIDForInputEventIE( } } - /** * SECTION: handle `click` event */ @@ -4639,16 +6219,10 @@ function shouldUseClickEvent(elem) { // Use the `click` event to detect changes to checkbox and radio inputs. // This approach works across all browsers, whereas `change` does not fire // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); + return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); } -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForClickEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topClick) { return topLevelTargetID; } @@ -4676,11 +6250,7 @@ var ChangeEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var getTargetIDFunc, handleEventFunc; if (shouldUseChangeEvent(topLevelTarget)) { @@ -4701,36 +6271,24 @@ var ChangeEventPlugin = { } if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); + var targetID = getTargetIDFunc(topLevelType, topLevelTarget, topLevelTargetID); if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); + var event = SyntheticEvent.getPooled(eventTypes.change, targetID, nativeEvent, nativeEventTarget); + event.type = 'change'; EventPropagators.accumulateTwoPhaseDispatches(event); return event; } } if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); + handleEventFunc(topLevelType, topLevelTarget, topLevelTargetID); } } }; module.exports = ChangeEventPlugin; - -},{"./EventConstants":56,"./EventPluginHub":58,"./EventPropagators":61,"./ExecutionEnvironment":62,"./ReactUpdates":140,"./SyntheticEvent":149,"./isEventSupported":192,"./isTextInputElement":194,"./keyOf":198}],49:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPluginHub":74,"./EventPropagators":77,"./ReactUpdates":154,"./SyntheticEvent":164,"./getEventTarget":187,"./isEventSupported":192,"./isTextInputElement":193,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/keyOf":225}],66:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -4748,14 +6306,13 @@ module.exports = ChangeEventPlugin; var nextReactRootIndex = 0; var ClientReactRootIndex = { - createReactRootIndex: function() { + createReactRootIndex: function () { return nextReactRootIndex++; } }; module.exports = ClientReactRootIndex; - -},{}],50:[function(require,module,exports){ +},{}],67:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -4771,11 +6328,13 @@ module.exports = ClientReactRootIndex; 'use strict'; -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); +var Danger = require('./Danger'); +var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes'); +var ReactPerf = require('./ReactPerf'); -var setTextContent = require("./setTextContent"); -var invariant = require("./invariant"); +var setInnerHTML = require('./setInnerHTML'); +var setTextContent = require('./setTextContent'); +var invariant = require('fbjs/lib/invariant'); /** * Inserts `childNode` as a child of `parentNode` at the `index`. @@ -4790,10 +6349,12 @@ function insertChildAt(parentNode, childNode, index) { // rely exclusively on `insertBefore(node, null)` instead of also using // `appendChild(node)`. However, using `undefined` is not allowed by all // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); + + // fix render order error in safari + // IE8 will throw error when index out of list size. + var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index); + + parentNode.insertBefore(childNode, beforeChild); } /** @@ -4813,7 +6374,7 @@ var DOMChildrenOperations = { * @param {array<string>} markupList List of markup strings. * @internal */ - processUpdates: function(updates, markupList) { + processUpdates: function (updates, markupList) { var update; // Mapping from parent IDs to initial child orderings. var initialChildren = null; @@ -4822,23 +6383,12 @@ var DOMChildrenOperations = { for (var i = 0; i < updates.length; i++) { update = updates[i]; - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { + if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { var updatedIndex = update.fromIndex; var updatedChild = update.parentNode.childNodes[updatedIndex]; var parentID = update.parentID; - ("production" !== process.env.NODE_ENV ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a <tbody> when using tables, ' + - 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + - 'in an <svg> parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); + !updatedChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a <tbody> when using tables, ' + 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + 'in an <svg> parent. Try inspecting the child nodes of the element ' + 'with React ID `%s`.', updatedIndex, parentID) : invariant(false) : undefined; initialChildren = initialChildren || {}; initialChildren[parentID] = initialChildren[parentID] || []; @@ -4849,7 +6399,13 @@ var DOMChildrenOperations = { } } - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + var renderedMarkup; + // markupList is either a list of markup or just a list of elements + if (markupList.length && typeof markupList[0] === 'string') { + renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + } else { + renderedMarkup = markupList; + } // Remove updated children first so that `toIndex` is consistent. if (updatedChildren) { @@ -4862,24 +6418,16 @@ var DOMChildrenOperations = { update = updates[k]; switch (update.type) { case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); + insertChildAt(update.parentNode, renderedMarkup[update.markupIndex], update.toIndex); break; case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); + insertChildAt(update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex); + break; + case ReactMultiChildUpdateTypes.SET_MARKUP: + setInnerHTML(update.parentNode, update.content); break; case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); + setTextContent(update.parentNode, update.content); break; case ReactMultiChildUpdateTypes.REMOVE_NODE: // Already removed by the for-loop above. @@ -4890,11 +6438,14 @@ var DOMChildrenOperations = { }; -module.exports = DOMChildrenOperations; +ReactPerf.measureMethods(DOMChildrenOperations, 'DOMChildrenOperations', { + updateTextContent: 'updateTextContent' +}); +module.exports = DOMChildrenOperations; }).call(this,require('_process')) -},{"./Danger":53,"./ReactMultiChildUpdateTypes":119,"./invariant":191,"./setTextContent":206,"_process":1}],51:[function(require,module,exports){ +},{"./Danger":70,"./ReactMultiChildUpdateTypes":132,"./ReactPerf":136,"./setInnerHTML":197,"./setTextContent":198,"_process":1,"fbjs/lib/invariant":220}],68:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -4908,11 +6459,9 @@ module.exports = DOMChildrenOperations; * @typechecks static-only */ -/*jslint bitwise: true */ - 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); function checkMask(value, bitmask) { return (value & bitmask) === bitmask; @@ -4948,6 +6497,9 @@ var DOMPropertyInjection = { * attribute name. Attribute names not specified use the **lowercase** * normalized name. * + * DOMAttributeNamespaces: object mapping React attribute name to the DOM + * attribute namespace URL. (Attribute names not specified use no namespace.) + * * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. * Property names not specified use the normalized name. * @@ -4956,92 +6508,68 @@ var DOMPropertyInjection = { * * @param {object} domPropertyConfig the config as described above. */ - injectDOMPropertyConfig: function(domPropertyConfig) { + injectDOMPropertyConfig: function (domPropertyConfig) { + var Injection = DOMPropertyInjection; var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); + DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute); } for (var propName in Properties) { - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; + !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + '\'%s\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName) : invariant(false) : undefined; var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; + var propConfig = Properties[propName]; + + var propertyInfo = { + attributeName: lowerCased, + attributeNamespace: null, + propertyName: propName, + mutationMethod: null, + + mustUseAttribute: checkMask(propConfig, Injection.MUST_USE_ATTRIBUTE), + mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), + hasSideEffects: checkMask(propConfig, Injection.HAS_SIDE_EFFECTS), + hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), + hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), + hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), + hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) + }; + + !(!propertyInfo.mustUseAttribute || !propertyInfo.mustUseProperty) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Cannot require using both attribute and property: %s', propName) : invariant(false) : undefined; + !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : undefined; + !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : undefined; + + if (process.env.NODE_ENV !== 'production') { + DOMProperty.getPossibleStandardName[lowerCased] = propName; + } if (DOMAttributeNames.hasOwnProperty(propName)) { var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; + propertyInfo.attributeName = attributeName; + if (process.env.NODE_ENV !== 'production') { + DOMProperty.getPossibleStandardName[attributeName] = propName; + } } - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; + if (DOMAttributeNamespaces.hasOwnProperty(propName)) { + propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; + } + + if (DOMPropertyNames.hasOwnProperty(propName)) { + propertyInfo.propertyName = DOMPropertyNames[propName]; + } if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; + propertyInfo.mutationMethod = DOMMutationMethods[propName]; } - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + DOMProperty.properties[propName] = propertyInfo; } } }; @@ -5065,87 +6593,49 @@ var DOMProperty = { ID_ATTRIBUTE_NAME: 'data-reactid', /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, + * Map from property "standard name" to an object with info about how to set + * the property in the DOM. Each object contains: + * + * attributeName: + * Used when rendering markup or with `*Attribute()`. + * attributeNamespace + * propertyName: + * Used on DOM node instances. (This includes properties that mutate due to + * external factors.) + * mutationMethod: + * If non-null, used instead of the property or `setAttribute()` after + * initial render. + * mustUseAttribute: + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails `<propName> in <element>`.) + * mustUseProperty: + * Whether the property must be accessed and mutated as an object property. + * hasSideEffects: + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. If true, we read from + * the DOM before updating to ensure that the value is only set if it has + * changed. + * hasBooleanValue: + * Whether the property should be removed when set to a falsey value. + * hasNumericValue: + * Whether the property must be numeric or parse as a numeric and should be + * removed when set to a falsey value. + * hasPositiveNumericValue: + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * hasOverloadedBooleanValue: + * Whether the property can be used as a flag as well as with a value. + * Removed when strictly equal to false; present without a value when + * strictly equal to true; present with a value otherwise. + */ + properties: {}, /** * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails `<propName> in <element>`.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. + * to warn in the case of missing properties. Available only in __DEV__. * @type {Object} */ - hasOverloadedBooleanValue: {}, + getPossibleStandardName: process.env.NODE_ENV !== 'production' ? {} : null, /** * All of the isCustomAttribute() functions that have been injected. @@ -5156,7 +6646,7 @@ var DOMProperty = { * Checks whether a property name is a custom attribute. * @method */ - isCustomAttribute: function(attributeName) { + isCustomAttribute: function (attributeName) { for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; if (isCustomAttributeFn(attributeName)) { @@ -5174,7 +6664,7 @@ var DOMProperty = { * TODO: Is it better to grab all the possible properties when creating an * element to avoid having to create the same element twice? */ - getDefaultValueForProperty: function(nodeName, prop) { + getDefaultValueForProperty: function (nodeName, prop) { var nodeDefaults = defaultValueCache[nodeName]; var testElement; if (!nodeDefaults) { @@ -5191,10 +6681,9 @@ var DOMProperty = { }; module.exports = DOMProperty; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],52:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],69:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -5210,20 +6699,38 @@ module.exports = DOMProperty; 'use strict'; -var DOMProperty = require("./DOMProperty"); +var DOMProperty = require('./DOMProperty'); +var ReactPerf = require('./ReactPerf'); -var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser"); -var warning = require("./warning"); +var quoteAttributeValueForBrowser = require('./quoteAttributeValueForBrowser'); +var warning = require('fbjs/lib/warning'); -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); +// Simplified subset +var VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][\w\.\-]*$/; +var illegalAttributeNameCache = {}; +var validatedAttributeNameCache = {}; + +function isAttributeNameSafe(attributeName) { + if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { + return true; + } + if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { + return false; + } + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { + validatedAttributeNameCache[attributeName] = true; + return true; + } + illegalAttributeNameCache[attributeName] = true; + process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : undefined; + return false; } -if ("production" !== process.env.NODE_ENV) { +function shouldIgnoreValue(propertyInfo, value) { + return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; +} + +if (process.env.NODE_ENV !== 'production') { var reactProps = { children: true, dangerouslySetInnerHTML: true, @@ -5232,9 +6739,8 @@ if ("production" !== process.env.NODE_ENV) { }; var warnedProperties = {}; - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + var warnUnknownProperty = function (name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { return; } @@ -5242,23 +6748,11 @@ if ("production" !== process.env.NODE_ENV) { var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); + var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; // For now, only warn when we have a suggested correction. This prevents // logging too much when using transferPropsTo. - ("production" !== process.env.NODE_ENV ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - + process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : undefined; }; } @@ -5273,9 +6767,12 @@ var DOMPropertyOperations = { * @param {string} id Unescaped ID. * @return {string} Markup string. */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); + createMarkupForID: function (id) { + return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); + }, + + setAttributeForID: function (node, id) { + node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); }, /** @@ -5285,16 +6782,15 @@ var DOMPropertyOperations = { * @param {*} value * @return {?string} Markup string, or null if the property was invalid. */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { + createMarkupForProperty: function (name, value) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + if (shouldIgnoreValue(propertyInfo, value)) { return ''; } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; + var attributeName = propertyInfo.attributeName; + if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { + return attributeName + '=""'; } return attributeName + '=' + quoteAttributeValueForBrowser(value); } else if (DOMProperty.isCustomAttribute(name)) { @@ -5302,92 +6798,121 @@ var DOMPropertyOperations = { return ''; } return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== process.env.NODE_ENV) { + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } return null; }, /** + * Creates markup for a custom property. + * + * @param {string} name + * @param {*} value + * @return {string} Markup string, or empty string if the property was invalid. + */ + createMarkupForCustomAttribute: function (name, value) { + if (!isAttributeNameSafe(name) || value == null) { + return ''; + } + return name + '=' + quoteAttributeValueForBrowser(value); + }, + + /** * Sets the value for a property on a node. * * @param {DOMElement} node * @param {string} name * @param {*} value */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; + setValueForProperty: function (node, name, value) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { + } else if (shouldIgnoreValue(propertyInfo, value)) { this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { + } else if (propertyInfo.mustUseAttribute) { + var attributeName = propertyInfo.attributeName; + var namespace = propertyInfo.attributeNamespace; // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + if (namespace) { + node.setAttributeNS(namespace, attributeName, '' + value); + } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { + node.setAttribute(attributeName, ''); + } else { + node.setAttribute(attributeName, '' + value); + } } else { - var propName = DOMProperty.getPropertyName[name]; + var propName = propertyInfo.propertyName; // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { + if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value) { // Contrary to `setAttribute`, object properties are properly // `toString`ed by IE8/9. node[propName] = value; } } } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== process.env.NODE_ENV) { + DOMPropertyOperations.setValueForAttribute(node, name, value); + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } }, + setValueForAttribute: function (node, name, value) { + if (!isAttributeNameSafe(name)) { + return; + } + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + }, + /** * Deletes the value for a property on a node. * * @param {DOMElement} node * @param {string} name */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; + deleteValueForProperty: function (node, name) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); + } else if (propertyInfo.mustUseAttribute) { + node.removeAttribute(propertyInfo.attributeName); } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { + var propName = propertyInfo.propertyName; + var defaultValue = DOMProperty.getDefaultValueForProperty(node.nodeName, propName); + if (!propertyInfo.hasSideEffects || '' + node[propName] !== defaultValue) { node[propName] = defaultValue; } } } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); - } else if ("production" !== process.env.NODE_ENV) { + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } } }; -module.exports = DOMPropertyOperations; +ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', { + setValueForProperty: 'setValueForProperty', + setValueForAttribute: 'setValueForAttribute', + deleteValueForProperty: 'deleteValueForProperty' +}); +module.exports = DOMPropertyOperations; }).call(this,require('_process')) -},{"./DOMProperty":51,"./quoteAttributeValueForBrowser":204,"./warning":212,"_process":1}],53:[function(require,module,exports){ +},{"./DOMProperty":68,"./ReactPerf":136,"./quoteAttributeValueForBrowser":195,"_process":1,"fbjs/lib/warning":232}],70:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -5401,16 +6926,14 @@ module.exports = DOMPropertyOperations; * @typechecks static-only */ -/*jslint evil: true, sub: true */ - 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); +var createNodesFromMarkup = require('fbjs/lib/createNodesFromMarkup'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var getMarkupWrap = require('fbjs/lib/getMarkupWrap'); +var invariant = require('fbjs/lib/invariant'); var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; var RESULT_INDEX_ATTR = 'data-danger-index'; @@ -5441,22 +6964,13 @@ var Danger = { * @return {array<DOMElement>} List of rendered nodes. * @internal */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); + dangerouslyRenderMarkup: function (markupList) { + !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : undefined; var nodeName; var markupByNodeName = {}; // Group markup by `nodeName` if a wrap is necessary, else by '*'. for (var i = 0; i < markupList.length; i++) { - ("production" !== process.env.NODE_ENV ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); + !markupList[i] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : undefined; nodeName = getNodeName(markupList[i]); nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; @@ -5481,61 +6995,41 @@ var Danger = { // Push the requested markup with an additional RESULT_INDEX_ATTR // attribute. If the markup does not start with a < character, it // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); + markupListByNodeName[resultIndex] = markup.replace(OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '); } } // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with <script> tags. + var renderNodes = createNodesFromMarkup(markupListByNodeName.join(''), emptyFunction // Do nothing special with <script> tags. ); for (var j = 0; j < renderNodes.length; ++j) { var renderNode = renderNodes[j]; - if (renderNode.hasAttribute && - renderNode.hasAttribute(RESULT_INDEX_ATTR)) { + if (renderNode.hasAttribute && renderNode.hasAttribute(RESULT_INDEX_ATTR)) { resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); renderNode.removeAttribute(RESULT_INDEX_ATTR); - ("production" !== process.env.NODE_ENV ? invariant( - !resultList.hasOwnProperty(resultIndex), - 'Danger: Assigning to an already-occupied result index.' - ) : invariant(!resultList.hasOwnProperty(resultIndex))); + !!resultList.hasOwnProperty(resultIndex) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Assigning to an already-occupied result index.') : invariant(false) : undefined; resultList[resultIndex] = renderNode; // This should match resultList.length and markupList.length when // we're done. resultListAssignmentCount += 1; - - } else if ("production" !== process.env.NODE_ENV) { - console.error( - 'Danger: Discarding unexpected node:', - renderNode - ); + } else if (process.env.NODE_ENV !== 'production') { + console.error('Danger: Discarding unexpected node:', renderNode); } } } // Although resultList was populated out of order, it should now be a dense // array. - ("production" !== process.env.NODE_ENV ? invariant( - resultListAssignmentCount === resultList.length, - 'Danger: Did not assign to every index of resultList.' - ) : invariant(resultListAssignmentCount === resultList.length)); - - ("production" !== process.env.NODE_ENV ? invariant( - resultList.length === markupList.length, - 'Danger: Expected markup to render %s nodes, but rendered %s.', - markupList.length, - resultList.length - ) : invariant(resultList.length === markupList.length)); + !(resultListAssignmentCount === resultList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Did not assign to every index of resultList.') : invariant(false) : undefined; + + !(resultList.length === markupList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length) : invariant(false) : undefined; return resultList; }, @@ -5548,34 +7042,26 @@ var Danger = { * @param {string} markup Markup to render in place of the child node. * @internal */ - dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + - 'worker thread. Make sure `window` and `document` are available ' + - 'globally before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - ("production" !== process.env.NODE_ENV ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup)); - ("production" !== process.env.NODE_ENV ? invariant( - oldChild.tagName.toLowerCase() !== 'html', - 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + - '<html> node. This is because browser quirks make this unreliable ' + - 'and/or slow. If you want to render to the root you must use ' + - 'server rendering. See React.renderToString().' - ) : invariant(oldChild.tagName.toLowerCase() !== 'html')); - - var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; + dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) { + !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. Make sure `window` and `document` are available ' + 'globally before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined; + !markup ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(false) : undefined; + !(oldChild.tagName.toLowerCase() !== 'html') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + '<html> node. This is because browser quirks make this unreliable ' + 'and/or slow. If you want to render to the root you must use ' + 'server rendering. See ReactDOMServer.renderToString().') : invariant(false) : undefined; + + var newChild; + if (typeof markup === 'string') { + newChild = createNodesFromMarkup(markup, emptyFunction)[0]; + } else { + newChild = markup; + } oldChild.parentNode.replaceChild(newChild, oldChild); } }; module.exports = Danger; - }).call(this,require('_process')) -},{"./ExecutionEnvironment":62,"./createNodesFromMarkup":167,"./emptyFunction":170,"./getMarkupWrap":183,"./invariant":191,"_process":1}],54:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/createNodesFromMarkup":211,"fbjs/lib/emptyFunction":212,"fbjs/lib/getMarkupWrap":216,"fbjs/lib/invariant":220}],71:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -5589,7 +7075,7 @@ module.exports = Danger; 'use strict'; -var keyOf = require("./keyOf"); +var keyOf = require('fbjs/lib/keyOf'); /** * Module that is injectable into `EventPluginHub`, that specifies a @@ -5600,21 +7086,10 @@ var keyOf = require("./keyOf"); * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that * preventing default on events is convenient in `SimpleEventPlugin` handlers. */ -var DefaultEventPluginOrder = [ - keyOf({ResponderEventPlugin: null}), - keyOf({SimpleEventPlugin: null}), - keyOf({TapEventPlugin: null}), - keyOf({EnterLeaveEventPlugin: null}), - keyOf({ChangeEventPlugin: null}), - keyOf({SelectEventPlugin: null}), - keyOf({BeforeInputEventPlugin: null}), - keyOf({AnalyticsEventPlugin: null}), - keyOf({MobileSafariClickEventPlugin: null}) -]; +var DefaultEventPluginOrder = [keyOf({ ResponderEventPlugin: null }), keyOf({ SimpleEventPlugin: null }), keyOf({ TapEventPlugin: null }), keyOf({ EnterLeaveEventPlugin: null }), keyOf({ ChangeEventPlugin: null }), keyOf({ SelectEventPlugin: null }), keyOf({ BeforeInputEventPlugin: null })]; module.exports = DefaultEventPluginOrder; - -},{"./keyOf":198}],55:[function(require,module,exports){ +},{"fbjs/lib/keyOf":225}],72:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -5629,30 +7104,24 @@ module.exports = DefaultEventPluginOrder; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var SyntheticMouseEvent = require("./SyntheticMouseEvent"); +var EventConstants = require('./EventConstants'); +var EventPropagators = require('./EventPropagators'); +var SyntheticMouseEvent = require('./SyntheticMouseEvent'); -var ReactMount = require("./ReactMount"); -var keyOf = require("./keyOf"); +var ReactMount = require('./ReactMount'); +var keyOf = require('fbjs/lib/keyOf'); var topLevelTypes = EventConstants.topLevelTypes; var getFirstReactDOM = ReactMount.getFirstReactDOM; var eventTypes = { mouseEnter: { - registrationName: keyOf({onMouseEnter: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] + registrationName: keyOf({ onMouseEnter: null }), + dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver] }, mouseLeave: { - registrationName: keyOf({onMouseLeave: null}), - dependencies: [ - topLevelTypes.topMouseOut, - topLevelTypes.topMouseOver - ] + registrationName: keyOf({ onMouseLeave: null }), + dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver] } }; @@ -5676,17 +7145,11 @@ var EnterLeaveEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topMouseOver && - (nativeEvent.relatedTarget || nativeEvent.fromElement)) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { return null; } - if (topLevelType !== topLevelTypes.topMouseOut && - topLevelType !== topLevelTypes.topMouseOver) { + if (topLevelType !== topLevelTypes.topMouseOut && topLevelType !== topLevelTypes.topMouseOver) { // Must not be a mouse in or mouse out - ignoring. return null; } @@ -5705,15 +7168,24 @@ var EnterLeaveEventPlugin = { } } - var from, to; + var from; + var to; + var fromID = ''; + var toID = ''; if (topLevelType === topLevelTypes.topMouseOut) { from = topLevelTarget; - to = - getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) || - win; + fromID = topLevelTargetID; + to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement); + if (to) { + toID = ReactMount.getID(to); + } else { + to = win; + } + to = to || win; } else { from = win; to = topLevelTarget; + toID = topLevelTargetID; } if (from === to) { @@ -5721,23 +7193,12 @@ var EnterLeaveEventPlugin = { return null; } - var fromID = from ? ReactMount.getID(from) : ''; - var toID = to ? ReactMount.getID(to) : ''; - - var leave = SyntheticMouseEvent.getPooled( - eventTypes.mouseLeave, - fromID, - nativeEvent - ); + var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, fromID, nativeEvent, nativeEventTarget); leave.type = 'mouseleave'; leave.target = from; leave.relatedTarget = to; - var enter = SyntheticMouseEvent.getPooled( - eventTypes.mouseEnter, - toID, - nativeEvent - ); + var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, toID, nativeEvent, nativeEventTarget); enter.type = 'mouseenter'; enter.target = to; enter.relatedTarget = from; @@ -5753,8 +7214,7 @@ var EnterLeaveEventPlugin = { }; module.exports = EnterLeaveEventPlugin; - -},{"./EventConstants":56,"./EventPropagators":61,"./ReactMount":117,"./SyntheticMouseEvent":153,"./keyOf":198}],56:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPropagators":77,"./ReactMount":130,"./SyntheticMouseEvent":168,"fbjs/lib/keyOf":225}],73:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -5768,15 +7228,18 @@ module.exports = EnterLeaveEventPlugin; 'use strict'; -var keyMirror = require("./keyMirror"); +var keyMirror = require('fbjs/lib/keyMirror'); -var PropagationPhases = keyMirror({bubbled: null, captured: null}); +var PropagationPhases = keyMirror({ bubbled: null, captured: null }); /** * Types of raw signals from the browser caught at the top level. */ var topLevelTypes = keyMirror({ + topAbort: null, topBlur: null, + topCanPlay: null, + topCanPlayThrough: null, topChange: null, topClick: null, topCompositionEnd: null, @@ -5794,6 +7257,10 @@ var topLevelTypes = keyMirror({ topDragOver: null, topDragStart: null, topDrop: null, + topDurationChange: null, + topEmptied: null, + topEncrypted: null, + topEnded: null, topError: null, topFocus: null, topInput: null, @@ -5801,21 +7268,36 @@ var topLevelTypes = keyMirror({ topKeyPress: null, topKeyUp: null, topLoad: null, + topLoadedData: null, + topLoadedMetadata: null, + topLoadStart: null, topMouseDown: null, topMouseMove: null, topMouseOut: null, topMouseOver: null, topMouseUp: null, topPaste: null, + topPause: null, + topPlay: null, + topPlaying: null, + topProgress: null, + topRateChange: null, topReset: null, topScroll: null, + topSeeked: null, + topSeeking: null, topSelectionChange: null, + topStalled: null, topSubmit: null, + topSuspend: null, topTextInput: null, + topTimeUpdate: null, topTouchCancel: null, topTouchEnd: null, topTouchMove: null, topTouchStart: null, + topVolumeChange: null, + topWaiting: null, topWheel: null }); @@ -5825,99 +7307,7 @@ var EventConstants = { }; module.exports = EventConstants; - -},{"./keyMirror":197}],57:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @providesModule EventListener - * @typechecks - */ - -var emptyFunction = require("./emptyFunction"); - -/** - * Upstream version of event listener. Does not take into account specific - * nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function() { - target.detachEvent('on' + eventType, callback); - } - }; - } - }, - - /** - * Listen to DOM events during the capture phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - capture: function(target, eventType, callback) { - if (!target.addEventListener) { - if ("production" !== process.env.NODE_ENV) { - console.error( - 'Attempted to listen to events during the capture phase on a ' + - 'browser that does not support the capture phase. Your application ' + - 'will not receive some events.' - ); - } - return { - remove: emptyFunction - }; - } else { - target.addEventListener(eventType, callback, true); - return { - remove: function() { - target.removeEventListener(eventType, callback, true); - } - }; - } - }, - - registerDefault: function() {} -}; - -module.exports = EventListener; - -}).call(this,require('_process')) - -},{"./emptyFunction":170,"_process":1}],58:[function(require,module,exports){ +},{"fbjs/lib/keyMirror":224}],74:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -5932,12 +7322,14 @@ module.exports = EventListener; 'use strict'; -var EventPluginRegistry = require("./EventPluginRegistry"); -var EventPluginUtils = require("./EventPluginUtils"); +var EventPluginRegistry = require('./EventPluginRegistry'); +var EventPluginUtils = require('./EventPluginUtils'); +var ReactErrorUtils = require('./ReactErrorUtils'); -var accumulateInto = require("./accumulateInto"); -var forEachAccumulated = require("./forEachAccumulated"); -var invariant = require("./invariant"); +var accumulateInto = require('./accumulateInto'); +var forEachAccumulated = require('./forEachAccumulated'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); /** * Internal store for event listeners @@ -5954,23 +7346,24 @@ var eventQueue = null; * Dispatches an event and releases it back into the pool, unless persistent. * * @param {?object} event Synthetic event to be dispatched. + * @param {boolean} simulated If the event is simulated (changes exn behavior) * @private */ -var executeDispatchesAndRelease = function(event) { +var executeDispatchesAndRelease = function (event, simulated) { 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); + EventPluginUtils.executeDispatchesInOrder(event, simulated); if (!event.isPersistent()) { event.constructor.release(event); } } }; +var executeDispatchesAndReleaseSimulated = function (e) { + return executeDispatchesAndRelease(e, true); +}; +var executeDispatchesAndReleaseTopLevel = function (e) { + return executeDispatchesAndRelease(e, false); +}; /** * - `InstanceHandle`: [required] Module that performs logical traversals of DOM @@ -5979,14 +7372,8 @@ var executeDispatchesAndRelease = function(event) { var InstanceHandle = null; function validateInstanceHandle() { - var valid = - InstanceHandle && - InstanceHandle.traverseTwoPhase && - InstanceHandle.traverseEnterLeave; - ("production" !== process.env.NODE_ENV ? invariant( - valid, - 'InstanceHandle not injected before use!' - ) : invariant(valid)); + var valid = InstanceHandle && InstanceHandle.traverseTwoPhase && InstanceHandle.traverseEnterLeave; + process.env.NODE_ENV !== 'production' ? warning(valid, 'InstanceHandle not injected before use!') : undefined; } /** @@ -6028,15 +7415,15 @@ var EventPluginHub = { * @param {object} InjectedInstanceHandle * @public */ - injectInstanceHandle: function(InjectedInstanceHandle) { + injectInstanceHandle: function (InjectedInstanceHandle) { InstanceHandle = InjectedInstanceHandle; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { validateInstanceHandle(); } }, - getInstanceHandle: function() { - if ("production" !== process.env.NODE_ENV) { + getInstanceHandle: function () { + if (process.env.NODE_ENV !== 'production') { validateInstanceHandle(); } return InstanceHandle; @@ -6066,16 +7453,16 @@ var EventPluginHub = { * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {?function} listener The callback to store. */ - putListener: function(id, registrationName, listener) { - ("production" !== process.env.NODE_ENV ? invariant( - !listener || typeof listener === 'function', - 'Expected %s listener to be a function, instead got type %s', - registrationName, typeof listener - ) : invariant(!listener || typeof listener === 'function')); + putListener: function (id, registrationName, listener) { + !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : invariant(false) : undefined; - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); + var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); bankForRegistrationName[id] = listener; + + var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; + if (PluginModule && PluginModule.didPutListener) { + PluginModule.didPutListener(id, registrationName, listener); + } }, /** @@ -6083,7 +7470,7 @@ var EventPluginHub = { * @param {string} registrationName Name of listener (e.g. `onClick`). * @return {?function} The stored callback. */ - getListener: function(id, registrationName) { + getListener: function (id, registrationName) { var bankForRegistrationName = listenerBank[registrationName]; return bankForRegistrationName && bankForRegistrationName[id]; }, @@ -6094,8 +7481,14 @@ var EventPluginHub = { * @param {string} id ID of the DOM element. * @param {string} registrationName Name of listener (e.g. `onClick`). */ - deleteListener: function(id, registrationName) { + deleteListener: function (id, registrationName) { + var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; + if (PluginModule && PluginModule.willDeleteListener) { + PluginModule.willDeleteListener(id, registrationName); + } + var bankForRegistrationName = listenerBank[registrationName]; + // TODO: This should never be null -- when is it? if (bankForRegistrationName) { delete bankForRegistrationName[id]; } @@ -6106,8 +7499,17 @@ var EventPluginHub = { * * @param {string} id ID of the DOM element. */ - deleteAllListeners: function(id) { + deleteAllListeners: function (id) { for (var registrationName in listenerBank) { + if (!listenerBank[registrationName][id]) { + continue; + } + + var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; + if (PluginModule && PluginModule.willDeleteListener) { + PluginModule.willDeleteListener(id, registrationName); + } + delete listenerBank[registrationName][id]; } }, @@ -6123,23 +7525,14 @@ var EventPluginHub = { * @return {*} An accumulation of synthetic events. * @internal */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var events; var plugins = EventPluginRegistry.plugins; - for (var i = 0, l = plugins.length; i < l; i++) { + for (var i = 0; i < plugins.length; 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 - ); + var extractedEvents = possiblePlugin.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget); if (extractedEvents) { events = accumulateInto(events, extractedEvents); } @@ -6155,7 +7548,7 @@ var EventPluginHub = { * @param {*} events An accumulation of synthetic events. * @internal */ - enqueueEvents: function(events) { + enqueueEvents: function (events) { if (events) { eventQueue = accumulateInto(eventQueue, events); } @@ -6166,37 +7559,38 @@ var EventPluginHub = { * * @internal */ - processEventQueue: function() { + processEventQueue: function (simulated) { // Set `eventQueue` to null before processing it so that we can tell if more // events get enqueued while processing. var processingEventQueue = eventQueue; eventQueue = null; - forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); - ("production" !== process.env.NODE_ENV ? invariant( - !eventQueue, - 'processEventQueue(): Additional events were enqueued while processing ' + - 'an event queue. Support for this has not yet been implemented.' - ) : invariant(!eventQueue)); + if (simulated) { + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); + } else { + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + } + !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.') : invariant(false) : undefined; + // This would be a good time to rethrow if any of the event handlers threw. + ReactErrorUtils.rethrowCaughtError(); }, /** * These are needed for tests only. Do not use! */ - __purge: function() { + __purge: function () { listenerBank = {}; }, - __getListenerBank: function() { + __getListenerBank: function () { return listenerBank; } }; module.exports = EventPluginHub; - }).call(this,require('_process')) -},{"./EventPluginRegistry":59,"./EventPluginUtils":60,"./accumulateInto":159,"./forEachAccumulated":176,"./invariant":191,"_process":1}],59:[function(require,module,exports){ +},{"./EventPluginRegistry":75,"./EventPluginUtils":76,"./ReactErrorUtils":119,"./accumulateInto":174,"./forEachAccumulated":183,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],75:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -6212,7 +7606,7 @@ module.exports = EventPluginHub; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * Injectable ordering of event plugins. @@ -6237,38 +7631,15 @@ function recomputePluginOrdering() { for (var pluginName in namesToPlugins) { var PluginModule = namesToPlugins[pluginName]; var pluginIndex = EventPluginOrder.indexOf(pluginName); - ("production" !== process.env.NODE_ENV ? invariant( - pluginIndex > -1, - 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + - 'the plugin ordering, `%s`.', - pluginName - ) : invariant(pluginIndex > -1)); + !(pluginIndex > -1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName) : invariant(false) : undefined; if (EventPluginRegistry.plugins[pluginIndex]) { continue; } - ("production" !== process.env.NODE_ENV ? invariant( - PluginModule.extractEvents, - 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + - 'method, but `%s` does not.', - pluginName - ) : invariant(PluginModule.extractEvents)); + !PluginModule.extractEvents ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName) : invariant(false) : undefined; EventPluginRegistry.plugins[pluginIndex] = PluginModule; var publishedEvents = PluginModule.eventTypes; for (var eventName in publishedEvents) { - ("production" !== process.env.NODE_ENV ? invariant( - publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ), - 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', - eventName, - pluginName - ) : invariant(publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ))); + !publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : invariant(false) : undefined; } } } @@ -6282,12 +7653,7 @@ function recomputePluginOrdering() { * @private */ function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { - ("production" !== process.env.NODE_ENV ? invariant( - !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName), - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'event name, `%s`.', - eventName - ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName))); + !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName) : invariant(false) : undefined; EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -6295,20 +7661,12 @@ function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { for (var phaseName in phasedRegistrationNames) { if (phasedRegistrationNames.hasOwnProperty(phaseName)) { var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - PluginModule, - eventName - ); + publishRegistrationName(phasedRegistrationName, PluginModule, eventName); } } return true; } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - PluginModule, - eventName - ); + publishRegistrationName(dispatchConfig.registrationName, PluginModule, eventName); return true; } return false; @@ -6323,15 +7681,9 @@ function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { * @private */ function publishRegistrationName(registrationName, PluginModule, eventName) { - ("production" !== process.env.NODE_ENV ? invariant( - !EventPluginRegistry.registrationNameModules[registrationName], - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'registration name, `%s`.', - registrationName - ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); + !!EventPluginRegistry.registrationNameModules[registrationName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName) : invariant(false) : undefined; EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = - PluginModule.eventTypes[eventName].dependencies; + EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies; } /** @@ -6370,12 +7722,8 @@ var EventPluginRegistry = { * @internal * @see {EventPluginHub.injection.injectEventPluginOrder} */ - injectEventPluginOrder: function(InjectedEventPluginOrder) { - ("production" !== process.env.NODE_ENV ? invariant( - !EventPluginOrder, - 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + - 'once. You are likely trying to load more than one copy of React.' - ) : invariant(!EventPluginOrder)); + injectEventPluginOrder: function (InjectedEventPluginOrder) { + !!EventPluginOrder ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + 'once. You are likely trying to load more than one copy of React.') : invariant(false) : undefined; // Clone the ordering so it cannot be dynamically mutated. EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); recomputePluginOrdering(); @@ -6391,21 +7739,15 @@ var EventPluginRegistry = { * @internal * @see {EventPluginHub.injection.injectEventPluginsByName} */ - injectEventPluginsByName: function(injectedNamesToPlugins) { + injectEventPluginsByName: function (injectedNamesToPlugins) { var isOrderingDirty = false; for (var pluginName in injectedNamesToPlugins) { if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { continue; } var PluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== PluginModule) { - ("production" !== process.env.NODE_ENV ? invariant( - !namesToPlugins[pluginName], - 'EventPluginRegistry: Cannot inject two different event plugins ' + - 'using the same name, `%s`.', - pluginName - ) : invariant(!namesToPlugins[pluginName])); + if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== PluginModule) { + !!namesToPlugins[pluginName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName) : invariant(false) : undefined; namesToPlugins[pluginName] = PluginModule; isOrderingDirty = true; } @@ -6422,20 +7764,16 @@ var EventPluginRegistry = { * @return {?object} The plugin that created the supplied event. * @internal */ - getPluginModuleForEvent: function(event) { + getPluginModuleForEvent: function (event) { var dispatchConfig = event.dispatchConfig; if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[ - dispatchConfig.registrationName - ] || null; + 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] - ]; + var PluginModule = EventPluginRegistry.registrationNameModules[dispatchConfig.phasedRegistrationNames[phase]]; if (PluginModule) { return PluginModule; } @@ -6447,7 +7785,7 @@ var EventPluginRegistry = { * Exposed for unit testing. * @private */ - _resetEventPlugins: function() { + _resetEventPlugins: function () { EventPluginOrder = null; for (var pluginName in namesToPlugins) { if (namesToPlugins.hasOwnProperty(pluginName)) { @@ -6474,10 +7812,9 @@ var EventPluginRegistry = { }; module.exports = EventPluginRegistry; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],60:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],76:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -6492,9 +7829,11 @@ module.exports = EventPluginRegistry; 'use strict'; -var EventConstants = require("./EventConstants"); +var EventConstants = require('./EventConstants'); +var ReactErrorUtils = require('./ReactErrorUtils'); -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); /** * Injected dependencies: @@ -6506,14 +7845,10 @@ var invariant = require("./invariant"); */ var injection = { Mount: null, - injectMount: function(InjectedMount) { + injectMount: function (InjectedMount) { injection.Mount = InjectedMount; - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? invariant( - InjectedMount && InjectedMount.getNode, - 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + - 'is missing getNode.' - ) : invariant(InjectedMount && InjectedMount.getNode)); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(InjectedMount && InjectedMount.getNode && InjectedMount.getID, 'EventPluginUtils.injection.injectMount(...): Injected Mount ' + 'module is missing getNode or getID.') : undefined; } } }; @@ -6521,50 +7856,56 @@ var injection = { var topLevelTypes = EventConstants.topLevelTypes; function isEndish(topLevelType) { - return topLevelType === topLevelTypes.topMouseUp || - topLevelType === topLevelTypes.topTouchEnd || - topLevelType === topLevelTypes.topTouchCancel; + return topLevelType === topLevelTypes.topMouseUp || topLevelType === topLevelTypes.topTouchEnd || topLevelType === topLevelTypes.topTouchCancel; } function isMoveish(topLevelType) { - return topLevelType === topLevelTypes.topMouseMove || - topLevelType === topLevelTypes.topTouchMove; + return topLevelType === topLevelTypes.topMouseMove || topLevelType === topLevelTypes.topTouchMove; } function isStartish(topLevelType) { - return topLevelType === topLevelTypes.topMouseDown || - topLevelType === topLevelTypes.topTouchStart; + return topLevelType === topLevelTypes.topMouseDown || topLevelType === topLevelTypes.topTouchStart; } - var validateEventDispatches; -if ("production" !== process.env.NODE_ENV) { - validateEventDispatches = function(event) { +if (process.env.NODE_ENV !== 'production') { + validateEventDispatches = function (event) { var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; var listenersIsArr = Array.isArray(dispatchListeners); var idsIsArr = Array.isArray(dispatchIDs); var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; - var listenersLen = listenersIsArr ? - dispatchListeners.length : - dispatchListeners ? 1 : 0; - - ("production" !== process.env.NODE_ENV ? invariant( - idsIsArr === listenersIsArr && IDsLen === listenersLen, - 'EventPluginUtils: Invalid `event`.' - ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); + var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; + + process.env.NODE_ENV !== 'production' ? warning(idsIsArr === listenersIsArr && IDsLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : undefined; }; } /** - * 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. + * Dispatch the event to the listener. + * @param {SyntheticEvent} event SyntheticEvent to handle + * @param {boolean} simulated If the event is simulated (changes exn behavior) + * @param {function} listener Application-level callback + * @param {string} domID DOM id to pass to the callback. */ -function forEachEventDispatch(event, cb) { +function executeDispatch(event, simulated, listener, domID) { + var type = event.type || 'unknown-event'; + event.currentTarget = injection.Mount.getNode(domID); + if (simulated) { + ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event, domID); + } else { + ReactErrorUtils.invokeGuardedCallback(type, listener, event, domID); + } + event.currentTarget = null; +} + +/** + * Standard/simple iteration through an event's collected dispatches. + */ +function executeDispatchesInOrder(event, simulated) { var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { @@ -6573,31 +7914,11 @@ function forEachEventDispatch(event, cb) { break; } // Listeners and IDs are two parallel arrays that are always in sync. - cb(event, dispatchListeners[i], dispatchIDs[i]); + executeDispatch(event, simulated, dispatchListeners[i], dispatchIDs[i]); } } else if (dispatchListeners) { - cb(event, dispatchListeners, dispatchIDs); + executeDispatch(event, simulated, 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; } @@ -6606,13 +7927,13 @@ function executeDispatchesInOrder(event, cb) { * 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. + * @return {?string} id of the first dispatch execution who's listener returns + * true, or null if no listener returned true. */ function executeDispatchesInOrderStopAtTrueImpl(event) { var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { @@ -6650,21 +7971,16 @@ function executeDispatchesInOrderStopAtTrue(event) { * 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. + * @return {*} The return value of executing the single dispatch. */ function executeDirectDispatch(event) { - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { validateEventDispatches(event); } var dispatchListener = event._dispatchListeners; var dispatchID = event._dispatchIDs; - ("production" !== process.env.NODE_ENV ? invariant( - !Array.isArray(dispatchListener), - 'executeDirectDispatch(...): Invalid `event`.' - ) : invariant(!Array.isArray(dispatchListener))); - var res = dispatchListener ? - dispatchListener(event, dispatchID) : - null; + !!Array.isArray(dispatchListener) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : invariant(false) : undefined; + var res = dispatchListener ? dispatchListener(event, dispatchID) : null; event._dispatchListeners = null; event._dispatchIDs = null; return res; @@ -6672,7 +7988,7 @@ function executeDirectDispatch(event) { /** * @param {SyntheticEvent} event - * @return {bool} True iff number of dispatches accumulated is greater than 0. + * @return {boolean} True iff number of dispatches accumulated is greater than 0. */ function hasDispatches(event) { return !!event._dispatchListeners; @@ -6687,19 +8003,24 @@ var EventPluginUtils = { isStartish: isStartish, executeDirectDispatch: executeDirectDispatch, - executeDispatch: executeDispatch, executeDispatchesInOrder: executeDispatchesInOrder, executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, hasDispatches: hasDispatches, - injection: injection, - useTouchEvents: false + + getNode: function (id) { + return injection.Mount.getNode(id); + }, + getID: function (node) { + return injection.Mount.getID(node); + }, + + injection: injection }; module.exports = EventPluginUtils; - }).call(this,require('_process')) -},{"./EventConstants":56,"./invariant":191,"_process":1}],61:[function(require,module,exports){ +},{"./EventConstants":73,"./ReactErrorUtils":119,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],77:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -6714,11 +8035,13 @@ module.exports = EventPluginUtils; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); +var EventConstants = require('./EventConstants'); +var EventPluginHub = require('./EventPluginHub'); + +var warning = require('fbjs/lib/warning'); -var accumulateInto = require("./accumulateInto"); -var forEachAccumulated = require("./forEachAccumulated"); +var accumulateInto = require('./accumulateInto'); +var forEachAccumulated = require('./forEachAccumulated'); var PropagationPhases = EventConstants.PropagationPhases; var getListener = EventPluginHub.getListener; @@ -6728,8 +8051,7 @@ var getListener = EventPluginHub.getListener; * "phases" of propagation. This finds listeners by a given phase. */ function listenerAtPhase(id, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; return getListener(id, registrationName); } @@ -6740,16 +8062,13 @@ function listenerAtPhase(id, event, propagationPhase) { * "dispatch" object that pairs the event with the listener. */ function accumulateDirectionalDispatches(domID, upwards, event) { - if ("production" !== process.env.NODE_ENV) { - if (!domID) { - throw new Error('Dispatching id must not be null'); - } + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(domID, 'Dispatching id must not be null') : undefined; } var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; var listener = listenerAtPhase(domID, event, phase); if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); + event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); event._dispatchIDs = accumulateInto(event._dispatchIDs, domID); } } @@ -6757,20 +8076,24 @@ function accumulateDirectionalDispatches(domID, upwards, event) { /** * 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 + * each event and perform the traversal for each one. We cannot 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 - ); + 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 @@ -6782,8 +8105,7 @@ function accumulateDispatches(id, ignoredDirection, event) { var registrationName = event.dispatchConfig.registrationName; var listener = getListener(id, registrationName); if (listener) { - event._dispatchListeners = - accumulateInto(event._dispatchListeners, listener); + event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); event._dispatchIDs = accumulateInto(event._dispatchIDs, id); } } @@ -6804,23 +8126,18 @@ function accumulateTwoPhaseDispatches(events) { forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } -function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) { - EventPluginHub.injection.getInstanceHandle().traverseEnterLeave( - fromID, - toID, - accumulateDispatches, - leave, - enter - ); +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 @@ -6834,59 +8151,15 @@ function accumulateDirectDispatches(events) { */ var EventPropagators = { accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, + accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, accumulateDirectDispatches: accumulateDirectDispatches, accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches }; module.exports = EventPropagators; - }).call(this,require('_process')) -},{"./EventConstants":56,"./EventPluginHub":58,"./accumulateInto":159,"./forEachAccumulated":176,"_process":1}],62:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule 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; - -},{}],63:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPluginHub":74,"./accumulateInto":174,"./forEachAccumulated":183,"_process":1,"fbjs/lib/warning":232}],78:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -6901,10 +8174,10 @@ module.exports = ExecutionEnvironment; 'use strict'; -var PooledClass = require("./PooledClass"); +var PooledClass = require('./PooledClass'); -var assign = require("./Object.assign"); -var getTextContentAccessor = require("./getTextContentAccessor"); +var assign = require('./Object.assign'); +var getTextContentAccessor = require('./getTextContentAccessor'); /** * This helper class stores information about text content of a target node, @@ -6924,12 +8197,18 @@ function FallbackCompositionState(root) { } assign(FallbackCompositionState.prototype, { + destructor: function () { + this._root = null; + this._startText = null; + this._fallbackText = null; + }, + /** * Get current text of input. * * @return {string} */ - getText: function() { + getText: function () { if ('value' in this._root) { return this._root.value; } @@ -6942,7 +8221,7 @@ assign(FallbackCompositionState.prototype, { * * @return {string} */ - getData: function() { + getData: function () { if (this._fallbackText) { return this._fallbackText; } @@ -6976,8 +8255,7 @@ assign(FallbackCompositionState.prototype, { PooledClass.addPoolingTo(FallbackCompositionState); module.exports = FallbackCompositionState; - -},{"./Object.assign":69,"./PooledClass":70,"./getTextContentAccessor":186}],64:[function(require,module,exports){ +},{"./Object.assign":82,"./PooledClass":83,"./getTextContentAccessor":190}],79:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -6989,41 +8267,27 @@ module.exports = FallbackCompositionState; * @providesModule HTMLDOMPropertyConfig */ -/*jslint bitwise: true*/ - 'use strict'; -var DOMProperty = require("./DOMProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var DOMProperty = require('./DOMProperty'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = - DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = - DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; +var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; +var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; var hasSVG; if (ExecutionEnvironment.canUseDOM) { var implementation = document.implementation; - hasSVG = ( - implementation && - implementation.hasFeature && - implementation.hasFeature( - 'http://www.w3.org/TR/SVG11/feature#BasicStructure', - '1.1' - ) - ); + hasSVG = implementation && implementation.hasFeature && implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'); } - var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind( - /^(data|aria)-[a-z_][a-z\d_.\-]*$/ - ), + isCustomAttribute: RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/), Properties: { /** * Standard Properties @@ -7037,12 +8301,14 @@ var HTMLDOMPropertyConfig = { alt: null, async: HAS_BOOLEAN_VALUE, autoComplete: null, - // autoFocus is polyfilled/normalized by AutoFocusMixin + // autoFocus is polyfilled/normalized by AutoFocusUtils // autoFocus: HAS_BOOLEAN_VALUE, autoPlay: HAS_BOOLEAN_VALUE, + capture: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, cellPadding: null, cellSpacing: null, charSet: MUST_USE_ATTRIBUTE, + challenge: MUST_USE_ATTRIBUTE, checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, classID: MUST_USE_ATTRIBUTE, // To set className on SVG elements, it's necessary to use .setAttribute; @@ -7061,6 +8327,7 @@ var HTMLDOMPropertyConfig = { crossOrigin: null, data: null, // For `<object />` acts as `src`. dateTime: MUST_USE_ATTRIBUTE, + 'default': HAS_BOOLEAN_VALUE, defer: HAS_BOOLEAN_VALUE, dir: null, disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, @@ -7084,6 +8351,12 @@ var HTMLDOMPropertyConfig = { httpEquiv: null, icon: null, id: MUST_USE_PROPERTY, + inputMode: MUST_USE_ATTRIBUTE, + integrity: null, + is: MUST_USE_ATTRIBUTE, + keyParams: MUST_USE_ATTRIBUTE, + keyType: MUST_USE_ATTRIBUTE, + kind: null, label: null, lang: null, list: MUST_USE_ATTRIBUTE, @@ -7098,9 +8371,11 @@ var HTMLDOMPropertyConfig = { mediaGroup: null, method: null, min: null, + minLength: MUST_USE_ATTRIBUTE, multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, name: null, + nonce: MUST_USE_ATTRIBUTE, noValidate: HAS_BOOLEAN_VALUE, open: HAS_BOOLEAN_VALUE, optimum: null, @@ -7112,6 +8387,7 @@ var HTMLDOMPropertyConfig = { readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, rel: null, required: HAS_BOOLEAN_VALUE, + reversed: HAS_BOOLEAN_VALUE, role: MUST_USE_ATTRIBUTE, rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, rowSpan: null, @@ -7128,10 +8404,12 @@ var HTMLDOMPropertyConfig = { spellCheck: null, src: null, srcDoc: MUST_USE_PROPERTY, + srcLang: null, srcSet: MUST_USE_ATTRIBUTE, start: HAS_NUMERIC_VALUE, step: null, style: null, + summary: null, tabIndex: null, target: null, title: null, @@ -7140,14 +8418,32 @@ var HTMLDOMPropertyConfig = { value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS, width: MUST_USE_ATTRIBUTE, wmode: MUST_USE_ATTRIBUTE, + wrap: null, + + /** + * RDFa Properties + */ + about: MUST_USE_ATTRIBUTE, + datatype: MUST_USE_ATTRIBUTE, + inlist: MUST_USE_ATTRIBUTE, + prefix: MUST_USE_ATTRIBUTE, + // property is also supported for OpenGraph in meta tags. + property: MUST_USE_ATTRIBUTE, + resource: MUST_USE_ATTRIBUTE, + 'typeof': MUST_USE_ATTRIBUTE, + vocab: MUST_USE_ATTRIBUTE, /** * Non-standard Properties */ // autoCapitalize and autoCorrect are supported in Mobile Safari for // keyboard hints. - autoCapitalize: null, - autoCorrect: null, + autoCapitalize: MUST_USE_ATTRIBUTE, + autoCorrect: MUST_USE_ATTRIBUTE, + // autoSave allows WebKit/Blink to persist values of input fields on page reloads + autoSave: null, + // color is for Safari mask-icon link + color: null, // itemProp, itemScope, itemType are for // Microdata support. See http://schema.org/docs/gs.html itemProp: MUST_USE_ATTRIBUTE, @@ -7158,8 +8454,12 @@ var HTMLDOMPropertyConfig = { // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api itemID: MUST_USE_ATTRIBUTE, itemRef: MUST_USE_ATTRIBUTE, - // property is supported for OpenGraph in meta tags. - property: null, + // results show looking glass icon and recent searches on input + // search fields in WebKit/Blink + results: null, + // IE-only attribute that specifies security restrictions on an iframe + // as an alternative to the sandbox attribute on IE<10 + security: MUST_USE_ATTRIBUTE, // IE-only attribute that controls focus behavior unselectable: MUST_USE_ATTRIBUTE }, @@ -7170,11 +8470,10 @@ var HTMLDOMPropertyConfig = { httpEquiv: 'http-equiv' }, DOMPropertyNames: { - autoCapitalize: 'autocapitalize', autoComplete: 'autocomplete', - autoCorrect: 'autocorrect', autoFocus: 'autofocus', autoPlay: 'autoplay', + autoSave: 'autosave', // `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter. // http://www.w3.org/TR/html5/forms.html#dom-fs-encoding encType: 'encoding', @@ -7187,8 +8486,7 @@ var HTMLDOMPropertyConfig = { }; module.exports = HTMLDOMPropertyConfig; - -},{"./DOMProperty":51,"./ExecutionEnvironment":62}],65:[function(require,module,exports){ +},{"./DOMProperty":68,"fbjs/lib/ExecutionEnvironment":206}],80:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7203,8 +8501,8 @@ module.exports = HTMLDOMPropertyConfig; 'use strict'; -var ReactLink = require("./ReactLink"); -var ReactStateSetters = require("./ReactStateSetters"); +var ReactLink = require('./ReactLink'); +var ReactStateSetters = require('./ReactStateSetters'); /** * A simple mixin around ReactLink.forState(). @@ -7219,17 +8517,13 @@ var LinkedStateMixin = { * if you're using Google Closure Compiler advanced mode. * @return {ReactLink} ReactLink instance linking to the state. */ - linkState: function(key) { - return new ReactLink( - this.state[key], - ReactStateSetters.createStateKeySetter(this, key) - ); + linkState: function (key) { + return new ReactLink(this.state[key], ReactStateSetters.createStateKeySetter(this, key)); } }; module.exports = LinkedStateMixin; - -},{"./ReactLink":115,"./ReactStateSetters":134}],66:[function(require,module,exports){ +},{"./ReactLink":128,"./ReactStateSetters":148}],81:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -7245,9 +8539,11 @@ module.exports = LinkedStateMixin; 'use strict'; -var ReactPropTypes = require("./ReactPropTypes"); +var ReactPropTypes = require('./ReactPropTypes'); +var ReactPropTypeLocations = require('./ReactPropTypeLocations'); -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); var hasReadOnlyValue = { 'button': true, @@ -7259,46 +8555,44 @@ var hasReadOnlyValue = { 'submit': true }; -function _assertSingleLink(input) { - ("production" !== process.env.NODE_ENV ? invariant( - input.props.checkedLink == null || input.props.valueLink == null, - 'Cannot provide a checkedLink and a valueLink. If you want to use ' + - 'checkedLink, you probably don\'t want to use valueLink and vice versa.' - ) : invariant(input.props.checkedLink == null || input.props.valueLink == null)); +function _assertSingleLink(inputProps) { + !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use ' + 'checkedLink, you probably don\'t want to use valueLink and vice versa.') : invariant(false) : undefined; } -function _assertValueLink(input) { - _assertSingleLink(input); - ("production" !== process.env.NODE_ENV ? invariant( - input.props.value == null && input.props.onChange == null, - 'Cannot provide a valueLink and a value or onChange event. If you want ' + - 'to use value or onChange, you probably don\'t want to use valueLink.' - ) : invariant(input.props.value == null && input.props.onChange == null)); +function _assertValueLink(inputProps) { + _assertSingleLink(inputProps); + !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want ' + 'to use value or onChange, you probably don\'t want to use valueLink.') : invariant(false) : undefined; } -function _assertCheckedLink(input) { - _assertSingleLink(input); - ("production" !== process.env.NODE_ENV ? invariant( - input.props.checked == null && input.props.onChange == null, - 'Cannot provide a checkedLink and a checked property or onChange event. ' + - 'If you want to use checked or onChange, you probably don\'t want to ' + - 'use checkedLink' - ) : invariant(input.props.checked == null && input.props.onChange == null)); +function _assertCheckedLink(inputProps) { + _assertSingleLink(inputProps); + !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. ' + 'If you want to use checked or onChange, you probably don\'t want to ' + 'use checkedLink') : invariant(false) : undefined; } -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedValueChange(e) { - /*jshint validthis:true */ - this.props.valueLink.requestChange(e.target.value); -} +var propTypes = { + value: function (props, propName, componentName) { + if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { + return null; + } + return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); + }, + checked: function (props, propName, componentName) { + if (!props[propName] || props.onChange || props.readOnly || props.disabled) { + return null; + } + return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); + }, + onChange: ReactPropTypes.func +}; -/** - * @param {SyntheticEvent} e change event to handle - */ -function _handleLinkedCheckChange(e) { - /*jshint validthis:true */ - this.props.checkedLink.requestChange(e.target.checked); +var loggedTypeFailures = {}; +function getDeclarationErrorAddendum(owner) { + if (owner) { + var name = owner.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } + } + return ''; } /** @@ -7306,203 +8600,68 @@ function _handleLinkedCheckChange(e) { * this outside of the ReactDOM controlled form components. */ var LinkedValueUtils = { - Mixin: { - propTypes: { - value: function(props, propName, componentName) { - if (!props[propName] || - hasReadOnlyValue[props.type] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `value` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultValue`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - checked: function(props, propName, componentName) { - if (!props[propName] || - props.onChange || - props.readOnly || - props.disabled) { - return null; - } - return new Error( - 'You provided a `checked` prop to a form field without an ' + - '`onChange` handler. This will render a read-only field. If ' + - 'the field should be mutable use `defaultChecked`. Otherwise, ' + - 'set either `onChange` or `readOnly`.' - ); - }, - onChange: ReactPropTypes.func + checkPropTypes: function (tagName, props, owner) { + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error = propTypes[propName](props, propName, tagName, ReactPropTypeLocations.prop); + } + 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(owner); + process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : undefined; + } } }, /** - * @param {ReactComponent} input Form component + * @param {object} inputProps Props for form component * @return {*} current value of the input either from value prop or link. */ - getValue: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return input.props.valueLink.value; + getValue: function (inputProps) { + if (inputProps.valueLink) { + _assertValueLink(inputProps); + return inputProps.valueLink.value; } - return input.props.value; + return inputProps.value; }, /** - * @param {ReactComponent} input Form component + * @param {object} inputProps Props for form component * @return {*} current checked status of the input either from checked prop * or link. */ - getChecked: function(input) { - if (input.props.checkedLink) { - _assertCheckedLink(input); - return input.props.checkedLink.value; + getChecked: function (inputProps) { + if (inputProps.checkedLink) { + _assertCheckedLink(inputProps); + return inputProps.checkedLink.value; } - return input.props.checked; + return inputProps.checked; }, /** - * @param {ReactComponent} input Form component - * @return {function} change callback either from onChange prop or link. + * @param {object} inputProps Props for form component + * @param {SyntheticEvent} event change event to handle */ - getOnChange: function(input) { - if (input.props.valueLink) { - _assertValueLink(input); - return _handleLinkedValueChange; - } else if (input.props.checkedLink) { - _assertCheckedLink(input); - return _handleLinkedCheckChange; + executeOnChange: function (inputProps, event) { + if (inputProps.valueLink) { + _assertValueLink(inputProps); + return inputProps.valueLink.requestChange(event.target.value); + } else if (inputProps.checkedLink) { + _assertCheckedLink(inputProps); + return inputProps.checkedLink.requestChange(event.target.checked); + } else if (inputProps.onChange) { + return inputProps.onChange.call(undefined, event); } - return input.props.onChange; } }; module.exports = LinkedValueUtils; - -}).call(this,require('_process')) - -},{"./ReactPropTypes":126,"./invariant":191,"_process":1}],67:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule LocalEventTrapMixin - */ - -'use strict'; - -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); - -var accumulateInto = require("./accumulateInto"); -var forEachAccumulated = require("./forEachAccumulated"); -var invariant = require("./invariant"); - -function remove(event) { - event.remove(); -} - -var LocalEventTrapMixin = { - trapBubbledEvent:function(topLevelType, handlerBaseName) { - ("production" !== process.env.NODE_ENV ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted())); - // If a component renders to null or if another component fatals and causes - // the state of the tree to be corrupted, `node` here can be null. - var node = this.getDOMNode(); - ("production" !== process.env.NODE_ENV ? invariant( - node, - 'LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered.' - ) : invariant(node)); - var listener = ReactBrowserEventEmitter.trapBubbledEvent( - topLevelType, - handlerBaseName, - node - ); - this._localEventListeners = - accumulateInto(this._localEventListeners, listener); - }, - - // trapCapturedEvent would look nearly identical. We don't implement that - // method because it isn't currently needed. - - componentWillUnmount:function() { - if (this._localEventListeners) { - forEachAccumulated(this._localEventListeners, remove); - } - } -}; - -module.exports = LocalEventTrapMixin; - }).call(this,require('_process')) -},{"./ReactBrowserEventEmitter":73,"./accumulateInto":159,"./forEachAccumulated":176,"./invariant":191,"_process":1}],68:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule MobileSafariClickEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = require("./EventConstants"); - -var emptyFunction = require("./emptyFunction"); - -var topLevelTypes = EventConstants.topLevelTypes; - -/** - * Mobile Safari does not fire properly bubble click events on non-interactive - * elements, which means delegated click listeners do not fire. The workaround - * for this bug involves attaching an empty click listener on the target node. - * - * This particular plugin works around the bug by attaching an empty click - * listener on `touchstart` (which does fire on every element). - */ -var MobileSafariClickEventPlugin = { - - eventTypes: null, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - if (topLevelType === topLevelTypes.topTouchStart) { - var target = nativeEvent.target; - if (target && !target.onclick) { - target.onclick = emptyFunction; - } - } - } - -}; - -module.exports = MobileSafariClickEventPlugin; - -},{"./EventConstants":56,"./emptyFunction":170}],69:[function(require,module,exports){ +},{"./ReactPropTypeLocations":139,"./ReactPropTypes":140,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],82:[function(require,module,exports){ /** * Copyright 2014-2015, Facebook, Inc. * All rights reserved. @@ -7550,8 +8709,7 @@ function assign(target, sources) { } module.exports = assign; - -},{}],70:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -7566,7 +8724,7 @@ module.exports = assign; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * Static poolers. Several custom versions for each potential number of @@ -7575,7 +8733,7 @@ var invariant = require("./invariant"); * 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 oneArgumentPooler = function (copyFieldsFrom) { var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); @@ -7586,7 +8744,7 @@ var oneArgumentPooler = function(copyFieldsFrom) { } }; -var twoArgumentPooler = function(a1, a2) { +var twoArgumentPooler = function (a1, a2) { var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); @@ -7597,7 +8755,7 @@ var twoArgumentPooler = function(a1, a2) { } }; -var threeArgumentPooler = function(a1, a2, a3) { +var threeArgumentPooler = function (a1, a2, a3) { var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); @@ -7608,7 +8766,18 @@ var threeArgumentPooler = function(a1, a2, a3) { } }; -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { +var fourArgumentPooler = function (a1, a2, a3, a4) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3, a4); + return instance; + } else { + return new Klass(a1, a2, a3, a4); + } +}; + +var fiveArgumentPooler = function (a1, a2, a3, a4, a5) { var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); @@ -7619,15 +8788,10 @@ var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { } }; -var standardReleaser = function(instance) { +var standardReleaser = function (instance) { var Klass = this; - ("production" !== process.env.NODE_ENV ? invariant( - instance instanceof Klass, - 'Trying to release an instance into a pool of a different type.' - ) : invariant(instance instanceof Klass)); - if (instance.destructor) { - instance.destructor(); - } + !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : invariant(false) : undefined; + instance.destructor(); if (Klass.instancePool.length < Klass.poolSize) { Klass.instancePool.push(instance); } @@ -7645,7 +8809,7 @@ var DEFAULT_POOLER = oneArgumentPooler; * @param {Function} CopyConstructor Constructor that can be used to reset. * @param {Function} pooler Customizable pooler. */ -var addPoolingTo = function(CopyConstructor, pooler) { +var addPoolingTo = function (CopyConstructor, pooler) { var NewKlass = CopyConstructor; NewKlass.instancePool = []; NewKlass.getPooled = pooler || DEFAULT_POOLER; @@ -7661,15 +8825,14 @@ var PooledClass = { oneArgumentPooler: oneArgumentPooler, twoArgumentPooler: twoArgumentPooler, threeArgumentPooler: threeArgumentPooler, + fourArgumentPooler: fourArgumentPooler, fiveArgumentPooler: fiveArgumentPooler }; module.exports = PooledClass; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],71:[function(require,module,exports){ -(function (process){ +},{"_process":1,"fbjs/lib/invariant":220}],84:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7681,147 +8844,37 @@ module.exports = PooledClass; * @providesModule React */ -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ - 'use strict'; -var EventPluginUtils = require("./EventPluginUtils"); -var ReactChildren = require("./ReactChildren"); -var ReactComponent = require("./ReactComponent"); -var ReactClass = require("./ReactClass"); -var ReactContext = require("./ReactContext"); -var ReactCurrentOwner = require("./ReactCurrentOwner"); -var ReactElement = require("./ReactElement"); -var ReactElementValidator = require("./ReactElementValidator"); -var ReactDOM = require("./ReactDOM"); -var ReactDOMTextComponent = require("./ReactDOMTextComponent"); -var ReactDefaultInjection = require("./ReactDefaultInjection"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactMount = require("./ReactMount"); -var ReactPerf = require("./ReactPerf"); -var ReactPropTypes = require("./ReactPropTypes"); -var ReactReconciler = require("./ReactReconciler"); -var ReactServerRendering = require("./ReactServerRendering"); - -var assign = require("./Object.assign"); -var findDOMNode = require("./findDOMNode"); -var onlyChild = require("./onlyChild"); +var ReactDOM = require('./ReactDOM'); +var ReactDOMServer = require('./ReactDOMServer'); +var ReactIsomorphic = require('./ReactIsomorphic'); -ReactDefaultInjection.inject(); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if ("production" !== process.env.NODE_ENV) { - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var render = ReactPerf.measure('React', 'render', ReactMount.render); - -var React = { - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - only: onlyChild - }, - Component: ReactComponent, - DOM: ReactDOM, - PropTypes: ReactPropTypes, - initializeTouchEvents: function(shouldUseTouch) { - EventPluginUtils.useTouchEvents = shouldUseTouch; - }, - createClass: ReactClass.createClass, - createElement: createElement, - cloneElement: cloneElement, - createFactory: createFactory, - createMixin: function(mixin) { - // Currently a noop. Will be used to validate and trace mixins. - return mixin; - }, - constructAndRenderComponent: ReactMount.constructAndRenderComponent, - constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, - findDOMNode: findDOMNode, - render: render, - renderToString: ReactServerRendering.renderToString, - renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup, - unmountComponentAtNode: ReactMount.unmountComponentAtNode, - isValidElement: ReactElement.isValidElement, - withContext: ReactContext.withContext, - - // Hook for JSX spread, don't use this for anything else. - __spread: assign -}; +var assign = require('./Object.assign'); +var deprecated = require('./deprecated'); -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - CurrentOwner: ReactCurrentOwner, - InstanceHandles: ReactInstanceHandles, - Mount: ReactMount, - Reconciler: ReactReconciler, - TextComponent: ReactDOMTextComponent - }); -} - -if ("production" !== process.env.NODE_ENV) { - var ExecutionEnvironment = require("./ExecutionEnvironment"); - if (ExecutionEnvironment.canUseDOM && window.top === window.self) { +// `version` will be added here by ReactIsomorphic. +var React = {}; - // If we're in Chrome, look for the devtools marker and provide a download - // link if not installed. - if (navigator.userAgent.indexOf('Chrome') > -1) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { - console.debug( - 'Download the React DevTools for a better development experience: ' + - 'https://fb.me/react-devtools' - ); - } - } +assign(React, ReactIsomorphic); - var expectedFeatures = [ - // shims - Array.isArray, - Array.prototype.every, - Array.prototype.forEach, - Array.prototype.indexOf, - Array.prototype.map, - Date.now, - Function.prototype.bind, - Object.keys, - String.prototype.split, - String.prototype.trim, - - // shams - Object.create, - Object.freeze - ]; +assign(React, { + // ReactDOM + findDOMNode: deprecated('findDOMNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.findDOMNode), + render: deprecated('render', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.render), + unmountComponentAtNode: deprecated('unmountComponentAtNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.unmountComponentAtNode), - for (var i = 0; i < expectedFeatures.length; i++) { - if (!expectedFeatures[i]) { - console.error( - 'One or more ES5 shim/shams expected by React are not available: ' + - 'https://fb.me/react-warning-polyfills' - ); - break; - } - } - } -} + // ReactDOMServer + renderToString: deprecated('renderToString', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToString), + renderToStaticMarkup: deprecated('renderToStaticMarkup', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToStaticMarkup) +}); -React.version = '0.13.3'; +React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOM; +React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOMServer; module.exports = React; - -}).call(this,require('_process')) - -},{"./EventPluginUtils":60,"./ExecutionEnvironment":62,"./Object.assign":69,"./ReactChildren":77,"./ReactClass":78,"./ReactComponent":79,"./ReactContext":84,"./ReactCurrentOwner":85,"./ReactDOM":86,"./ReactDOMTextComponent":97,"./ReactDefaultInjection":100,"./ReactElement":103,"./ReactElementValidator":104,"./ReactInstanceHandles":112,"./ReactMount":117,"./ReactPerf":122,"./ReactPropTypes":126,"./ReactReconciler":129,"./ReactServerRendering":132,"./findDOMNode":173,"./onlyChild":201,"_process":1}],72:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactDOM":98,"./ReactDOMServer":108,"./ReactIsomorphic":127,"./deprecated":179}],85:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7835,7 +8888,12 @@ module.exports = React; 'use strict'; -var findDOMNode = require("./findDOMNode"); +var ReactInstanceMap = require('./ReactInstanceMap'); + +var findDOMNode = require('./findDOMNode'); +var warning = require('fbjs/lib/warning'); + +var didWarnKey = '_getDOMNodeDidWarn'; var ReactBrowserComponentMixin = { /** @@ -7845,14 +8903,17 @@ var ReactBrowserComponentMixin = { * @final * @protected */ - getDOMNode: function() { + getDOMNode: function () { + process.env.NODE_ENV !== 'production' ? warning(this.constructor[didWarnKey], '%s.getDOMNode(...) is deprecated. Please use ' + 'ReactDOM.findDOMNode(instance) instead.', ReactInstanceMap.get(this).getName() || this.tagName || 'Unknown') : undefined; + this.constructor[didWarnKey] = true; return findDOMNode(this); } }; module.exports = ReactBrowserComponentMixin; +}).call(this,require('_process')) -},{"./findDOMNode":173}],73:[function(require,module,exports){ +},{"./ReactInstanceMap":126,"./findDOMNode":181,"_process":1,"fbjs/lib/warning":232}],86:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7867,14 +8928,15 @@ module.exports = ReactBrowserComponentMixin; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPluginRegistry = require("./EventPluginRegistry"); -var ReactEventEmitterMixin = require("./ReactEventEmitterMixin"); -var ViewportMetrics = require("./ViewportMetrics"); +var EventConstants = require('./EventConstants'); +var EventPluginHub = require('./EventPluginHub'); +var EventPluginRegistry = require('./EventPluginRegistry'); +var ReactEventEmitterMixin = require('./ReactEventEmitterMixin'); +var ReactPerf = require('./ReactPerf'); +var ViewportMetrics = require('./ViewportMetrics'); -var assign = require("./Object.assign"); -var isEventSupported = require("./isEventSupported"); +var assign = require('./Object.assign'); +var isEventSupported = require('./isEventSupported'); /** * Summary of `ReactBrowserEventEmitter` event handling: @@ -7939,7 +9001,10 @@ var reactTopListenersCounter = 0; // lower node than `document`), binding at `document` would cause duplicate // events so we don't include them here var topEventMapping = { + topAbort: 'abort', topBlur: 'blur', + topCanPlay: 'canplay', + topCanPlayThrough: 'canplaythrough', topChange: 'change', topClick: 'click', topCompositionEnd: 'compositionend', @@ -7957,24 +9022,44 @@ var topEventMapping = { topDragOver: 'dragover', topDragStart: 'dragstart', topDrop: 'drop', + topDurationChange: 'durationchange', + topEmptied: 'emptied', + topEncrypted: 'encrypted', + topEnded: 'ended', + topError: 'error', topFocus: 'focus', topInput: 'input', topKeyDown: 'keydown', topKeyPress: 'keypress', topKeyUp: 'keyup', + topLoadedData: 'loadeddata', + topLoadedMetadata: 'loadedmetadata', + topLoadStart: 'loadstart', topMouseDown: 'mousedown', topMouseMove: 'mousemove', topMouseOut: 'mouseout', topMouseOver: 'mouseover', topMouseUp: 'mouseup', topPaste: 'paste', + topPause: 'pause', + topPlay: 'play', + topPlaying: 'playing', + topProgress: 'progress', + topRateChange: 'ratechange', topScroll: 'scroll', + topSeeked: 'seeked', + topSeeking: 'seeking', topSelectionChange: 'selectionchange', + topStalled: 'stalled', + topSuspend: 'suspend', topTextInput: 'textInput', + topTimeUpdate: 'timeupdate', topTouchCancel: 'touchcancel', topTouchEnd: 'touchend', topTouchMove: 'touchmove', topTouchStart: 'touchstart', + topVolumeChange: 'volumechange', + topWaiting: 'waiting', topWheel: 'wheel' }; @@ -8014,10 +9099,8 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { /** * @param {object} ReactEventListener */ - injectReactEventListener: function(ReactEventListener) { - ReactEventListener.setHandleTopLevel( - ReactBrowserEventEmitter.handleTopLevel - ); + injectReactEventListener: function (ReactEventListener) { + ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel); ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; } }, @@ -8027,7 +9110,7 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { * * @param {boolean} enabled True if callbacks should be enabled. */ - setEnabled: function(enabled) { + setEnabled: function (enabled) { if (ReactBrowserEventEmitter.ReactEventListener) { ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); } @@ -8036,10 +9119,8 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { /** * @return {boolean} True if callbacks are enabled. */ - isEnabled: function() { - return !!( - (ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()) - ); + isEnabled: function () { + return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()); }, /** @@ -8063,93 +9144,49 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {object} contentDocumentHandle Document which owns the container */ - listenTo: function(registrationName, contentDocumentHandle) { + listenTo: function (registrationName, contentDocumentHandle) { var mountAt = contentDocumentHandle; var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry. - registrationNameDependencies[registrationName]; + var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; var topLevelTypes = EventConstants.topLevelTypes; - for (var i = 0, l = dependencies.length; i < l; i++) { + for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; - if (!( - (isListening.hasOwnProperty(dependency) && isListening[dependency]) - )) { + if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { if (dependency === topLevelTypes.topWheel) { if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'wheel', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt); } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'mousewheel', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt); } else { // Firefox needs to capture a different mouse scroll event. // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'DOMMouseScroll', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt); } } else if (dependency === topLevelTypes.topScroll) { if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topScroll, - 'scroll', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt); } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topScroll, - 'scroll', - ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topScroll, 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE); } - } else if (dependency === topLevelTypes.topFocus || - dependency === topLevelTypes.topBlur) { + } else if (dependency === topLevelTypes.topFocus || dependency === topLevelTypes.topBlur) { if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topFocus, - 'focus', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topBlur, - 'blur', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt); + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt); } else if (isEventSupported('focusin')) { // IE has `focusin` and `focusout` events which bubble. // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topFocus, - 'focusin', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topBlur, - 'focusout', - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt); } // to make sure blur and focus event listeners are only attached once isListening[topLevelTypes.topBlur] = true; isListening[topLevelTypes.topFocus] = true; } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - dependency, - topEventMapping[dependency], - mountAt - ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt); } isListening[dependency] = true; @@ -8157,20 +9194,12 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { } }, - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelType, - handlerBaseName, - handle - ); + trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle); }, - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelType, - handlerBaseName, - handle - ); + trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle); }, /** @@ -8181,7 +9210,7 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { * * @see http://www.quirksmode.org/dom/events/scroll.html */ - ensureScrollValueMonitoring: function() { + ensureScrollValueMonitoring: function () { if (!isMonitoringScrollValue) { var refresh = ViewportMetrics.refreshScrollValues; ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); @@ -8203,9 +9232,13 @@ var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { }); -module.exports = ReactBrowserEventEmitter; +ReactPerf.measureMethods(ReactBrowserEventEmitter, 'ReactBrowserEventEmitter', { + putListener: 'putListener', + deleteListener: 'deleteListener' +}); -},{"./EventConstants":56,"./EventPluginHub":58,"./EventPluginRegistry":59,"./Object.assign":69,"./ReactEventEmitterMixin":107,"./ViewportMetrics":158,"./isEventSupported":192}],74:[function(require,module,exports){ +module.exports = ReactBrowserEventEmitter; +},{"./EventConstants":73,"./EventPluginHub":74,"./EventPluginRegistry":75,"./Object.assign":82,"./ReactEventEmitterMixin":120,"./ReactPerf":136,"./ViewportMetrics":173,"./isEventSupported":192}],87:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -8220,28 +9253,47 @@ module.exports = ReactBrowserEventEmitter; 'use strict'; -var React = require("./React"); +var React = require('./React'); -var assign = require("./Object.assign"); +var assign = require('./Object.assign'); -var ReactTransitionGroup = React.createFactory( - require("./ReactTransitionGroup") -); -var ReactCSSTransitionGroupChild = React.createFactory( - require("./ReactCSSTransitionGroupChild") -); +var ReactTransitionGroup = require('./ReactTransitionGroup'); +var ReactCSSTransitionGroupChild = require('./ReactCSSTransitionGroupChild'); + +function createTransitionTimeoutPropValidator(transitionType) { + var timeoutPropName = 'transition' + transitionType + 'Timeout'; + var enabledPropName = 'transition' + transitionType; + + return function (props) { + // If the transition is enabled + if (props[enabledPropName]) { + // If no timeout duration is provided + if (props[timeoutPropName] == null) { + return new Error(timeoutPropName + ' wasn\'t supplied to ReactCSSTransitionGroup: ' + 'this can cause unreliable animations and won\'t be supported in ' + 'a future version of React. See ' + 'https://fb.me/react-animation-transition-group-timeout for more ' + 'information.'); + + // If the duration isn't a number + } else if (typeof props[timeoutPropName] !== 'number') { + return new Error(timeoutPropName + ' must be a number (in milliseconds)'); + } + } + }; +} var ReactCSSTransitionGroup = React.createClass({ displayName: 'ReactCSSTransitionGroup', propTypes: { - transitionName: React.PropTypes.string.isRequired, + transitionName: ReactCSSTransitionGroupChild.propTypes.name, + transitionAppear: React.PropTypes.bool, transitionEnter: React.PropTypes.bool, - transitionLeave: React.PropTypes.bool + transitionLeave: React.PropTypes.bool, + transitionAppearTimeout: createTransitionTimeoutPropValidator('Appear'), + transitionEnterTimeout: createTransitionTimeoutPropValidator('Enter'), + transitionLeaveTimeout: createTransitionTimeoutPropValidator('Leave') }, - getDefaultProps: function() { + getDefaultProps: function () { return { transitionAppear: false, transitionEnter: true, @@ -8249,34 +9301,28 @@ var ReactCSSTransitionGroup = React.createClass({ }; }, - _wrapChild: function(child) { + _wrapChild: function (child) { // We need to provide this childFactory so that // ReactCSSTransitionGroupChild can receive updates to name, enter, and // leave while it is leaving. - return ReactCSSTransitionGroupChild( - { - name: this.props.transitionName, - appear: this.props.transitionAppear, - enter: this.props.transitionEnter, - leave: this.props.transitionLeave - }, - child - ); + return React.createElement(ReactCSSTransitionGroupChild, { + name: this.props.transitionName, + appear: this.props.transitionAppear, + enter: this.props.transitionEnter, + leave: this.props.transitionLeave, + appearTimeout: this.props.transitionAppearTimeout, + enterTimeout: this.props.transitionEnterTimeout, + leaveTimeout: this.props.transitionLeaveTimeout + }, child); }, - render: function() { - return ( - ReactTransitionGroup( - assign({}, this.props, {childFactory: this._wrapChild}) - ) - ); + render: function () { + return React.createElement(ReactTransitionGroup, assign({}, this.props, { childFactory: this._wrapChild })); } }); module.exports = ReactCSSTransitionGroup; - -},{"./Object.assign":69,"./React":71,"./ReactCSSTransitionGroupChild":75,"./ReactTransitionGroup":138}],75:[function(require,module,exports){ -(function (process){ +},{"./Object.assign":82,"./React":84,"./ReactCSSTransitionGroupChild":88,"./ReactTransitionGroup":152}],88:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -8291,53 +9337,68 @@ module.exports = ReactCSSTransitionGroup; 'use strict'; -var React = require("./React"); +var React = require('./React'); +var ReactDOM = require('./ReactDOM'); -var CSSCore = require("./CSSCore"); -var ReactTransitionEvents = require("./ReactTransitionEvents"); +var CSSCore = require('fbjs/lib/CSSCore'); +var ReactTransitionEvents = require('./ReactTransitionEvents'); -var onlyChild = require("./onlyChild"); -var warning = require("./warning"); +var onlyChild = require('./onlyChild'); // We don't remove the element from the DOM until we receive an animationend or // transitionend event. If the user screws up and forgets to add an animation // their node will be stuck in the DOM forever, so we detect if an animation // does not start and if it doesn't, we just call the end listener immediately. var TICK = 17; -var NO_EVENT_TIMEOUT = 5000; - -var noEventListener = null; - - -if ("production" !== process.env.NODE_ENV) { - noEventListener = function() { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'transition(): tried to perform an animation without ' + - 'an animationend or transitionend event after timeout (' + - '%sms). You should either disable this ' + - 'transition in JS or add a CSS animation/transition.', - NO_EVENT_TIMEOUT - ) : null); - }; -} var ReactCSSTransitionGroupChild = React.createClass({ displayName: 'ReactCSSTransitionGroupChild', - transition: function(animationType, finishCallback) { - var node = this.getDOMNode(); - var className = this.props.name + '-' + animationType; - var activeClassName = className + '-active'; - var noEventTimeout = null; + propTypes: { + name: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.shape({ + enter: React.PropTypes.string, + leave: React.PropTypes.string, + active: React.PropTypes.string + }), React.PropTypes.shape({ + enter: React.PropTypes.string, + enterActive: React.PropTypes.string, + leave: React.PropTypes.string, + leaveActive: React.PropTypes.string, + appear: React.PropTypes.string, + appearActive: React.PropTypes.string + })]).isRequired, + + // Once we require timeouts to be specified, we can remove the + // boolean flags (appear etc.) and just accept a number + // or a bool for the timeout flags (appearTimeout etc.) + appear: React.PropTypes.bool, + enter: React.PropTypes.bool, + leave: React.PropTypes.bool, + appearTimeout: React.PropTypes.number, + enterTimeout: React.PropTypes.number, + leaveTimeout: React.PropTypes.number + }, + + transition: function (animationType, finishCallback, userSpecifiedDelay) { + var node = ReactDOM.findDOMNode(this); + + if (!node) { + if (finishCallback) { + finishCallback(); + } + return; + } + + var className = this.props.name[animationType] || this.props.name + '-' + animationType; + var activeClassName = this.props.name[animationType + 'Active'] || className + '-active'; + var timeout = null; - var endListener = function(e) { + var endListener = function (e) { if (e && e.target !== node) { return; } - if ("production" !== process.env.NODE_ENV) { - clearTimeout(noEventTimeout); - } + + clearTimeout(timeout); CSSCore.removeClass(node, className); CSSCore.removeClass(node, activeClassName); @@ -8351,19 +9412,23 @@ var ReactCSSTransitionGroupChild = React.createClass({ } }; - ReactTransitionEvents.addEndEventListener(node, endListener); - CSSCore.addClass(node, className); // Need to do this to actually trigger a transition. this.queueClass(activeClassName); - if ("production" !== process.env.NODE_ENV) { - noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT); + // If the user specified a timeout delay. + if (userSpecifiedDelay) { + // Clean-up the animation after the specified delay + timeout = setTimeout(endListener, userSpecifiedDelay); + this.transitionTimeouts.push(timeout); + } else { + // DEPRECATED: this listener will be removed in a future version of react + ReactTransitionEvents.addEndEventListener(node, endListener); } }, - queueClass: function(className) { + queueClass: function (className) { this.classNameQueue.push(className); if (!this.timeout) { @@ -8371,60 +9436,60 @@ var ReactCSSTransitionGroupChild = React.createClass({ } }, - flushClassNameQueue: function() { + flushClassNameQueue: function () { if (this.isMounted()) { - this.classNameQueue.forEach( - CSSCore.addClass.bind(CSSCore, this.getDOMNode()) - ); + this.classNameQueue.forEach(CSSCore.addClass.bind(CSSCore, ReactDOM.findDOMNode(this))); } this.classNameQueue.length = 0; this.timeout = null; }, - componentWillMount: function() { + componentWillMount: function () { this.classNameQueue = []; + this.transitionTimeouts = []; }, - componentWillUnmount: function() { + componentWillUnmount: function () { if (this.timeout) { clearTimeout(this.timeout); } + this.transitionTimeouts.forEach(function (timeout) { + clearTimeout(timeout); + }); }, - componentWillAppear: function(done) { + componentWillAppear: function (done) { if (this.props.appear) { - this.transition('appear', done); + this.transition('appear', done, this.props.appearTimeout); } else { done(); } }, - componentWillEnter: function(done) { + componentWillEnter: function (done) { if (this.props.enter) { - this.transition('enter', done); + this.transition('enter', done, this.props.enterTimeout); } else { done(); } }, - componentWillLeave: function(done) { + componentWillLeave: function (done) { if (this.props.leave) { - this.transition('leave', done); + this.transition('leave', done, this.props.leaveTimeout); } else { done(); } }, - render: function() { + render: function () { return onlyChild(this.props.children); } }); module.exports = ReactCSSTransitionGroupChild; - -}).call(this,require('_process')) - -},{"./CSSCore":44,"./React":71,"./ReactTransitionEvents":137,"./onlyChild":201,"./warning":212,"_process":1}],76:[function(require,module,exports){ +},{"./React":84,"./ReactDOM":98,"./ReactTransitionEvents":151,"./onlyChild":194,"fbjs/lib/CSSCore":204}],89:[function(require,module,exports){ +(function (process){ /** * Copyright 2014-2015, Facebook, Inc. * All rights reserved. @@ -8439,11 +9504,23 @@ module.exports = ReactCSSTransitionGroupChild; 'use strict'; -var ReactReconciler = require("./ReactReconciler"); +var ReactReconciler = require('./ReactReconciler'); + +var instantiateReactComponent = require('./instantiateReactComponent'); +var shouldUpdateReactComponent = require('./shouldUpdateReactComponent'); +var traverseAllChildren = require('./traverseAllChildren'); +var warning = require('fbjs/lib/warning'); -var flattenChildren = require("./flattenChildren"); -var instantiateReactComponent = require("./instantiateReactComponent"); -var shouldUpdateReactComponent = require("./shouldUpdateReactComponent"); +function instantiateChild(childInstances, child, name) { + // We found a component instance. + var keyUnique = childInstances[name] === undefined; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? 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) : undefined; + } + if (child != null && keyUnique) { + childInstances[name] = instantiateReactComponent(child, null); + } +} /** * ReactChildReconciler provides helpers for initializing or updating a set of @@ -8451,7 +9528,6 @@ var shouldUpdateReactComponent = require("./shouldUpdateReactComponent"); * 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. @@ -8460,41 +9536,31 @@ var ReactChildReconciler = { * @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; - } + instantiateChildren: function (nestedChildNodes, transaction, context) { + if (nestedChildNodes == null) { + return null; } - return children; + var childInstances = {}; + traverseAllChildren(nestedChildNodes, instantiateChild, childInstances); + return childInstances; }, /** * 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 {?object} nextChildren Flat child element maps. * @param {ReactReconcileTransaction} transaction * @param {object} context * @return {?object} A new set of child instances. * @internal */ - updateChildren: function( - prevChildren, - nextNestedChildNodes, - transaction, - context) { + updateChildren: function (prevChildren, nextChildren, 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; } @@ -8506,27 +9572,21 @@ var ReactChildReconciler = { var prevChild = prevChildren && prevChildren[name]; var prevElement = prevChild && prevChild._currentElement; var nextElement = nextChildren[name]; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - ReactReconciler.receiveComponent( - prevChild, nextElement, transaction, context - ); + if (prevChild != null && 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 - ); + 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))) { + if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { ReactReconciler.unmountComponent(prevChildren[name]); } } @@ -8540,19 +9600,21 @@ var ReactChildReconciler = { * @param {?object} renderedChildren Previously initialized set of children. * @internal */ - unmountChildren: function(renderedChildren) { + unmountChildren: function (renderedChildren) { for (var name in renderedChildren) { - var renderedChild = renderedChildren[name]; - ReactReconciler.unmountComponent(renderedChild); + if (renderedChildren.hasOwnProperty(name)) { + var renderedChild = renderedChildren[name]; + ReactReconciler.unmountComponent(renderedChild); + } } } }; module.exports = ReactChildReconciler; +}).call(this,require('_process')) -},{"./ReactReconciler":129,"./flattenChildren":174,"./instantiateReactComponent":190,"./shouldUpdateReactComponent":208}],77:[function(require,module,exports){ -(function (process){ +},{"./ReactReconciler":142,"./instantiateReactComponent":191,"./shouldUpdateReactComponent":200,"./traverseAllChildren":201,"_process":1,"fbjs/lib/warning":232}],90:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -8566,14 +9628,19 @@ module.exports = ReactChildReconciler; 'use strict'; -var PooledClass = require("./PooledClass"); -var ReactFragment = require("./ReactFragment"); +var PooledClass = require('./PooledClass'); +var ReactElement = require('./ReactElement'); -var traverseAllChildren = require("./traverseAllChildren"); -var warning = require("./warning"); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var traverseAllChildren = require('./traverseAllChildren'); var twoArgumentPooler = PooledClass.twoArgumentPooler; -var threeArgumentPooler = PooledClass.threeArgumentPooler; +var fourArgumentPooler = PooledClass.fourArgumentPooler; + +var userProvidedKeyEscapeRegex = /\/(?!\/)/g; +function escapeUserProvidedKey(text) { + return ('' + text).replace(userProvidedKeyEscapeRegex, '//'); +} /** * PooledClass representing the bookkeeping associated with performing a child @@ -8584,15 +9651,22 @@ var threeArgumentPooler = PooledClass.threeArgumentPooler; * @param {?*} forEachContext Context to perform context with. */ function ForEachBookKeeping(forEachFunction, forEachContext) { - this.forEachFunction = forEachFunction; - this.forEachContext = forEachContext; + this.func = forEachFunction; + this.context = forEachContext; + this.count = 0; } +ForEachBookKeeping.prototype.destructor = function () { + this.func = null; + this.context = null; + this.count = 0; +}; PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); -function forEachSingleChild(traverseContext, child, name, i) { - var forEachBookKeeping = traverseContext; - forEachBookKeeping.forEachFunction.call( - forEachBookKeeping.forEachContext, child, i); +function forEachSingleChild(bookKeeping, child, name) { + var func = bookKeeping.func; + var context = bookKeeping.context; + + func.call(context, child, bookKeeping.count++); } /** @@ -8602,16 +9676,14 @@ function forEachSingleChild(traverseContext, child, name, i) { * leaf child. * * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc. + * @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); + var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); traverseAllChildren(children, forEachSingleChild, traverseContext); ForEachBookKeeping.release(traverseContext); } @@ -8625,33 +9697,50 @@ function forEachChildren(children, forEachFunc, forEachContext) { * @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; +function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) { + this.result = mapResult; + this.keyPrefix = keyPrefix; + this.func = mapFunction; + this.context = mapContext; + this.count = 0; } -PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); +MapBookKeeping.prototype.destructor = function () { + this.result = null; + this.keyPrefix = null; + this.func = null; + this.context = null; + this.count = 0; +}; +PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); -function mapSingleChildIntoContext(traverseContext, child, name, i) { - var mapBookKeeping = traverseContext; - var mapResult = mapBookKeeping.mapResult; +function mapSingleChildIntoContext(bookKeeping, child, childKey) { + var result = bookKeeping.result; + var keyPrefix = bookKeeping.keyPrefix; + var func = bookKeeping.func; + var context = bookKeeping.context; - var keyUnique = !mapResult.hasOwnProperty(name); - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - keyUnique, - 'ReactChildren.map(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); + var mappedChild = func.call(context, child, bookKeeping.count++); + if (Array.isArray(mappedChild)) { + mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument); + } else if (mappedChild != null) { + if (ReactElement.isValidElement(mappedChild)) { + mappedChild = ReactElement.cloneAndReplaceKey(mappedChild, + // Keep both the (mapped) and old keys if they differ, just as + // traverseAllChildren used to do for objects as children + keyPrefix + (mappedChild !== child ? escapeUserProvidedKey(mappedChild.key || '') + '/' : '') + childKey); + } + result.push(mappedChild); } +} - if (keyUnique) { - var mappedChild = - mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); - mapResult[name] = mappedChild; +function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { + var escapedPrefix = ''; + if (prefix != null) { + escapedPrefix = escapeUserProvidedKey(prefix) + '/'; } + var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context); + traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); + MapBookKeeping.release(traverseContext); } /** @@ -8660,27 +9749,21 @@ function mapSingleChildIntoContext(traverseContext, child, name, i) { * 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. + * @param {function(*, int)} func The map function. + * @param {*} context 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); + var result = []; + mapIntoWithKeyPrefixInternal(children, result, null, func, context); + return result; } -function forEachSingleChildDummy(traverseContext, child, name, i) { +function forEachSingleChildDummy(traverseContext, child, name) { return null; } @@ -8695,17 +9778,26 @@ function countChildren(children, context) { return traverseAllChildren(children, forEachSingleChildDummy, null); } +/** + * Flatten a children object (typically specified as `props.children`) and + * return an array with appropriately re-keyed children. + */ +function toArray(children) { + var result = []; + mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument); + return result; +} + var ReactChildren = { forEach: forEachChildren, map: mapChildren, - count: countChildren + mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal, + count: countChildren, + toArray: toArray }; module.exports = ReactChildren; - -}).call(this,require('_process')) - -},{"./PooledClass":70,"./ReactFragment":109,"./traverseAllChildren":210,"./warning":212,"_process":1}],78:[function(require,module,exports){ +},{"./PooledClass":83,"./ReactElement":115,"./traverseAllChildren":201,"fbjs/lib/emptyFunction":212}],91:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -8720,23 +9812,20 @@ module.exports = ReactChildren; '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 ReactComponent = require('./ReactComponent'); +var ReactElement = require('./ReactElement'); +var ReactPropTypeLocations = require('./ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); +var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue'); -var assign = require("./Object.assign"); -var invariant = require("./invariant"); -var keyMirror = require("./keyMirror"); -var keyOf = require("./keyOf"); -var warning = require("./warning"); +var assign = require('./Object.assign'); +var emptyObject = require('fbjs/lib/emptyObject'); +var invariant = require('fbjs/lib/invariant'); +var keyMirror = require('fbjs/lib/keyMirror'); +var keyOf = require('fbjs/lib/keyOf'); +var warning = require('fbjs/lib/warning'); -var MIXINS_KEY = keyOf({mixins: null}); +var MIXINS_KEY = keyOf({ mixins: null }); /** * Policies that describe methods in `ReactClassInterface`. @@ -8763,9 +9852,16 @@ var SpecPolicy = keyMirror({ DEFINE_MANY_MERGED: null }); - var injectedMixins = []; +var warnedSetProps = false; +function warnSetProps() { + if (!warnedSetProps) { + warnedSetProps = true; + process.env.NODE_ENV !== 'production' ? warning(false, 'setProps(...) and replaceProps(...) are deprecated. ' + 'Instead, call render again at the top level.') : undefined; + } +} + /** * Composite components are higher-level components that compose other composite * or native components. @@ -8783,7 +9879,7 @@ var injectedMixins = []; * 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. + * class specification will be available on the prototype. * * @interface ReactClassInterface * @internal @@ -8885,8 +9981,6 @@ var ReactClassInterface = { */ render: SpecPolicy.DEFINE_ONCE, - - // ==== Delegate methods ==== /** @@ -8997,8 +10091,6 @@ var ReactClassInterface = { */ componentWillUnmount: SpecPolicy.DEFINE_MANY, - - // ==== Advanced methods ==== /** @@ -9025,121 +10117,72 @@ var ReactClassInterface = { * which all other static methods are defined. */ var RESERVED_SPEC_KEYS = { - displayName: function(Constructor, displayName) { + displayName: function (Constructor, displayName) { Constructor.displayName = displayName; }, - mixins: function(Constructor, mixins) { + mixins: function (Constructor, mixins) { if (mixins) { for (var i = 0; i < mixins.length; i++) { mixSpecIntoComponent(Constructor, mixins[i]); } } }, - childContextTypes: function(Constructor, childContextTypes) { - if ("production" !== process.env.NODE_ENV) { - validateTypeDef( - Constructor, - childContextTypes, - ReactPropTypeLocations.childContext - ); + childContextTypes: function (Constructor, childContextTypes) { + if (process.env.NODE_ENV !== 'production') { + validateTypeDef(Constructor, childContextTypes, ReactPropTypeLocations.childContext); } - Constructor.childContextTypes = assign( - {}, - Constructor.childContextTypes, - childContextTypes - ); + Constructor.childContextTypes = assign({}, Constructor.childContextTypes, childContextTypes); }, - contextTypes: function(Constructor, contextTypes) { - if ("production" !== process.env.NODE_ENV) { - validateTypeDef( - Constructor, - contextTypes, - ReactPropTypeLocations.context - ); + contextTypes: function (Constructor, contextTypes) { + if (process.env.NODE_ENV !== 'production') { + validateTypeDef(Constructor, contextTypes, ReactPropTypeLocations.context); } - Constructor.contextTypes = assign( - {}, - Constructor.contextTypes, - contextTypes - ); + Constructor.contextTypes = assign({}, Constructor.contextTypes, contextTypes); }, /** * Special case getDefaultProps which should move into statics but requires * automatic merging. */ - getDefaultProps: function(Constructor, getDefaultProps) { + getDefaultProps: function (Constructor, getDefaultProps) { if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction( - Constructor.getDefaultProps, - getDefaultProps - ); + Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps); } else { Constructor.getDefaultProps = getDefaultProps; } }, - propTypes: function(Constructor, propTypes) { - if ("production" !== process.env.NODE_ENV) { - validateTypeDef( - Constructor, - propTypes, - ReactPropTypeLocations.prop - ); + propTypes: function (Constructor, propTypes) { + if (process.env.NODE_ENV !== 'production') { + validateTypeDef(Constructor, propTypes, ReactPropTypeLocations.prop); } - Constructor.propTypes = assign( - {}, - Constructor.propTypes, - propTypes - ); + Constructor.propTypes = assign({}, Constructor.propTypes, propTypes); }, - statics: function(Constructor, statics) { + statics: function (Constructor, statics) { mixStaticSpecIntoComponent(Constructor, statics); - } -}; + }, + autobind: function () {} }; +// noop function validateTypeDef(Constructor, typeDef, location) { for (var propName in typeDef) { if (typeDef.hasOwnProperty(propName)) { // use a warning instead of an invariant so components // don't show up in prod but not in __DEV__ - ("production" !== process.env.NODE_ENV ? warning( - typeof typeDef[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - Constructor.displayName || 'ReactClass', - ReactPropTypeLocationNames[location], - propName - ) : null); + 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) : undefined; } } } function validateMethodOverride(proto, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? - ReactClassInterface[name] : - null; + var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null; // Disallow overriding of base class methods unless explicitly allowed. if (ReactClassMixin.hasOwnProperty(name)) { - ("production" !== process.env.NODE_ENV ? invariant( - specPolicy === SpecPolicy.OVERRIDE_BASE, - 'ReactClassInterface: You are attempting to override ' + - '`%s` from your class specification. Ensure that your method names ' + - 'do not overlap with React methods.', - name - ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); + !(specPolicy === SpecPolicy.OVERRIDE_BASE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name) : invariant(false) : undefined; } // Disallow defining methods more than once unless explicitly allowed. if (proto.hasOwnProperty(name)) { - ("production" !== process.env.NODE_ENV ? invariant( - specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED, - 'ReactClassInterface: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be due ' + - 'to a mixin.', - name - ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); + !(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name) : invariant(false) : undefined; } } @@ -9152,16 +10195,8 @@ function mixSpecIntoComponent(Constructor, spec) { return; } - ("production" !== process.env.NODE_ENV ? invariant( - typeof spec !== 'function', - 'ReactClass: You\'re attempting to ' + - 'use a component class as a mixin. Instead, just use a regular object.' - ) : invariant(typeof spec !== 'function')); - ("production" !== process.env.NODE_ENV ? invariant( - !ReactElement.isValidElement(spec), - 'ReactClass: You\'re attempting to ' + - 'use a component as a mixin. Instead, just use a regular object.' - ) : invariant(!ReactElement.isValidElement(spec))); + !(typeof spec !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.') : invariant(false) : undefined; + !!ReactElement.isValidElement(spec) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.') : invariant(false) : undefined; var proto = Constructor.prototype; @@ -9178,7 +10213,7 @@ function mixSpecIntoComponent(Constructor, spec) { } if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above + // We have already handled mixins in a special case above. continue; } @@ -9192,16 +10227,10 @@ function mixSpecIntoComponent(Constructor, spec) { // 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 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; + var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false; if (shouldAutoBind) { if (!proto.__reactAutoBindMap) { @@ -9213,18 +10242,8 @@ function mixSpecIntoComponent(Constructor, spec) { if (isAlreadyDefined) { var specPolicy = ReactClassInterface[name]; - // These cases should already be caught by validateMethodOverride - ("production" !== process.env.NODE_ENV ? invariant( - isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ), - 'ReactClass: Unexpected spec policy %s for key %s ' + - 'when mixing in component specs.', - specPolicy, - name - ) : invariant(isReactClassMethod && ( - (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) - ))); + // These cases should already be caught by validateMethodOverride. + !(isReactClassMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name) : invariant(false) : undefined; // For methods which are defined more than once, call the existing // methods before calling the new property, merging if appropriate. @@ -9235,7 +10254,7 @@ function mixSpecIntoComponent(Constructor, spec) { } } else { proto[name] = property; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // Add verbose displayName to the function, which helps when looking // at profiling tools. if (typeof property === 'function' && spec.displayName) { @@ -9258,24 +10277,11 @@ function mixStaticSpecIntoComponent(Constructor, statics) { continue; } - var isReserved = name in RESERVED_SPEC_KEYS; - ("production" !== process.env.NODE_ENV ? invariant( - !isReserved, - 'ReactClass: You are attempting to define a reserved ' + - 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + - 'as an instance property instead; it will still be accessible on the ' + - 'constructor.', - name - ) : invariant(!isReserved)); - - var isInherited = name in Constructor; - ("production" !== process.env.NODE_ENV ? invariant( - !isInherited, - 'ReactClass: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be ' + - 'due to a mixin.', - name - ) : invariant(!isInherited)); + var isReserved = (name in RESERVED_SPEC_KEYS); + !!isReserved ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define a reserved ' + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + 'as an instance property instead; it will still be accessible on the ' + 'constructor.', name) : invariant(false) : undefined; + + var isInherited = (name in Constructor); + !!isInherited ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name) : invariant(false) : undefined; Constructor[name] = property; } } @@ -9288,22 +10294,11 @@ function mixStaticSpecIntoComponent(Constructor, statics) { * @return {object} one after it has been mutated to contain everything in two. */ function mergeIntoWithNoDuplicateKeys(one, two) { - ("production" !== process.env.NODE_ENV ? invariant( - one && two && typeof one === 'object' && typeof two === 'object', - 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' - ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); + !(one && two && typeof one === 'object' && typeof two === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : invariant(false) : undefined; for (var key in two) { if (two.hasOwnProperty(key)) { - ("production" !== process.env.NODE_ENV ? invariant( - one[key] === undefined, - 'mergeIntoWithNoDuplicateKeys(): ' + - 'Tried to merge two objects with the same key: `%s`. This conflict ' + - 'may be due to a mixin; in particular, this may be caused by two ' + - 'getInitialState() or getDefaultProps() methods returning objects ' + - 'with clashing keys.', - key - ) : invariant(one[key] === undefined)); + !(one[key] === undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: `%s`. This conflict ' + 'may be due to a mixin; in particular, this may be caused by two ' + 'getInitialState() or getDefaultProps() methods returning objects ' + 'with clashing keys.', key) : invariant(false) : undefined; one[key] = two[key]; } } @@ -9358,32 +10353,25 @@ function createChainedFunction(one, two) { */ function bindAutoBindMethod(component, method) { var boundMethod = method.bind(component); - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { 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]); + boundMethod.bind = function (newThis) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + // User is trying to bind() an autobound method; we effectively will // ignore the value of "this" that the user is trying to use, so // let's warn. if (newThis !== component && newThis !== null) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'bind(): React component methods may only be bound to the ' + - 'component instance. See %s', - componentName - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : undefined; } else if (!args.length) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'bind(): You are binding a component method to the component. ' + - 'React does this for you automatically in a high-performance ' + - 'way, so you can safely remove this call. See %s', - componentName - ) : null); + process.env.NODE_ENV !== 'production' ? 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) : undefined; return boundMethod; } var reboundMethod = _bind.apply(boundMethod, arguments); @@ -9406,34 +10394,11 @@ 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 - ) - ); + component[autoBindKey] = bindAutoBindMethod(component, method); } } } -var typeDeprecationDescriptor = { - enumerable: false, - get: function() { - var displayName = this.displayName || this.name || 'Component'; - ("production" !== process.env.NODE_ENV ? warning( - false, - '%s.type is deprecated. Use %s directly to access the class.', - displayName, - displayName - ) : null); - Object.defineProperty(this, 'type', { - value: this - }); - return this; - } -}; - /** * Add more to the ReactClass base class. These are all legacy features and * therefore not already part of the modern ReactComponent. @@ -9444,10 +10409,10 @@ 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); + replaceState: function (newState, callback) { + this.updater.enqueueReplaceState(this, newState); if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); + this.updater.enqueueCallback(this, callback); } }, @@ -9457,27 +10422,8 @@ var ReactClassMixin = { * @protected * @final */ - isMounted: function() { - if ("production" !== process.env.NODE_ENV) { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - ("production" !== process.env.NODE_ENV ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing isMounted inside its render() function. ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(this); - return ( - internalInstance && - internalInstance !== ReactLifeCycle.currentlyMountingInstance - ); + isMounted: function () { + return this.updater.isMounted(this); }, /** @@ -9489,10 +10435,13 @@ var ReactClassMixin = { * @public * @deprecated */ - setProps: function(partialProps, callback) { - ReactUpdateQueue.enqueueSetProps(this, partialProps); + setProps: function (partialProps, callback) { + if (process.env.NODE_ENV !== 'production') { + warnSetProps(); + } + this.updater.enqueueSetProps(this, partialProps); if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); + this.updater.enqueueCallback(this, callback); } }, @@ -9505,20 +10454,19 @@ var ReactClassMixin = { * @public * @deprecated */ - replaceProps: function(newProps, callback) { - ReactUpdateQueue.enqueueReplaceProps(this, newProps); + replaceProps: function (newProps, callback) { + if (process.env.NODE_ENV !== 'production') { + warnSetProps(); + } + this.updater.enqueueReplaceProps(this, newProps); if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); + this.updater.enqueueCallback(this, callback); } } }; -var ReactClassComponent = function() {}; -assign( - ReactClassComponent.prototype, - ReactComponent.prototype, - ReactClassMixin -); +var ReactClassComponent = function () {}; +assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin); /** * Module for creating composite components. @@ -9534,17 +10482,13 @@ var ReactClass = { * @return {function} Component constructor function. * @public */ - createClass: function(spec) { - var Constructor = function(props, context) { + createClass: function (spec) { + var Constructor = function (props, context, updater) { // This constructor is overridden by mocks. The argument is used // by mocks to assert on what gets mounted. - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - this instanceof Constructor, - 'Something is calling a React component directly. Use a factory or ' + - 'JSX instead. See: https://fb.me/react-legacyfactory' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : undefined; } // Wire up auto-binding @@ -9554,44 +10498,40 @@ var ReactClass = { this.props = props; this.context = context; + this.refs = emptyObject; + this.updater = updater || ReactNoopUpdateQueue; + this.state = null; // ReactClasses doesn't have constructors. Instead, they use the // getInitialState and componentWillMount methods for initialization. var initialState = this.getInitialState ? this.getInitialState() : null; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // We allow auto-mocks to proceed as if they're returning null. - if (typeof initialState === 'undefined' && - this.getInitialState._isMockFunction) { + if (typeof initialState === 'undefined' && this.getInitialState._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. initialState = null; } } - ("production" !== process.env.NODE_ENV ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.getInitialState(): must return an object or null', - Constructor.displayName || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : invariant(false) : undefined; this.state = initialState; }; Constructor.prototype = new ReactClassComponent(); Constructor.prototype.constructor = Constructor; - injectedMixins.forEach( - mixSpecIntoComponent.bind(null, Constructor) - ); + injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); mixSpecIntoComponent(Constructor, spec); - // Initialize the defaultProps property after all mixins have been merged + // Initialize the defaultProps property after all mixins have been merged. if (Constructor.getDefaultProps) { Constructor.defaultProps = Constructor.getDefaultProps(); } - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // 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 @@ -9604,20 +10544,11 @@ var ReactClass = { } } - ("production" !== process.env.NODE_ENV ? invariant( - Constructor.prototype.render, - 'createClass(...): Class specification must implement a `render` method.' - ) : invariant(Constructor.prototype.render)); + !Constructor.prototype.render ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : invariant(false) : undefined; - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - !Constructor.prototype.componentShouldUpdate, - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - spec.displayName || 'A component' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? 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') : undefined; + process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : undefined; } // Reduce time spent doing lookups by setting these on the prototype. @@ -9627,21 +10558,11 @@ var ReactClass = { } } - // Legacy hook - Constructor.type = Constructor; - if ("production" !== process.env.NODE_ENV) { - try { - Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - return Constructor; }, injection: { - injectMixin: function(mixin) { + injectMixin: function (mixin) { injectedMixins.push(mixin); } } @@ -9649,10 +10570,9 @@ var ReactClass = { }; module.exports = ReactClass; - }).call(this,require('_process')) -},{"./Object.assign":69,"./ReactComponent":79,"./ReactCurrentOwner":85,"./ReactElement":103,"./ReactErrorUtils":106,"./ReactInstanceMap":113,"./ReactLifeCycle":114,"./ReactPropTypeLocationNames":124,"./ReactPropTypeLocations":125,"./ReactUpdateQueue":139,"./invariant":191,"./keyMirror":197,"./keyOf":198,"./warning":212,"_process":1}],79:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactComponent":92,"./ReactElement":115,"./ReactNoopUpdateQueue":134,"./ReactPropTypeLocationNames":138,"./ReactPropTypeLocations":139,"_process":1,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220,"fbjs/lib/keyMirror":224,"fbjs/lib/keyOf":225,"fbjs/lib/warning":232}],92:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -9667,19 +10587,27 @@ module.exports = ReactClass; 'use strict'; -var ReactUpdateQueue = require("./ReactUpdateQueue"); +var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue'); -var invariant = require("./invariant"); -var warning = require("./warning"); +var canDefineProperty = require('./canDefineProperty'); +var emptyObject = require('fbjs/lib/emptyObject'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); /** * Base class helpers for the updating state of a component. */ -function ReactComponent(props, context) { +function ReactComponent(props, context, updater) { this.props = props; this.context = context; + this.refs = emptyObject; + // We initialize the default updater but the real one gets injected by the + // renderer. + this.updater = updater || ReactNoopUpdateQueue; } +ReactComponent.prototype.isReactComponent = {}; + /** * Sets a subset of the state. Always use this to mutate * state. You should treat `this.state` as immutable. @@ -9705,26 +10633,14 @@ function ReactComponent(props, context) { * @final * @protected */ -ReactComponent.prototype.setState = function(partialState, callback) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null, - 'setState(...): takes an object of state variables to update or a ' + - 'function which returns an object of state variables.' - ) : invariant(typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null)); - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - partialState != null, - 'setState(...): You passed an undefined or null state object; ' + - 'instead, use forceUpdate().' - ) : null); - } - ReactUpdateQueue.enqueueSetState(this, partialState); +ReactComponent.prototype.setState = function (partialState, callback) { + !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.') : invariant(false) : undefined; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : undefined; + } + this.updater.enqueueSetState(this, partialState); if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); + this.updater.enqueueCallback(this, callback); } }; @@ -9742,10 +10658,10 @@ ReactComponent.prototype.setState = function(partialState, callback) { * @final * @protected */ -ReactComponent.prototype.forceUpdate = function(callback) { - ReactUpdateQueue.enqueueForceUpdate(this); +ReactComponent.prototype.forceUpdate = function (callback) { + this.updater.enqueueForceUpdate(this); if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); + this.updater.enqueueCallback(this, callback); } }; @@ -9754,46 +10670,22 @@ ReactComponent.prototype.forceUpdate = function(callback) { * we would like to deprecate them, we're not going to move them over to this * modern base class. Instead, we define a getter that warns if it's accessed. */ -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { var deprecatedAPIs = { - getDOMNode: [ - 'getDOMNode', - 'Use React.findDOMNode(component) instead.' - ], - isMounted: [ - 'isMounted', - 'Instead, make sure to clean up subscriptions and pending requests in ' + - 'componentWillUnmount to prevent memory leaks.' - ], - replaceProps: [ - 'replaceProps', - 'Instead, call React.render again at the top level.' - ], - replaceState: [ - 'replaceState', - 'Refactor your code to use setState instead (see ' + - 'https://github.com/facebook/react/issues/3236).' - ], - setProps: [ - 'setProps', - 'Instead, call React.render again at the top level.' - ] + getDOMNode: ['getDOMNode', 'Use ReactDOM.findDOMNode(component) instead.'], + isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'], + replaceProps: ['replaceProps', 'Instead, call render again at the top level.'], + replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'], + setProps: ['setProps', 'Instead, call render again at the top level.'] }; - var defineDeprecationWarning = function(methodName, info) { - try { + var defineDeprecationWarning = function (methodName, info) { + if (canDefineProperty) { Object.defineProperty(ReactComponent.prototype, methodName, { - get: function() { - ("production" !== process.env.NODE_ENV ? warning( - false, - '%s(...) is deprecated in plain JavaScript React classes. %s', - info[0], - info[1] - ) : null); + get: function () { + process.env.NODE_ENV !== 'production' ? warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]) : undefined; return undefined; } }); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) } }; for (var fnName in deprecatedAPIs) { @@ -9804,10 +10696,9 @@ if ("production" !== process.env.NODE_ENV) { } module.exports = ReactComponent; - }).call(this,require('_process')) -},{"./ReactUpdateQueue":139,"./invariant":191,"./warning":212,"_process":1}],80:[function(require,module,exports){ +},{"./ReactNoopUpdateQueue":134,"./canDefineProperty":176,"_process":1,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],93:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -9819,12 +10710,10 @@ module.exports = ReactComponent; * @providesModule ReactComponentBrowserEnvironment */ -/*jslint evil: true */ - 'use strict'; -var ReactDOMIDOperations = require("./ReactDOMIDOperations"); -var ReactMount = require("./ReactMount"); +var ReactDOMIDOperations = require('./ReactDOMIDOperations'); +var ReactMount = require('./ReactMount'); /** * Abstracts away all functionality of the reconciler that requires knowledge of @@ -9833,11 +10722,9 @@ var ReactMount = require("./ReactMount"); */ var ReactComponentBrowserEnvironment = { - processChildrenUpdates: - ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, + processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, - replaceNodeWithMarkupByID: - ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, + replaceNodeWithMarkupByID: ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, /** * If a particular environment requires that some resources be cleaned up, @@ -9846,15 +10733,14 @@ var ReactComponentBrowserEnvironment = { * * @private */ - unmountIDFromEnvironment: function(rootNodeID) { + unmountIDFromEnvironment: function (rootNodeID) { ReactMount.purgeID(rootNodeID); } }; module.exports = ReactComponentBrowserEnvironment; - -},{"./ReactDOMIDOperations":90,"./ReactMount":117}],81:[function(require,module,exports){ +},{"./ReactDOMIDOperations":103,"./ReactMount":130}],94:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -9869,7 +10755,7 @@ module.exports = ReactComponentBrowserEnvironment; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); var injected = false; @@ -9895,17 +10781,11 @@ var ReactComponentEnvironment = { processChildrenUpdates: null, injection: { - injectEnvironment: function(environment) { - ("production" !== process.env.NODE_ENV ? invariant( - !injected, - 'ReactCompositeComponent: injectEnvironment() can only be called once.' - ) : invariant(!injected)); - ReactComponentEnvironment.unmountIDFromEnvironment = - environment.unmountIDFromEnvironment; - ReactComponentEnvironment.replaceNodeWithMarkupByID = - environment.replaceNodeWithMarkupByID; - ReactComponentEnvironment.processChildrenUpdates = - environment.processChildrenUpdates; + injectEnvironment: function (environment) { + !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : invariant(false) : undefined; + ReactComponentEnvironment.unmountIDFromEnvironment = environment.unmountIDFromEnvironment; + ReactComponentEnvironment.replaceNodeWithMarkupByID = environment.replaceNodeWithMarkupByID; + ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates; injected = true; } } @@ -9913,10 +10793,9 @@ var ReactComponentEnvironment = { }; module.exports = ReactComponentEnvironment; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],82:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],95:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -9925,12 +10804,12 @@ module.exports = ReactComponentEnvironment; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * -* @providesModule ReactComponentWithPureRenderMixin -*/ + * @providesModule ReactComponentWithPureRenderMixin + */ 'use strict'; -var shallowEqual = require("./shallowEqual"); +var shallowCompare = require('./shallowCompare'); /** * If your React component's render function is "pure", e.g. it will render the @@ -9957,15 +10836,13 @@ var shallowEqual = require("./shallowEqual"); * use `forceUpdate()` when you know deep data structures have changed. */ var ReactComponentWithPureRenderMixin = { - shouldComponentUpdate: function(nextProps, nextState) { - return !shallowEqual(this.props, nextProps) || - !shallowEqual(this.state, nextState); + shouldComponentUpdate: function (nextProps, nextState) { + return shallowCompare(this, nextProps, nextState); } }; module.exports = ReactComponentWithPureRenderMixin; - -},{"./shallowEqual":207}],83:[function(require,module,exports){ +},{"./shallowCompare":199}],96:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -9980,25 +10857,21 @@ module.exports = ReactComponentWithPureRenderMixin; '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"); +var ReactComponentEnvironment = require('./ReactComponentEnvironment'); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactElement = require('./ReactElement'); +var ReactInstanceMap = require('./ReactInstanceMap'); +var ReactPerf = require('./ReactPerf'); +var ReactPropTypeLocations = require('./ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); +var ReactReconciler = require('./ReactReconciler'); +var ReactUpdateQueue = require('./ReactUpdateQueue'); + +var assign = require('./Object.assign'); +var emptyObject = require('fbjs/lib/emptyObject'); +var invariant = require('fbjs/lib/invariant'); +var shouldUpdateReactComponent = require('./shouldUpdateReactComponent'); +var warning = require('fbjs/lib/warning'); function getDeclarationErrorAddendum(component) { var owner = component._currentElement._owner || null; @@ -10011,6 +10884,12 @@ function getDeclarationErrorAddendum(component) { return ''; } +function StatelessComponent(Component) {} +StatelessComponent.prototype.render = function () { + var Component = ReactInstanceMap.get(this)._currentElement.type; + return Component(this.props, this.context, this.updater); +}; + /** * ------------------ The Life-Cycle of a Composite Component ------------------ * @@ -10058,7 +10937,7 @@ var ReactCompositeComponentMixin = { * @final * @internal */ - construct: function(element) { + construct: function (element) { this._currentElement = element; this._rootNodeID = null; this._instance = null; @@ -10073,7 +10952,7 @@ var ReactCompositeComponentMixin = { this._context = null; this._mountOrder = 0; - this._isTopLevel = false; + this._topLevelWrapper = null; // See ReactUpdates and ReactUpdateQueue. this._pendingCallbacks = null; @@ -10088,32 +10967,54 @@ var ReactCompositeComponentMixin = { * @final * @internal */ - mountComponent: function(rootID, transaction, context) { + 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 publicContext = this._processContext(context); - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); + var Component = this._currentElement.type; // Initialize the public class - var inst = new Component(publicProps, publicContext); + var inst; + var renderedElement; + + // This is a way to detect if Component is a stateless arrow function + // component, which is not newable. It might not be 100% reliable but is + // something we can do until we start detecting that Component extends + // React.Component. We already assume that typeof Component === 'function'. + var canInstantiate = ('prototype' in Component); + + if (canInstantiate) { + if (process.env.NODE_ENV !== 'production') { + ReactCurrentOwner.current = this; + try { + inst = new Component(publicProps, publicContext, ReactUpdateQueue); + } finally { + ReactCurrentOwner.current = null; + } + } else { + inst = new Component(publicProps, publicContext, ReactUpdateQueue); + } + } + + if (!canInstantiate || inst === null || inst === false || ReactElement.isValidElement(inst)) { + renderedElement = inst; + inst = new StatelessComponent(Component); + } - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // This will throw later in _renderValidatedComponent, but add an early // warning now to help debugging - ("production" !== process.env.NODE_ENV ? warning( - inst.render != null, - '%s(...): No `render` method found on the returned component ' + - 'instance: you may have forgotten to define `render` in your ' + - 'component or you may have accidentally tried to render an element ' + - 'whose type is a function that isn\'t a React component.', - Component.displayName || Component.name || 'Component' - ) : null); + if (inst.render == null) { + process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`, returned ' + 'null/false from a stateless component, or tried to render an ' + 'element whose type is a function that isn\'t a React component.', Component.displayName || Component.name || 'Component') : undefined; + } else { + // We support ES6 inheriting from React.Component, the module pattern, + // and stateless components, but not ES6 classes that don't extend + process.env.NODE_ENV !== 'production' ? warning(Component.prototype && Component.prototype.isReactComponent || !canInstantiate || !(inst instanceof Component), '%s(...): React component classes must extend React.Component.', Component.displayName || Component.name || 'Component') : undefined; + } } // These should be set up in the constructor, but as a convenience for @@ -10121,104 +11022,53 @@ var ReactCompositeComponentMixin = { inst.props = publicProps; inst.context = publicContext; inst.refs = emptyObject; + inst.updater = ReactUpdateQueue; this._instance = inst; // Store a reference from the instance back to the internal representation ReactInstanceMap.set(inst, this); - if ("production" !== process.env.NODE_ENV) { - this._warnIfContextsDiffer(this._currentElement._context, context); - } - - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // Since plain JS classes are defined without any special initialization // logic, we can not catch common errors early. Therefore, we have to // catch them here, at initialization time, instead. - ("production" !== process.env.NODE_ENV ? warning( - !inst.getInitialState || - inst.getInitialState.isReactClassApproved, - 'getInitialState was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Did you mean to define a state property instead?', - this.getName() || 'a component' - ) : null); - ("production" !== process.env.NODE_ENV ? warning( - !inst.getDefaultProps || - inst.getDefaultProps.isReactClassApproved, - 'getDefaultProps was defined on %s, a plain JavaScript class. ' + - 'This is only supported for classes created using React.createClass. ' + - 'Use a static property to define defaultProps instead.', - this.getName() || 'a component' - ) : null); - ("production" !== process.env.NODE_ENV ? warning( - !inst.propTypes, - 'propTypes was defined as an instance property on %s. Use a static ' + - 'property to define propTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== process.env.NODE_ENV ? warning( - !inst.contextTypes, - 'contextTypes was defined as an instance property on %s. Use a ' + - 'static property to define contextTypes instead.', - this.getName() || 'a component' - ) : null); - ("production" !== process.env.NODE_ENV ? warning( - typeof inst.componentShouldUpdate !== 'function', - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - (this.getName() || 'A component') - ) : null); + process.env.NODE_ENV !== 'production' ? 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') : undefined; + process.env.NODE_ENV !== 'production' ? 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') : undefined; + process.env.NODE_ENV !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : undefined; + process.env.NODE_ENV !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : undefined; + process.env.NODE_ENV !== 'production' ? 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') : undefined; + process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : undefined; + process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : undefined; } var initialState = inst.state; if (initialState === undefined) { inst.state = initialState = null; } - ("production" !== process.env.NODE_ENV ? invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.state: must be set to an object or null', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined; this._pendingStateQueue = null; this._pendingReplaceState = false; this._pendingForceUpdate = false; - var childContext; - var renderedElement; - - var previouslyMounting = ReactLifeCycle.currentlyMountingInstance; - ReactLifeCycle.currentlyMountingInstance = this; - try { - if (inst.componentWillMount) { - inst.componentWillMount(); - // When mounting, calls to `setState` by `componentWillMount` will set - // `this._pendingStateQueue` without triggering a re-render. - if (this._pendingStateQueue) { - inst.state = this._processPendingState(inst.props, inst.context); - } + if (inst.componentWillMount) { + inst.componentWillMount(); + // When mounting, calls to `setState` by `componentWillMount` will set + // `this._pendingStateQueue` without triggering a re-render. + if (this._pendingStateQueue) { + inst.state = this._processPendingState(inst.props, inst.context); } + } - childContext = this._getValidatedChildContext(context); - renderedElement = this._renderValidatedComponent(childContext); - } finally { - ReactLifeCycle.currentlyMountingInstance = previouslyMounting; + // If not a stateless component, we now render + if (renderedElement === undefined) { + renderedElement = this._renderValidatedComponent(); } - this._renderedComponent = this._instantiateReactComponent( - renderedElement, - this._currentElement.type // The wrapping type - ); + this._renderedComponent = this._instantiateReactComponent(renderedElement); - var markup = ReactReconciler.mountComponent( - this._renderedComponent, - rootID, - transaction, - this._mergeChildContext(context, childContext) - ); + var markup = ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, this._processChildContext(context)); if (inst.componentDidMount) { transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); } @@ -10232,23 +11082,20 @@ var ReactCompositeComponentMixin = { * @final * @internal */ - unmountComponent: function() { + unmountComponent: function () { var inst = this._instance; if (inst.componentWillUnmount) { - var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; - ReactLifeCycle.currentlyUnmountingInstance = this; - try { - inst.componentWillUnmount(); - } finally { - ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; - } + inst.componentWillUnmount(); } ReactReconciler.unmountComponent(this._renderedComponent); this._renderedComponent = null; + this._instance = null; // Reset pending fields + // Even if this component is scheduled for another update in ReactUpdates, + // it would still be ignored because these fields are reset. this._pendingStateQueue = null; this._pendingReplaceState = false; this._pendingForceUpdate = false; @@ -10259,6 +11106,7 @@ var ReactCompositeComponentMixin = { // longer accessible. this._context = null; this._rootNodeID = null; + this._topLevelWrapper = null; // Delete the reference from the instance to this internal representation // which allow the internals to be properly cleaned up even if the user @@ -10273,25 +11121,6 @@ var ReactCompositeComponentMixin = { }, /** - * 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` * @@ -10299,14 +11128,10 @@ var ReactCompositeComponentMixin = { * @return {?object} * @private */ - _maskContext: function(context) { + _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; + var Component = this._currentElement.type; + var contextTypes = Component.contextTypes; if (!contextTypes) { return emptyObject; } @@ -10325,18 +11150,12 @@ var ReactCompositeComponentMixin = { * @return {?object} * @private */ - _processContext: function(context) { + _processContext: function (context) { var maskedContext = this._maskContext(context); - if ("production" !== process.env.NODE_ENV) { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); + if (process.env.NODE_ENV !== 'production') { + var Component = this._currentElement.type; if (Component.contextTypes) { - this._checkPropTypes( - Component.contextTypes, - maskedContext, - ReactPropTypeLocations.context - ); + this._checkPropTypes(Component.contextTypes, maskedContext, ReactPropTypeLocations.context); } } return maskedContext; @@ -10347,38 +11166,18 @@ var ReactCompositeComponentMixin = { * @return {object} * @private */ - _getValidatedChildContext: function(currentContext) { + _processChildContext: function (currentContext) { + var Component = this._currentElement.type; var inst = this._instance; var childContext = inst.getChildContext && inst.getChildContext(); if (childContext) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof inst.constructor.childContextTypes === 'object', - '%s.getChildContext(): childContextTypes must be defined in order to ' + - 'use getChildContext().', - this.getName() || 'ReactCompositeComponent' - ) : invariant(typeof inst.constructor.childContextTypes === 'object')); - if ("production" !== process.env.NODE_ENV) { - this._checkPropTypes( - inst.constructor.childContextTypes, - childContext, - ReactPropTypeLocations.childContext - ); + !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined; + if (process.env.NODE_ENV !== 'production') { + this._checkPropTypes(Component.childContextTypes, childContext, ReactPropTypeLocations.childContext); } for (var name in childContext) { - ("production" !== process.env.NODE_ENV ? invariant( - name in inst.constructor.childContextTypes, - '%s.getChildContext(): key "%s" is not defined in childContextTypes.', - this.getName() || 'ReactCompositeComponent', - name - ) : invariant(name in inst.constructor.childContextTypes)); + !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : invariant(false) : undefined; } - return childContext; - } - return null; - }, - - _mergeChildContext: function(currentContext, childContext) { - if (childContext) { return assign({}, currentContext, childContext); } return currentContext; @@ -10393,17 +11192,11 @@ var ReactCompositeComponentMixin = { * @return {object} * @private */ - _processProps: function(newProps) { - if ("production" !== process.env.NODE_ENV) { - var Component = ReactNativeComponent.getComponentClassForElement( - this._currentElement - ); + _processProps: function (newProps) { + if (process.env.NODE_ENV !== 'production') { + var Component = this._currentElement.type; if (Component.propTypes) { - this._checkPropTypes( - Component.propTypes, - newProps, - ReactPropTypeLocations.prop - ); + this._checkPropTypes(Component.propTypes, newProps, ReactPropTypeLocations.prop); } } return newProps; @@ -10417,7 +11210,7 @@ var ReactCompositeComponentMixin = { * @param {string} location e.g. "prop", "context", "child context" * @private */ - _checkPropTypes: function(propTypes, props, location) { + _checkPropTypes: function (propTypes, props, location) { // TODO: Stop validating prop types here and only use the element // validation. var componentName = this.getName(); @@ -10427,58 +11220,35 @@ var ReactCompositeComponentMixin = { try { // This is intentionally an invariant that gets caught. It's the same // behavior as without this statement except with a better message. - ("production" !== process.env.NODE_ENV ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually ' + - 'from React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); + !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually ' + 'from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined; 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 + // top-level render calls, so I'm abstracting it away into // a function to minimize refactoring in the future var addendum = getDeclarationErrorAddendum(this); if (location === ReactPropTypeLocations.prop) { // Preface gives us something to blacklist in warning module - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Failed Composite propType: %s%s', - error.message, - addendum - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Composite propType: %s%s', error.message, addendum) : undefined; } else { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Failed Context Types: %s%s', - error.message, - addendum - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Context Types: %s%s', error.message, addendum) : undefined; } } } } }, - receiveComponent: function(nextElement, transaction, nextContext) { + receiveComponent: function (nextElement, transaction, nextContext) { var prevElement = this._currentElement; var prevContext = this._context; this._pendingElement = null; - this.updateComponent( - transaction, - prevElement, - nextElement, - prevContext, - nextContext - ); + this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext); }, /** @@ -10488,54 +11258,13 @@ var ReactCompositeComponentMixin = { * @param {ReactReconcileTransaction} transaction * @internal */ - performUpdateIfNecessary: function(transaction) { + performUpdateIfNecessary: function (transaction) { if (this._pendingElement != null) { - ReactReconciler.receiveComponent( - this, - this._pendingElement || this._currentElement, - transaction, - this._context - ); + ReactReconciler.receiveComponent(this, this._pendingElement || this._currentElement, transaction, this._context); } if (this._pendingStateQueue !== null || this._pendingForceUpdate) { - if ("production" !== process.env.NODE_ENV) { - ReactElementValidator.checkAndWarnForMutatedProps( - this._currentElement - ); - } - - this.updateComponent( - transaction, - this._currentElement, - this._currentElement, - this._context, - this._context - ); - } - }, - - /** - * Compare two contexts, warning if they are different - * TODO: Remove this check when owner-context is removed - */ - _warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) { - ownerBasedContext = this._maskContext(ownerBasedContext); - parentBasedContext = this._maskContext(parentBasedContext); - var parentKeys = Object.keys(parentBasedContext).sort(); - var displayName = this.getName() || 'ReactCompositeComponent'; - for (var i = 0; i < parentKeys.length; i++) { - var key = parentKeys[i]; - ("production" !== process.env.NODE_ENV ? warning( - ownerBasedContext[key] === parentBasedContext[key], - 'owner-based and parent-based contexts differ ' + - '(values: `%s` vs `%s`) for key (%s) while mounting %s ' + - '(see: http://fb.me/react-context-by-parent)', - ownerBasedContext[key], - parentBasedContext[key], - key, - displayName - ) : null); + this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context); } }, @@ -10554,32 +11283,19 @@ var ReactCompositeComponentMixin = { * @internal * @overridable */ - updateComponent: function( - transaction, - prevParentElement, - nextParentElement, - prevUnmaskedContext, - nextUnmaskedContext - ) { + updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) { var inst = this._instance; - var nextContext = inst.context; - var nextProps = inst.props; + var nextContext = this._context === nextUnmaskedContext ? inst.context : this._processContext(nextUnmaskedContext); + var nextProps; // Distinguish between a props update versus a simple state update - if (prevParentElement !== nextParentElement) { - nextContext = this._processContext(nextParentElement._context); + if (prevParentElement === nextParentElement) { + // Skip checking prop types again -- we don't read inst.props to avoid + // warning for DOM component props in this upgrade + nextProps = nextParentElement.props; + } else { nextProps = this._processProps(nextParentElement.props); - - if ("production" !== process.env.NODE_ENV) { - if (nextUnmaskedContext != null) { - this._warnIfContextsDiffer( - nextParentElement._context, - nextUnmaskedContext - ); - } - } - // An update here will schedule an update but immediately set // _pendingStateQueue which will ensure that any state updates gets // immediately reconciled instead of waiting for the next batch. @@ -10591,31 +11307,16 @@ var ReactCompositeComponentMixin = { var nextState = this._processPendingState(nextProps, nextContext); - var shouldUpdate = - this._pendingForceUpdate || - !inst.shouldComponentUpdate || - inst.shouldComponentUpdate(nextProps, nextState, nextContext); + var shouldUpdate = this._pendingForceUpdate || !inst.shouldComponentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext); - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - typeof shouldUpdate !== 'undefined', - '%s.shouldComponentUpdate(): Returned undefined instead of a ' + - 'boolean value. Make sure to return true or false.', - this.getName() || 'ReactCompositeComponent' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(typeof shouldUpdate !== 'undefined', '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : undefined; } if (shouldUpdate) { this._pendingForceUpdate = false; // Will set `this.props`, `this.state` and `this.context`. - this._performComponentUpdate( - nextParentElement, - nextProps, - nextState, - nextContext, - transaction, - nextUnmaskedContext - ); + 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. @@ -10627,7 +11328,7 @@ var ReactCompositeComponentMixin = { } }, - _processPendingState: function(props, context) { + _processPendingState: function (props, context) { var inst = this._instance; var queue = this._pendingStateQueue; var replace = this._pendingReplaceState; @@ -10645,12 +11346,7 @@ var ReactCompositeComponentMixin = { 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 - ); + assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial); } return nextState; @@ -10668,19 +11364,18 @@ var ReactCompositeComponentMixin = { * @param {?object} unmaskedContext * @private */ - _performComponentUpdate: function( - nextElement, - nextProps, - nextState, - nextContext, - transaction, - unmaskedContext - ) { + _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) { var inst = this._instance; - var prevProps = inst.props; - var prevState = inst.state; - var prevContext = inst.context; + var hasComponentDidUpdate = Boolean(inst.componentDidUpdate); + var prevProps; + var prevState; + var prevContext; + if (hasComponentDidUpdate) { + prevProps = inst.props; + prevState = inst.state; + prevContext = inst.context; + } if (inst.componentWillUpdate) { inst.componentWillUpdate(nextProps, nextState, nextContext); @@ -10694,11 +11389,8 @@ var ReactCompositeComponentMixin = { this._updateRenderedComponent(transaction, unmaskedContext); - if (inst.componentDidUpdate) { - transaction.getReactMountReady().enqueue( - inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), - inst - ); + if (hasComponentDidUpdate) { + transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); } }, @@ -10708,34 +11400,20 @@ var ReactCompositeComponentMixin = { * @param {ReactReconcileTransaction} transaction * @internal */ - _updateRenderedComponent: function(transaction, context) { + _updateRenderedComponent: function (transaction, context) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; - var childContext = this._getValidatedChildContext(); - var nextRenderedElement = this._renderValidatedComponent(childContext); + var nextRenderedElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { - ReactReconciler.receiveComponent( - prevComponentInstance, - nextRenderedElement, - transaction, - this._mergeChildContext(context, childContext) - ); + 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._mergeChildContext(context, childContext) - ); + this._renderedComponent = this._instantiateReactComponent(nextRenderedElement); + var nextMarkup = ReactReconciler.mountComponent(this._renderedComponent, thisID, transaction, this._processChildContext(context)); this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); } }, @@ -10743,23 +11421,19 @@ var ReactCompositeComponentMixin = { /** * @protected */ - _replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) { - ReactComponentEnvironment.replaceNodeWithMarkupByID( - prevComponentID, - nextMarkup - ); + _replaceNodeWithMarkupByID: function (prevComponentID, nextMarkup) { + ReactComponentEnvironment.replaceNodeWithMarkupByID(prevComponentID, nextMarkup); }, /** * @protected */ - _renderValidatedComponentWithoutOwnerOrContext: function() { + _renderValidatedComponentWithoutOwnerOrContext: function () { var inst = this._instance; var renderedComponent = inst.render(); - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // We allow auto-mocks to proceed as if they're returning null. - if (typeof renderedComponent === 'undefined' && - inst.render._isMockFunction) { + if (typeof renderedComponent === 'undefined' && inst.render._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. renderedComponent = null; @@ -10772,31 +11446,17 @@ var ReactCompositeComponentMixin = { /** * @private */ - _renderValidatedComponent: function(childContext) { + _renderValidatedComponent: function () { var renderedComponent; - var previousContext = ReactContext.current; - ReactContext.current = this._mergeChildContext( - this._currentElement._context, - childContext - ); ReactCurrentOwner.current = this; try { - renderedComponent = - this._renderValidatedComponentWithoutOwnerOrContext(); + renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); } finally { - ReactContext.current = previousContext; ReactCurrentOwner.current = null; } - ("production" !== process.env.NODE_ENV ? invariant( - // TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent), - '%s.render(): A valid ReactComponent must be returned. You may have ' + - 'returned undefined, an array or some other invalid object.', - this.getName() || 'ReactCompositeComponent' - ) : invariant(// TODO: An `isValidNode` function would probably be more appropriate - renderedComponent === null || renderedComponent === false || - ReactElement.isValidElement(renderedComponent))); + !( + // TODO: An `isValidNode` function would probably be more appropriate + renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined; return renderedComponent; }, @@ -10808,10 +11468,16 @@ var ReactCompositeComponentMixin = { * @final * @private */ - attachRef: function(ref, component) { + attachRef: function (ref, component) { var inst = this.getPublicInstance(); - var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs; - refs[ref] = component.getPublicInstance(); + !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : invariant(false) : undefined; + var publicComponentInstance = component.getPublicInstance(); + if (process.env.NODE_ENV !== 'production') { + var componentName = component && component.getName ? component.getName() : 'a component'; + process.env.NODE_ENV !== 'production' ? warning(publicComponentInstance != null, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : undefined; + } + var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs; + refs[ref] = publicComponentInstance; }, /** @@ -10821,7 +11487,7 @@ var ReactCompositeComponentMixin = { * @final * @private */ - detachRef: function(ref) { + detachRef: function (ref) { var refs = this.getPublicInstance().refs; delete refs[ref]; }, @@ -10832,26 +11498,26 @@ var ReactCompositeComponentMixin = { * @return {string} The name or null. * @internal */ - getName: function() { + 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 - ); + 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 + * is exposed by refs and returned by render. Can be null for stateless * components. * * @return {ReactComponent} the public component instance. * @internal */ - getPublicInstance: function() { - return this._instance; + getPublicInstance: function () { + var inst = this._instance; + if (inst instanceof StatelessComponent) { + return null; + } + return inst; }, // Stub @@ -10859,15 +11525,11 @@ var ReactCompositeComponentMixin = { }; -ReactPerf.measureMethods( - ReactCompositeComponentMixin, - 'ReactCompositeComponent', - { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent', - _renderValidatedComponent: '_renderValidatedComponent' - } -); +ReactPerf.measureMethods(ReactCompositeComponentMixin, 'ReactCompositeComponent', { + mountComponent: 'mountComponent', + updateComponent: 'updateComponent', + _renderValidatedComponent: '_renderValidatedComponent' +}); var ReactCompositeComponent = { @@ -10876,89 +11538,9 @@ var ReactCompositeComponent = { }; module.exports = ReactCompositeComponent; - -}).call(this,require('_process')) - -},{"./Object.assign":69,"./ReactComponentEnvironment":81,"./ReactContext":84,"./ReactCurrentOwner":85,"./ReactElement":103,"./ReactElementValidator":104,"./ReactInstanceMap":113,"./ReactLifeCycle":114,"./ReactNativeComponent":120,"./ReactPerf":122,"./ReactPropTypeLocationNames":124,"./ReactPropTypeLocations":125,"./ReactReconciler":129,"./ReactUpdates":140,"./emptyObject":171,"./invariant":191,"./shouldUpdateReactComponent":208,"./warning":212,"_process":1}],84:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactContext - */ - -'use strict'; - -var assign = require("./Object.assign"); -var emptyObject = require("./emptyObject"); -var warning = require("./warning"); - -var didWarn = false; - -/** - * Keeps track of the current context. - * - * The context is automatically passed down the component ownership hierarchy - * and is accessible via `this.context` on ReactCompositeComponents. - */ -var ReactContext = { - - /** - * @internal - * @type {object} - */ - current: emptyObject, - - /** - * Temporarily extends the current context while executing scopedCallback. - * - * A typical use case might look like - * - * render: function() { - * var children = ReactContext.withContext({foo: 'foo'}, () => ( - * - * )); - * return <div>{children}</div>; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array<ReactComponent>} - */ - withContext: function(newContext, scopedCallback) { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - didWarn, - 'withContext is deprecated and will be removed in a future version. ' + - 'Use a wrapper component with getChildContext instead.' - ) : null); - - didWarn = true; - } - - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; - } - -}; - -module.exports = ReactContext; - }).call(this,require('_process')) -},{"./Object.assign":69,"./emptyObject":171,"./warning":212,"_process":1}],85:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactComponentEnvironment":94,"./ReactCurrentOwner":97,"./ReactElement":115,"./ReactInstanceMap":126,"./ReactPerf":136,"./ReactPropTypeLocationNames":138,"./ReactPropTypeLocations":139,"./ReactReconciler":142,"./ReactUpdateQueue":153,"./shouldUpdateReactComponent":200,"_process":1,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],97:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -10977,8 +11559,6 @@ module.exports = ReactContext; * * 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 = { @@ -10991,8 +11571,7 @@ var ReactCurrentOwner = { }; module.exports = ReactCurrentOwner; - -},{}],86:[function(require,module,exports){ +},{}],98:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -11003,176 +11582,92 @@ module.exports = ReactCurrentOwner; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule ReactDOM - * @typechecks static-only */ +/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ + 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactElementValidator = require("./ReactElementValidator"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactDOMTextComponent = require('./ReactDOMTextComponent'); +var ReactDefaultInjection = require('./ReactDefaultInjection'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactMount = require('./ReactMount'); +var ReactPerf = require('./ReactPerf'); +var ReactReconciler = require('./ReactReconciler'); +var ReactUpdates = require('./ReactUpdates'); +var ReactVersion = require('./ReactVersion'); -var mapObject = require("./mapObject"); +var findDOMNode = require('./findDOMNode'); +var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer'); +var warning = require('fbjs/lib/warning'); -/** - * Create a factory that creates HTML tag elements. - * - * @param {string} tag Tag name (e.g. `div`). - * @private - */ -function createDOMFactory(tag) { - if ("production" !== process.env.NODE_ENV) { - return ReactElementValidator.createFactory(tag); - } - return ReactElement.createFactory(tag); +ReactDefaultInjection.inject(); + +var render = ReactPerf.measure('React', 'render', ReactMount.render); + +var React = { + findDOMNode: findDOMNode, + render: render, + unmountComponentAtNode: ReactMount.unmountComponentAtNode, + version: ReactVersion, + + /* eslint-disable camelcase */ + unstable_batchedUpdates: ReactUpdates.batchedUpdates, + unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer +}; + +// Inject the runtime into a devtools global hook regardless of browser. +// Allows for debugging when the hook is injected on the page. +/* eslint-enable camelcase */ +if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { + __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ + CurrentOwner: ReactCurrentOwner, + InstanceHandles: ReactInstanceHandles, + Mount: ReactMount, + Reconciler: ReactReconciler, + TextComponent: ReactDOMTextComponent + }); } -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOM = mapObject({ - a: 'a', - abbr: 'abbr', - address: 'address', - area: 'area', - article: 'article', - aside: 'aside', - audio: 'audio', - b: 'b', - base: 'base', - bdi: 'bdi', - bdo: 'bdo', - big: 'big', - blockquote: 'blockquote', - body: 'body', - br: 'br', - button: 'button', - canvas: 'canvas', - caption: 'caption', - cite: 'cite', - code: 'code', - col: 'col', - colgroup: 'colgroup', - data: 'data', - datalist: 'datalist', - dd: 'dd', - del: 'del', - details: 'details', - dfn: 'dfn', - dialog: 'dialog', - div: 'div', - dl: 'dl', - dt: 'dt', - em: 'em', - embed: 'embed', - fieldset: 'fieldset', - figcaption: 'figcaption', - figure: 'figure', - footer: 'footer', - form: 'form', - h1: 'h1', - h2: 'h2', - h3: 'h3', - h4: 'h4', - h5: 'h5', - h6: 'h6', - head: 'head', - header: 'header', - hr: 'hr', - html: 'html', - i: 'i', - iframe: 'iframe', - img: 'img', - input: 'input', - ins: 'ins', - kbd: 'kbd', - keygen: 'keygen', - label: 'label', - legend: 'legend', - li: 'li', - link: 'link', - main: 'main', - map: 'map', - mark: 'mark', - menu: 'menu', - menuitem: 'menuitem', - meta: 'meta', - meter: 'meter', - nav: 'nav', - noscript: 'noscript', - object: 'object', - ol: 'ol', - optgroup: 'optgroup', - option: 'option', - output: 'output', - p: 'p', - param: 'param', - picture: 'picture', - pre: 'pre', - progress: 'progress', - q: 'q', - rp: 'rp', - rt: 'rt', - ruby: 'ruby', - s: 's', - samp: 'samp', - script: 'script', - section: 'section', - select: 'select', - small: 'small', - source: 'source', - span: 'span', - strong: 'strong', - style: 'style', - sub: 'sub', - summary: 'summary', - sup: 'sup', - table: 'table', - tbody: 'tbody', - td: 'td', - textarea: 'textarea', - tfoot: 'tfoot', - th: 'th', - thead: 'thead', - time: 'time', - title: 'title', - tr: 'tr', - track: 'track', - u: 'u', - ul: 'ul', - 'var': 'var', - video: 'video', - wbr: 'wbr', +if (process.env.NODE_ENV !== 'production') { + var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); + if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - // SVG - circle: 'circle', - clipPath: 'clipPath', - defs: 'defs', - ellipse: 'ellipse', - g: 'g', - line: 'line', - linearGradient: 'linearGradient', - mask: 'mask', - path: 'path', - pattern: 'pattern', - polygon: 'polygon', - polyline: 'polyline', - radialGradient: 'radialGradient', - rect: 'rect', - stop: 'stop', - svg: 'svg', - text: 'text', - tspan: 'tspan' + // First check if devtools is not installed + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { + // If we're in Chrome or Firefox, provide a download link if not installed. + if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { + console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools'); + } + } -}, createDOMFactory); + // If we're in IE8, check to see if we are in compatibility mode and provide + // information on preventing compatibility mode + var ieCompatibilityMode = document.documentMode && document.documentMode < 8; -module.exports = ReactDOM; + process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : undefined; + + var expectedFeatures = [ + // shims + Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim, + + // shams + Object.create, Object.freeze]; + + for (var i = 0; i < expectedFeatures.length; i++) { + if (!expectedFeatures[i]) { + console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills'); + break; + } + } + } +} +module.exports = React; }).call(this,require('_process')) -},{"./ReactElement":103,"./ReactElementValidator":104,"./mapObject":199,"_process":1}],87:[function(require,module,exports){ +},{"./ReactCurrentOwner":97,"./ReactDOMTextComponent":109,"./ReactDefaultInjection":112,"./ReactInstanceHandles":125,"./ReactMount":130,"./ReactPerf":136,"./ReactReconciler":142,"./ReactUpdates":154,"./ReactVersion":155,"./findDOMNode":181,"./renderSubtreeIntoContainer":196,"_process":1,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/warning":232}],99:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -11186,57 +11681,44 @@ module.exports = ReactDOM; 'use strict'; -var AutoFocusMixin = require("./AutoFocusMixin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); - -var keyMirror = require("./keyMirror"); - -var button = ReactElement.createFactory('button'); - -var mouseListenerNames = keyMirror({ +var mouseListenerNames = { onClick: true, onDoubleClick: true, onMouseDown: true, onMouseMove: true, onMouseUp: true, + onClickCapture: true, onDoubleClickCapture: true, onMouseDownCapture: true, onMouseMoveCapture: true, onMouseUpCapture: true -}); +}; /** * Implements a <button> native component that does not receive mouse events * when `disabled` is set. */ -var ReactDOMButton = ReactClass.createClass({ - displayName: 'ReactDOMButton', - tagName: 'BUTTON', - - mixins: [AutoFocusMixin, ReactBrowserComponentMixin], - - render: function() { - var props = {}; +var ReactDOMButton = { + getNativeProps: function (inst, props, context) { + if (!props.disabled) { + return props; + } - // Copy the props; except the mouse listeners if we're disabled - for (var key in this.props) { - if (this.props.hasOwnProperty(key) && - (!this.props.disabled || !mouseListenerNames[key])) { - props[key] = this.props[key]; + // Copy the props, except the mouse listeners + var nativeProps = {}; + for (var key in props) { + if (props.hasOwnProperty(key) && !mouseListenerNames[key]) { + nativeProps[key] = props[key]; } } - return button(props, this.props.children); + return nativeProps; } - -}); +}; module.exports = ReactDOMButton; - -},{"./AutoFocusMixin":42,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103,"./keyMirror":197}],88:[function(require,module,exports){ +},{}],100:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -11254,104 +11736,293 @@ module.exports = ReactDOMButton; 'use strict'; -var CSSPropertyOperations = require("./CSSPropertyOperations"); -var DOMProperty = require("./DOMProperty"); -var DOMPropertyOperations = require("./DOMPropertyOperations"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); -var ReactComponentBrowserEnvironment = - require("./ReactComponentBrowserEnvironment"); -var ReactMount = require("./ReactMount"); -var ReactMultiChild = require("./ReactMultiChild"); -var ReactPerf = require("./ReactPerf"); - -var assign = require("./Object.assign"); -var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); -var invariant = require("./invariant"); -var isEventSupported = require("./isEventSupported"); -var keyOf = require("./keyOf"); -var warning = require("./warning"); +var AutoFocusUtils = require('./AutoFocusUtils'); +var CSSPropertyOperations = require('./CSSPropertyOperations'); +var DOMProperty = require('./DOMProperty'); +var DOMPropertyOperations = require('./DOMPropertyOperations'); +var EventConstants = require('./EventConstants'); +var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); +var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment'); +var ReactDOMButton = require('./ReactDOMButton'); +var ReactDOMInput = require('./ReactDOMInput'); +var ReactDOMOption = require('./ReactDOMOption'); +var ReactDOMSelect = require('./ReactDOMSelect'); +var ReactDOMTextarea = require('./ReactDOMTextarea'); +var ReactMount = require('./ReactMount'); +var ReactMultiChild = require('./ReactMultiChild'); +var ReactPerf = require('./ReactPerf'); +var ReactUpdateQueue = require('./ReactUpdateQueue'); + +var assign = require('./Object.assign'); +var canDefineProperty = require('./canDefineProperty'); +var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); +var invariant = require('fbjs/lib/invariant'); +var isEventSupported = require('./isEventSupported'); +var keyOf = require('fbjs/lib/keyOf'); +var setInnerHTML = require('./setInnerHTML'); +var setTextContent = require('./setTextContent'); +var shallowEqual = require('fbjs/lib/shallowEqual'); +var validateDOMNesting = require('./validateDOMNesting'); +var warning = require('fbjs/lib/warning'); var deleteListener = ReactBrowserEventEmitter.deleteListener; var listenTo = ReactBrowserEventEmitter.listenTo; var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules; // For quickly matching children type, to test if can be treated as content. -var CONTENT_TYPES = {'string': true, 'number': true}; +var CONTENT_TYPES = { 'string': true, 'number': true }; -var STYLE = keyOf({style: null}); +var CHILDREN = keyOf({ children: null }); +var STYLE = keyOf({ style: null }); +var HTML = keyOf({ __html: null }); var ELEMENT_NODE_TYPE = 1; -/** - * Optionally injectable operations for mutating the DOM - */ -var BackendIDOperations = null; +function getDeclarationErrorAddendum(internalInstance) { + if (internalInstance) { + var owner = internalInstance._currentElement._owner || null; + if (owner) { + var name = owner.getName(); + if (name) { + return ' This DOM node was rendered by `' + name + '`.'; + } + } + } + return ''; +} + +var legacyPropsDescriptor; +if (process.env.NODE_ENV !== 'production') { + legacyPropsDescriptor = { + props: { + enumerable: false, + get: function () { + var component = this._reactInternalComponent; + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined; + return component._currentElement.props; + } + } + }; +} + +function legacyGetDOMNode() { + if (process.env.NODE_ENV !== 'production') { + var component = this._reactInternalComponent; + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .getDOMNode() of a DOM node; ' + 'instead, use the node directly.%s', getDeclarationErrorAddendum(component)) : undefined; + } + return this; +} + +function legacyIsMounted() { + var component = this._reactInternalComponent; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined; + } + return !!component; +} + +function legacySetStateEtc() { + if (process.env.NODE_ENV !== 'production') { + var component = this._reactInternalComponent; + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setState(), .replaceState(), or ' + '.forceUpdate() of a DOM node. This is a no-op.%s', getDeclarationErrorAddendum(component)) : undefined; + } +} + +function legacySetProps(partialProps, callback) { + var component = this._reactInternalComponent; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined; + } + if (!component) { + return; + } + ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps); + if (callback) { + ReactUpdateQueue.enqueueCallbackInternal(component, callback); + } +} + +function legacyReplaceProps(partialProps, callback) { + var component = this._reactInternalComponent; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined; + } + if (!component) { + return; + } + ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps); + if (callback) { + ReactUpdateQueue.enqueueCallbackInternal(component, callback); + } +} + +function friendlyStringify(obj) { + if (typeof obj === 'object') { + if (Array.isArray(obj)) { + return '[' + obj.map(friendlyStringify).join(', ') + ']'; + } else { + var pairs = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key); + pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key])); + } + } + return '{' + pairs.join(', ') + '}'; + } + } else if (typeof obj === 'string') { + return JSON.stringify(obj); + } else if (typeof obj === 'function') { + return '[function object]'; + } + // Differs from JSON.stringify in that undefined becauses undefined and that + // inf and nan don't become null + return String(obj); +} + +var styleMutationWarning = {}; + +function checkAndWarnForMutatedStyle(style1, style2, component) { + if (style1 == null || style2 == null) { + return; + } + if (shallowEqual(style1, style2)) { + return; + } + + var componentName = component._tag; + var owner = component._currentElement._owner; + var ownerName; + if (owner) { + ownerName = owner.getName(); + } + + var hash = ownerName + '|' + componentName; + + if (styleMutationWarning.hasOwnProperty(hash)) { + return; + } + + styleMutationWarning[hash] = true; + + process.env.NODE_ENV !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : undefined; +} /** + * @param {object} component * @param {?object} props */ -function assertValidProps(props) { +function assertValidProps(component, props) { if (!props) { return; } // Note the use of `==` which checks for null or undefined. + if (process.env.NODE_ENV !== 'production') { + if (voidElementTags[component._tag]) { + process.env.NODE_ENV !== 'production' ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined; + } + } if (props.dangerouslySetInnerHTML != null) { - ("production" !== process.env.NODE_ENV ? invariant( - props.children == null, - 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' - ) : invariant(props.children == null)); - ("production" !== process.env.NODE_ENV ? invariant( - typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML, - '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + - 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + - 'for more information.' - ) : invariant(typeof props.dangerouslySetInnerHTML === 'object' && - '__html' in props.dangerouslySetInnerHTML)); - } - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - props.innerHTML == null, - 'Directly setting property `innerHTML` is not permitted. ' + - 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' - ) : null); - ("production" !== process.env.NODE_ENV ? warning( - !props.contentEditable || props.children == null, - 'A component is `contentEditable` and contains `children` managed by ' + - 'React. It is now your responsibility to guarantee that none of ' + - 'those nodes are unexpectedly modified or duplicated. This is ' + - 'probably not intentional.' - ) : null); - } - ("production" !== process.env.NODE_ENV ? invariant( - props.style == null || typeof props.style === 'object', - 'The `style` prop expects a mapping from style properties to values, ' + - 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + - 'using JSX.' - ) : invariant(props.style == null || typeof props.style === 'object')); -} - -function putListener(id, registrationName, listener, transaction) { - if ("production" !== process.env.NODE_ENV) { + !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined; + !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined; + } + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined; + process.env.NODE_ENV !== 'production' ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined; + } + !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : undefined; +} + +function enqueuePutListener(id, registrationName, listener, transaction) { + if (process.env.NODE_ENV !== 'production') { // IE8 has no API for event capturing and the `onScroll` event doesn't // bubble. - ("production" !== process.env.NODE_ENV ? warning( - registrationName !== 'onScroll' || isEventSupported('scroll', true), - 'This browser doesn\'t support the `onScroll` event' - ) : null); + process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined; } var container = ReactMount.findReactContainerForID(id); if (container) { - var doc = container.nodeType === ELEMENT_NODE_TYPE ? - container.ownerDocument : - container; + var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container; listenTo(registrationName, doc); } - transaction.getPutListenerQueue().enqueuePutListener( - id, - registrationName, - listener - ); + transaction.getReactMountReady().enqueue(putListener, { + id: id, + registrationName: registrationName, + listener: listener + }); +} + +function putListener() { + var listenerToPut = this; + ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener); +} + +// There are so many media events, it makes sense to just +// maintain a list rather than create a `trapBubbledEvent` for each +var mediaEvents = { + topAbort: 'abort', + topCanPlay: 'canplay', + topCanPlayThrough: 'canplaythrough', + topDurationChange: 'durationchange', + topEmptied: 'emptied', + topEncrypted: 'encrypted', + topEnded: 'ended', + topError: 'error', + topLoadedData: 'loadeddata', + topLoadedMetadata: 'loadedmetadata', + topLoadStart: 'loadstart', + topPause: 'pause', + topPlay: 'play', + topPlaying: 'playing', + topProgress: 'progress', + topRateChange: 'ratechange', + topSeeked: 'seeked', + topSeeking: 'seeking', + topStalled: 'stalled', + topSuspend: 'suspend', + topTimeUpdate: 'timeupdate', + topVolumeChange: 'volumechange', + topWaiting: 'waiting' +}; + +function trapBubbledEventsLocal() { + var inst = this; + // If a component renders to null or if another component fatals and causes + // the state of the tree to be corrupted, `node` here can be null. + !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined; + var node = ReactMount.getNode(inst._rootNodeID); + !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined; + + switch (inst._tag) { + case 'iframe': + inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)]; + break; + case 'video': + case 'audio': + + inst._wrapperState.listeners = []; + // create listener for each media event + for (var event in mediaEvents) { + if (mediaEvents.hasOwnProperty(event)) { + inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node)); + } + } + + break; + case 'img': + inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)]; + break; + case 'form': + inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)]; + break; + } +} + +function mountReadyInputWrapper() { + ReactDOMInput.mountReadyWrapper(this); +} + +function postUpdateSelectWrapper() { + ReactDOMSelect.postUpdateWrapper(this); } // For HTML, certain tags should omit their close tag. We keep a whitelist for @@ -11373,24 +12044,49 @@ var omittedCloseTags = { 'source': true, 'track': true, 'wbr': true - // NOTE: menuitem's close tag should be omitted, but that causes problems. }; -// We accept any tag to be rendered but since this gets injected into abitrary +// NOTE: menuitem's close tag should be omitted, but that causes problems. +var newlineEatingTags = { + 'listing': true, + 'pre': true, + 'textarea': true +}; + +// For HTML, certain tags cannot have children. This has the same purpose as +// `omittedCloseTags` except that `menuitem` should still have its closing tag. + +var voidElementTags = assign({ + 'menuitem': true +}, omittedCloseTags); + +// We accept any tag to be rendered but since this gets injected into arbitrary // HTML, we want to make sure that it's a safe tag. // http://www.w3.org/TR/REC-xml/#NT-Name var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; +var hasOwnProperty = ({}).hasOwnProperty; function validateDangerousTag(tag) { if (!hasOwnProperty.call(validatedTagCache, tag)) { - ("production" !== process.env.NODE_ENV ? invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag) : invariant(VALID_TAG_REGEX.test(tag))); + !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined; validatedTagCache[tag] = true; } } +function processChildContextDev(context, inst) { + // Pass down our tag name to child components for validation purposes + context = assign({}, context); + var info = context[validateDOMNesting.ancestorInfoContextKey]; + context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst); + return context; +} + +function isCustomComponent(tagName, props) { + return tagName.indexOf('-') >= 0 || props.is != null; +} + /** * Creates a new React class that is idempotent and capable of containing other * React components. It accepts event listeners and DOM properties that are @@ -11407,17 +12103,25 @@ function validateDangerousTag(tag) { */ function ReactDOMComponent(tag) { validateDangerousTag(tag); - this._tag = tag; + this._tag = tag.toLowerCase(); this._renderedChildren = null; + this._previousStyle = null; this._previousStyleCopy = null; this._rootNodeID = null; + this._wrapperState = null; + this._topLevelWrapper = null; + this._nodeWithLegacyProperties = null; + if (process.env.NODE_ENV !== 'production') { + this._unprocessedContextDev = null; + this._processedContextDev = null; + } } ReactDOMComponent.displayName = 'ReactDOMComponent'; ReactDOMComponent.Mixin = { - construct: function(element) { + construct: function (element) { this._currentElement = element; }, @@ -11428,17 +12132,94 @@ ReactDOMComponent.Mixin = { * @internal * @param {string} rootID The root DOM ID for this node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {object} context * @return {string} The computed markup. */ - mountComponent: function(rootID, transaction, context) { + mountComponent: function (rootID, transaction, context) { this._rootNodeID = rootID; - assertValidProps(this._currentElement.props); - var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>'; - return ( - this._createOpenTagMarkupAndPutListeners(transaction) + - this._createContentMarkup(transaction, context) + - closeTag - ); + + var props = this._currentElement.props; + + switch (this._tag) { + case 'iframe': + case 'img': + case 'form': + case 'video': + case 'audio': + this._wrapperState = { + listeners: null + }; + transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); + break; + case 'button': + props = ReactDOMButton.getNativeProps(this, props, context); + break; + case 'input': + ReactDOMInput.mountWrapper(this, props, context); + props = ReactDOMInput.getNativeProps(this, props, context); + break; + case 'option': + ReactDOMOption.mountWrapper(this, props, context); + props = ReactDOMOption.getNativeProps(this, props, context); + break; + case 'select': + ReactDOMSelect.mountWrapper(this, props, context); + props = ReactDOMSelect.getNativeProps(this, props, context); + context = ReactDOMSelect.processChildContext(this, props, context); + break; + case 'textarea': + ReactDOMTextarea.mountWrapper(this, props, context); + props = ReactDOMTextarea.getNativeProps(this, props, context); + break; + } + + assertValidProps(this, props); + if (process.env.NODE_ENV !== 'production') { + if (context[validateDOMNesting.ancestorInfoContextKey]) { + validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]); + } + } + + if (process.env.NODE_ENV !== 'production') { + this._unprocessedContextDev = context; + this._processedContextDev = processChildContextDev(context, this); + context = this._processedContextDev; + } + + var mountImage; + if (transaction.useCreateElement) { + var ownerDocument = context[ReactMount.ownerDocumentContextKey]; + var el = ownerDocument.createElement(this._currentElement.type); + DOMPropertyOperations.setAttributeForID(el, this._rootNodeID); + // Populate node cache + ReactMount.getID(el); + this._updateDOMProperties({}, props, transaction, el); + this._createInitialChildren(transaction, props, context, el); + mountImage = el; + } else { + var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); + var tagContent = this._createContentMarkup(transaction, props, context); + if (!tagContent && omittedCloseTags[this._tag]) { + mountImage = tagOpen + '/>'; + } else { + mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>'; + } + } + + switch (this._tag) { + case 'input': + transaction.getReactMountReady().enqueue(mountReadyInputWrapper, this); + // falls through + case 'button': + case 'select': + case 'textarea': + if (props.autoFocus) { + transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); + } + break; + } + + return mountImage; }, /** @@ -11451,11 +12232,11 @@ ReactDOMComponent.Mixin = { * * @private * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {object} props * @return {string} Markup of opening tag. */ - _createOpenTagMarkupAndPutListeners: function(transaction) { - var props = this._currentElement.props; - var ret = '<' + this._tag; + _createOpenTagMarkupAndPutListeners: function (transaction, props) { + var ret = '<' + this._currentElement.type; for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { @@ -11466,16 +12247,28 @@ ReactDOMComponent.Mixin = { continue; } if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, propValue, transaction); + if (propValue) { + enqueuePutListener(this._rootNodeID, propKey, propValue, transaction); + } } else { if (propKey === STYLE) { if (propValue) { + if (process.env.NODE_ENV !== 'production') { + // See `_updateDOMProperties`. style block + this._previousStyle = propValue; + } propValue = this._previousStyleCopy = assign({}, props.style); } propValue = CSSPropertyOperations.createMarkupForStyles(propValue); } - var markup = - DOMPropertyOperations.createMarkupForProperty(propKey, propValue); + var markup = null; + if (this._tag != null && isCustomComponent(this._tag, props)) { + if (propKey !== CHILDREN) { + markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); + } + } else { + markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue); + } if (markup) { ret += ' ' + markup; } @@ -11485,11 +12278,11 @@ ReactDOMComponent.Mixin = { // For static pages, no need to put React ID and checksum. Saves lots of // bytes. if (transaction.renderToStaticMarkup) { - return ret + '>'; + return ret; } var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); - return ret + ' ' + markupForID + '>'; + return ret + ' ' + markupForID; }, /** @@ -11497,47 +12290,78 @@ ReactDOMComponent.Mixin = { * * @private * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {object} props * @param {object} context * @return {string} Content markup. */ - _createContentMarkup: function(transaction, context) { - var prefix = ''; - if (this._tag === 'listing' || - this._tag === 'pre' || - this._tag === 'textarea') { - // Add an initial newline because browsers ignore the first newline in - // a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody. - prefix = '\n'; - } + _createContentMarkup: function (transaction, props, context) { + var ret = ''; - var props = this._currentElement.props; + // Intentional use of != to avoid catching zero/false. + var innerHTML = props.dangerouslySetInnerHTML; + if (innerHTML != null) { + if (innerHTML.__html != null) { + ret = innerHTML.__html; + } + } else { + var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; + var childrenToUse = contentToUse != null ? null : props.children; + if (contentToUse != null) { + // TODO: Validate that text is allowed as a child of this node + ret = escapeTextContentForBrowser(contentToUse); + } else if (childrenToUse != null) { + var mountImages = this.mountChildren(childrenToUse, transaction, context); + ret = mountImages.join(''); + } + } + if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') { + // text/html ignores the first character in these tags if it's a newline + // Prefer to break application/xml over text/html (for now) by adding + // a newline specifically to get eaten by the parser. (Alternately for + // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first + // \r is normalized out by HTMLTextAreaElement#value.) + // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> + // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> + // See: <http://www.w3.org/TR/html5/syntax.html#newlines> + // See: Parsing of "textarea" "listing" and "pre" elements + // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> + return '\n' + ret; + } else { + return ret; + } + }, + _createInitialChildren: function (transaction, props, context, el) { // Intentional use of != to avoid catching zero/false. var innerHTML = props.dangerouslySetInnerHTML; if (innerHTML != null) { if (innerHTML.__html != null) { - return prefix + innerHTML.__html; + setInnerHTML(el, innerHTML.__html); } } else { - var contentToUse = - CONTENT_TYPES[typeof props.children] ? props.children : null; + var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; var childrenToUse = contentToUse != null ? null : props.children; if (contentToUse != null) { - return prefix + escapeTextContentForBrowser(contentToUse); + // TODO: Validate that text is allowed as a child of this node + setTextContent(el, contentToUse); } else if (childrenToUse != null) { - var mountImages = this.mountChildren( - childrenToUse, - transaction, - context - ); - return prefix + mountImages.join(''); + var mountImages = this.mountChildren(childrenToUse, transaction, context); + for (var i = 0; i < mountImages.length; i++) { + el.appendChild(mountImages[i]); + } } } - return prefix; }, - receiveComponent: function(nextElement, transaction, context) { + /** + * Receives a next element and updates the component. + * + * @internal + * @param {ReactElement} nextElement + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {object} context + */ + receiveComponent: function (nextElement, transaction, context) { var prevElement = this._currentElement; this._currentElement = nextElement; this.updateComponent(transaction, prevElement, nextElement, context); @@ -11553,10 +12377,59 @@ ReactDOMComponent.Mixin = { * @internal * @overridable */ - updateComponent: function(transaction, prevElement, nextElement, context) { - assertValidProps(this._currentElement.props); - this._updateDOMProperties(prevElement.props, transaction); - this._updateDOMChildren(prevElement.props, transaction, context); + updateComponent: function (transaction, prevElement, nextElement, context) { + var lastProps = prevElement.props; + var nextProps = this._currentElement.props; + + switch (this._tag) { + case 'button': + lastProps = ReactDOMButton.getNativeProps(this, lastProps); + nextProps = ReactDOMButton.getNativeProps(this, nextProps); + break; + case 'input': + ReactDOMInput.updateWrapper(this); + lastProps = ReactDOMInput.getNativeProps(this, lastProps); + nextProps = ReactDOMInput.getNativeProps(this, nextProps); + break; + case 'option': + lastProps = ReactDOMOption.getNativeProps(this, lastProps); + nextProps = ReactDOMOption.getNativeProps(this, nextProps); + break; + case 'select': + lastProps = ReactDOMSelect.getNativeProps(this, lastProps); + nextProps = ReactDOMSelect.getNativeProps(this, nextProps); + break; + case 'textarea': + ReactDOMTextarea.updateWrapper(this); + lastProps = ReactDOMTextarea.getNativeProps(this, lastProps); + nextProps = ReactDOMTextarea.getNativeProps(this, nextProps); + break; + } + + if (process.env.NODE_ENV !== 'production') { + // If the context is reference-equal to the old one, pass down the same + // processed object so the update bailout in ReactReconciler behaves + // correctly (and identically in dev and prod). See #5005. + if (this._unprocessedContextDev !== context) { + this._unprocessedContextDev = context; + this._processedContextDev = processChildContextDev(context, this); + } + context = this._processedContextDev; + } + + assertValidProps(this, nextProps); + this._updateDOMProperties(lastProps, nextProps, transaction, null); + this._updateDOMChildren(lastProps, nextProps, transaction, context); + + if (!canDefineProperty && this._nodeWithLegacyProperties) { + this._nodeWithLegacyProperties.props = nextProps; + } + + if (this._tag === 'select') { + // <select> value update needs to occur after <option> children + // reconciliation + transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this); + } }, /** @@ -11572,16 +12445,16 @@ ReactDOMComponent.Mixin = { * * @private * @param {object} lastProps + * @param {object} nextProps * @param {ReactReconcileTransaction} transaction + * @param {?DOMElement} node */ - _updateDOMProperties: function(lastProps, transaction) { - var nextProps = this._currentElement.props; + _updateDOMProperties: function (lastProps, nextProps, transaction, node) { var propKey; var styleName; var styleUpdates; for (propKey in lastProps) { - if (nextProps.hasOwnProperty(propKey) || - !lastProps.hasOwnProperty(propKey)) { + if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey)) { continue; } if (propKey === STYLE) { @@ -11594,26 +12467,31 @@ ReactDOMComponent.Mixin = { } this._previousStyleCopy = null; } else if (registrationNameModules.hasOwnProperty(propKey)) { - deleteListener(this._rootNodeID, propKey); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.deletePropertyByID( - this._rootNodeID, - propKey - ); + if (lastProps[propKey]) { + // Only call deleteListener if there was a listener previously or + // else willDeleteListener gets called when there wasn't actually a + // listener (e.g., onClick={null}) + deleteListener(this._rootNodeID, propKey); + } + } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { + if (!node) { + node = ReactMount.getNode(this._rootNodeID); + } + DOMPropertyOperations.deleteValueForProperty(node, propKey); } } for (propKey in nextProps) { var nextProp = nextProps[propKey]; - var lastProp = propKey === STYLE ? - this._previousStyleCopy : - lastProps[propKey]; + var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps[propKey]; if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) { continue; } if (propKey === STYLE) { if (nextProp) { + if (process.env.NODE_ENV !== 'production') { + checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this); + this._previousStyle = nextProp; + } nextProp = this._previousStyleCopy = assign({}, nextProp); } else { this._previousStyleCopy = null; @@ -11621,16 +12499,14 @@ ReactDOMComponent.Mixin = { if (lastProp) { // Unset styles on `lastProp` but not on `nextProp`. for (styleName in lastProp) { - if (lastProp.hasOwnProperty(styleName) && - (!nextProp || !nextProp.hasOwnProperty(styleName))) { + if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { styleUpdates = styleUpdates || {}; styleUpdates[styleName] = ''; } } // Update styles that changed since `lastProp`. for (styleName in nextProp) { - if (nextProp.hasOwnProperty(styleName) && - lastProp[styleName] !== nextProp[styleName]) { + if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { styleUpdates = styleUpdates || {}; styleUpdates[styleName] = nextProp[styleName]; } @@ -11640,22 +12516,38 @@ ReactDOMComponent.Mixin = { styleUpdates = nextProp; } } else if (registrationNameModules.hasOwnProperty(propKey)) { - putListener(this._rootNodeID, propKey, nextProp, transaction); - } else if ( - DOMProperty.isStandardName[propKey] || - DOMProperty.isCustomAttribute(propKey)) { - BackendIDOperations.updatePropertyByID( - this._rootNodeID, - propKey, - nextProp - ); + if (nextProp) { + enqueuePutListener(this._rootNodeID, propKey, nextProp, transaction); + } else if (lastProp) { + deleteListener(this._rootNodeID, propKey); + } + } else if (isCustomComponent(this._tag, nextProps)) { + if (!node) { + node = ReactMount.getNode(this._rootNodeID); + } + if (propKey === CHILDREN) { + nextProp = null; + } + DOMPropertyOperations.setValueForAttribute(node, propKey, nextProp); + } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { + if (!node) { + node = ReactMount.getNode(this._rootNodeID); + } + // If we're updating to null or undefined, we should remove the property + // from the DOM node instead of inadvertantly setting to a string. This + // brings us in line with the same behavior we have on initial render. + if (nextProp != null) { + DOMPropertyOperations.setValueForProperty(node, propKey, nextProp); + } else { + DOMPropertyOperations.deleteValueForProperty(node, propKey); + } } } if (styleUpdates) { - BackendIDOperations.updateStylesByID( - this._rootNodeID, - styleUpdates - ); + if (!node) { + node = ReactMount.getNode(this._rootNodeID); + } + CSSPropertyOperations.setValueForStyles(node, styleUpdates); } }, @@ -11664,22 +12556,16 @@ ReactDOMComponent.Mixin = { * children content. * * @param {object} lastProps + * @param {object} nextProps * @param {ReactReconcileTransaction} transaction + * @param {object} context */ - _updateDOMChildren: function(lastProps, transaction, context) { - var nextProps = this._currentElement.props; + _updateDOMChildren: function (lastProps, nextProps, transaction, context) { + var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; + var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - var lastContent = - CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; - var nextContent = - CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - - var lastHtml = - lastProps.dangerouslySetInnerHTML && - lastProps.dangerouslySetInnerHTML.__html; - var nextHtml = - nextProps.dangerouslySetInnerHTML && - nextProps.dangerouslySetInnerHTML.__html; + var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html; + var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html; // Note the use of `!=` which checks for null or undefined. var lastChildren = lastContent != null ? null : lastProps.children; @@ -11701,10 +12587,7 @@ ReactDOMComponent.Mixin = { } } else if (nextHtml != null) { if (lastHtml !== nextHtml) { - BackendIDOperations.updateInnerHTMLByID( - this._rootNodeID, - nextHtml - ); + this.updateMarkup('' + nextHtml); } } else if (nextChildren != null) { this.updateChildren(nextChildren, transaction, context); @@ -11717,11 +12600,76 @@ ReactDOMComponent.Mixin = { * * @internal */ - unmountComponent: function() { + unmountComponent: function () { + switch (this._tag) { + case 'iframe': + case 'img': + case 'form': + case 'video': + case 'audio': + var listeners = this._wrapperState.listeners; + if (listeners) { + for (var i = 0; i < listeners.length; i++) { + listeners[i].remove(); + } + } + break; + case 'input': + ReactDOMInput.unmountWrapper(this); + break; + case 'html': + case 'head': + case 'body': + /** + * Components like <html> <head> and <body> can't be removed or added + * easily in a cross-browser way, however it's valuable to be able to + * take advantage of React's reconciliation for styling and <title> + * management. So we just document it and throw in dangerous cases. + */ + !false ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is ' + 'impossible to unmount some top-level components (eg <html>, ' + '<head>, and <body>) reliably and efficiently. To fix this, have a ' + 'single top-level component that never unmounts render these ' + 'elements.', this._tag) : invariant(false) : undefined; + break; + } + this.unmountChildren(); ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID); ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); this._rootNodeID = null; + this._wrapperState = null; + if (this._nodeWithLegacyProperties) { + var node = this._nodeWithLegacyProperties; + node._reactInternalComponent = null; + this._nodeWithLegacyProperties = null; + } + }, + + getPublicInstance: function () { + if (!this._nodeWithLegacyProperties) { + var node = ReactMount.getNode(this._rootNodeID); + + node._reactInternalComponent = this; + node.getDOMNode = legacyGetDOMNode; + node.isMounted = legacyIsMounted; + node.setState = legacySetStateEtc; + node.replaceState = legacySetStateEtc; + node.forceUpdate = legacySetStateEtc; + node.setProps = legacySetProps; + node.replaceProps = legacyReplaceProps; + + if (process.env.NODE_ENV !== 'production') { + if (canDefineProperty) { + Object.defineProperties(node, legacyPropsDescriptor); + } else { + // updateComponent will update this property on subsequent renders + node.props = this._currentElement.props; + } + } else { + // updateComponent will update this property on subsequent renders + node.props = this._currentElement.props; + } + + this._nodeWithLegacyProperties = node; + } + return this._nodeWithLegacyProperties; } }; @@ -11731,23 +12679,13 @@ ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', { updateComponent: 'updateComponent' }); -assign( - ReactDOMComponent.prototype, - ReactDOMComponent.Mixin, - ReactMultiChild.Mixin -); - -ReactDOMComponent.injection = { - injectIDOperations: function(IDOperations) { - ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations; - } -}; +assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); module.exports = ReactDOMComponent; - }).call(this,require('_process')) -},{"./CSSPropertyOperations":46,"./DOMProperty":51,"./DOMPropertyOperations":52,"./Object.assign":69,"./ReactBrowserEventEmitter":73,"./ReactComponentBrowserEnvironment":80,"./ReactMount":117,"./ReactMultiChild":118,"./ReactPerf":122,"./escapeTextContentForBrowser":172,"./invariant":191,"./isEventSupported":192,"./keyOf":198,"./warning":212,"_process":1}],89:[function(require,module,exports){ +},{"./AutoFocusUtils":60,"./CSSPropertyOperations":63,"./DOMProperty":68,"./DOMPropertyOperations":69,"./EventConstants":73,"./Object.assign":82,"./ReactBrowserEventEmitter":86,"./ReactComponentBrowserEnvironment":93,"./ReactDOMButton":99,"./ReactDOMInput":104,"./ReactDOMOption":105,"./ReactDOMSelect":106,"./ReactDOMTextarea":110,"./ReactMount":130,"./ReactMultiChild":131,"./ReactPerf":136,"./ReactUpdateQueue":153,"./canDefineProperty":176,"./escapeTextContentForBrowser":180,"./isEventSupported":192,"./setInnerHTML":197,"./setTextContent":198,"./validateDOMNesting":203,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/keyOf":225,"fbjs/lib/shallowEqual":230,"fbjs/lib/warning":232}],101:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -11756,47 +12694,197 @@ module.exports = ReactDOMComponent; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDOMForm + * @providesModule ReactDOMFactories + * @typechecks static-only */ 'use strict'; -var EventConstants = require("./EventConstants"); -var LocalEventTrapMixin = require("./LocalEventTrapMixin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); +var ReactElement = require('./ReactElement'); +var ReactElementValidator = require('./ReactElementValidator'); -var form = ReactElement.createFactory('form'); +var mapObject = require('fbjs/lib/mapObject'); /** - * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need - * to capture it on the <form> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <form> a - * composite component and use `componentDidMount` to attach the event handlers. + * Create a factory that creates HTML tag elements. + * + * @param {string} tag Tag name (e.g. `div`). + * @private */ -var ReactDOMForm = ReactClass.createClass({ - displayName: 'ReactDOMForm', - tagName: 'FORM', +function createDOMFactory(tag) { + if (process.env.NODE_ENV !== 'production') { + return ReactElementValidator.createFactory(tag); + } + return ReactElement.createFactory(tag); +} - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], +/** + * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. + * This is also accessible via `React.DOM`. + * + * @public + */ +var ReactDOMFactories = mapObject({ + a: 'a', + abbr: 'abbr', + address: 'address', + area: 'area', + article: 'article', + aside: 'aside', + audio: 'audio', + b: 'b', + base: 'base', + bdi: 'bdi', + bdo: 'bdo', + big: 'big', + blockquote: 'blockquote', + body: 'body', + br: 'br', + button: 'button', + canvas: 'canvas', + caption: 'caption', + cite: 'cite', + code: 'code', + col: 'col', + colgroup: 'colgroup', + data: 'data', + datalist: 'datalist', + dd: 'dd', + del: 'del', + details: 'details', + dfn: 'dfn', + dialog: 'dialog', + div: 'div', + dl: 'dl', + dt: 'dt', + em: 'em', + embed: 'embed', + fieldset: 'fieldset', + figcaption: 'figcaption', + figure: 'figure', + footer: 'footer', + form: 'form', + h1: 'h1', + h2: 'h2', + h3: 'h3', + h4: 'h4', + h5: 'h5', + h6: 'h6', + head: 'head', + header: 'header', + hgroup: 'hgroup', + hr: 'hr', + html: 'html', + i: 'i', + iframe: 'iframe', + img: 'img', + input: 'input', + ins: 'ins', + kbd: 'kbd', + keygen: 'keygen', + label: 'label', + legend: 'legend', + li: 'li', + link: 'link', + main: 'main', + map: 'map', + mark: 'mark', + menu: 'menu', + menuitem: 'menuitem', + meta: 'meta', + meter: 'meter', + nav: 'nav', + noscript: 'noscript', + object: 'object', + ol: 'ol', + optgroup: 'optgroup', + option: 'option', + output: 'output', + p: 'p', + param: 'param', + picture: 'picture', + pre: 'pre', + progress: 'progress', + q: 'q', + rp: 'rp', + rt: 'rt', + ruby: 'ruby', + s: 's', + samp: 'samp', + script: 'script', + section: 'section', + select: 'select', + small: 'small', + source: 'source', + span: 'span', + strong: 'strong', + style: 'style', + sub: 'sub', + summary: 'summary', + sup: 'sup', + table: 'table', + tbody: 'tbody', + td: 'td', + textarea: 'textarea', + tfoot: 'tfoot', + th: 'th', + thead: 'thead', + time: 'time', + title: 'title', + tr: 'tr', + track: 'track', + u: 'u', + ul: 'ul', + 'var': 'var', + video: 'video', + wbr: 'wbr', - render: function() { - // TODO: Instead of using `ReactDOM` directly, we should use JSX. However, - // `jshint` fails to parse JSX so in order for linting to work in the open - // source repo, we need to just use `ReactDOM.form`. - return form(this.props); - }, + // SVG + circle: 'circle', + clipPath: 'clipPath', + defs: 'defs', + ellipse: 'ellipse', + g: 'g', + image: 'image', + line: 'line', + linearGradient: 'linearGradient', + mask: 'mask', + path: 'path', + pattern: 'pattern', + polygon: 'polygon', + polyline: 'polyline', + radialGradient: 'radialGradient', + rect: 'rect', + stop: 'stop', + svg: 'svg', + text: 'text', + tspan: 'tspan' - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit'); - } -}); +}, createDOMFactory); + +module.exports = ReactDOMFactories; +}).call(this,require('_process')) + +},{"./ReactElement":115,"./ReactElementValidator":116,"_process":1,"fbjs/lib/mapObject":226}],102:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMFeatureFlags + */ -module.exports = ReactDOMForm; +'use strict'; + +var ReactDOMFeatureFlags = { + useCreateElement: false +}; -},{"./EventConstants":56,"./LocalEventTrapMixin":67,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103}],90:[function(require,module,exports){ +module.exports = ReactDOMFeatureFlags; +},{}],103:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -11810,34 +12898,28 @@ module.exports = ReactDOMForm; * @typechecks static-only */ -/*jslint evil: true */ - 'use strict'; -var CSSPropertyOperations = require("./CSSPropertyOperations"); -var DOMChildrenOperations = require("./DOMChildrenOperations"); -var DOMPropertyOperations = require("./DOMPropertyOperations"); -var ReactMount = require("./ReactMount"); -var ReactPerf = require("./ReactPerf"); +var DOMChildrenOperations = require('./DOMChildrenOperations'); +var DOMPropertyOperations = require('./DOMPropertyOperations'); +var ReactMount = require('./ReactMount'); +var ReactPerf = require('./ReactPerf'); -var invariant = require("./invariant"); -var setInnerHTML = require("./setInnerHTML"); +var invariant = require('fbjs/lib/invariant'); /** - * Errors for properties that should not be updated with `updatePropertyById()`. + * Errors for properties that should not be updated with `updatePropertyByID()`. * * @type {object} * @private */ var INVALID_PROPERTY_ERRORS = { - dangerouslySetInnerHTML: - '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', + dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', style: '`style` must be set using `updateStylesByID()`.' }; /** - * Operations used to process updates to DOM nodes. This is made injectable via - * `ReactDOMComponent.BackendIDOperations`. + * Operations used to process updates to DOM nodes. */ var ReactDOMIDOperations = { @@ -11850,13 +12932,9 @@ var ReactDOMIDOperations = { * @param {*} value New value of the property. * @internal */ - updatePropertyByID: function(id, name, value) { + updatePropertyByID: function (id, name, value) { var node = ReactMount.getNode(id); - ("production" !== process.env.NODE_ENV ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); + !!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined; // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertantly setting to a string. This @@ -11869,61 +12947,6 @@ var ReactDOMIDOperations = { }, /** - * Updates a DOM node to remove a property. This should only be used to remove - * DOM properties in `DOMProperty`. - * - * @param {string} id ID of the node to update. - * @param {string} name A property name to remove, see `DOMProperty`. - * @internal - */ - deletePropertyByID: function(id, name, value) { - var node = ReactMount.getNode(id); - ("production" !== process.env.NODE_ENV ? invariant( - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), - 'updatePropertyByID(...): %s', - INVALID_PROPERTY_ERRORS[name] - ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); - DOMPropertyOperations.deleteValueForProperty(node, name, value); - }, - - /** - * Updates a DOM node with new style values. If a value is specified as '', - * the corresponding style property will be unset. - * - * @param {string} id ID of the node to update. - * @param {object} styles Mapping from styles to values. - * @internal - */ - updateStylesByID: function(id, styles) { - var node = ReactMount.getNode(id); - CSSPropertyOperations.setValueForStyles(node, styles); - }, - - /** - * Updates a DOM node's innerHTML. - * - * @param {string} id ID of the node to update. - * @param {string} html An HTML string. - * @internal - */ - updateInnerHTMLByID: function(id, html) { - var node = ReactMount.getNode(id); - setInnerHTML(node, html); - }, - - /** - * Updates a DOM node's text content set by `props.content`. - * - * @param {string} id ID of the node to update. - * @param {string} content Text content. - * @internal - */ - updateTextContentByID: function(id, content) { - var node = ReactMount.getNode(id); - DOMChildrenOperations.updateTextContent(node, content); - }, - - /** * Replaces a DOM node that exists in the document with markup. * * @param {string} id ID of child to be replaced. @@ -11931,7 +12954,7 @@ var ReactDOMIDOperations = { * @internal * @see {Danger.dangerouslyReplaceNodeWithMarkup} */ - dangerouslyReplaceNodeWithMarkupByID: function(id, markup) { + dangerouslyReplaceNodeWithMarkupByID: function (id, markup) { var node = ReactMount.getNode(id); DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); }, @@ -11943,7 +12966,7 @@ var ReactDOMIDOperations = { * @param {array<string>} markup List of markup strings. * @internal */ - dangerouslyProcessChildrenUpdates: function(updates, markup) { + dangerouslyProcessChildrenUpdates: function (updates, markup) { for (var i = 0; i < updates.length; i++) { updates[i].parentNode = ReactMount.getNode(updates[i].parentID); } @@ -11952,111 +12975,14 @@ var ReactDOMIDOperations = { }; ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { - updatePropertyByID: 'updatePropertyByID', - deletePropertyByID: 'deletePropertyByID', - updateStylesByID: 'updateStylesByID', - updateInnerHTMLByID: 'updateInnerHTMLByID', - updateTextContentByID: 'updateTextContentByID', dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID', dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' }); module.exports = ReactDOMIDOperations; - }).call(this,require('_process')) -},{"./CSSPropertyOperations":46,"./DOMChildrenOperations":50,"./DOMPropertyOperations":52,"./ReactMount":117,"./ReactPerf":122,"./invariant":191,"./setInnerHTML":205,"_process":1}],91:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMIframe - */ - -'use strict'; - -var EventConstants = require("./EventConstants"); -var LocalEventTrapMixin = require("./LocalEventTrapMixin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); - -var iframe = ReactElement.createFactory('iframe'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <iframe> element itself. There are lots of hacks we could - * do to accomplish this, but the most reliable is to make <iframe> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMIframe = ReactClass.createClass({ - displayName: 'ReactDOMIframe', - tagName: 'IFRAME', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return iframe(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - } -}); - -module.exports = ReactDOMIframe; - -},{"./EventConstants":56,"./LocalEventTrapMixin":67,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103}],92:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMImg - */ - -'use strict'; - -var EventConstants = require("./EventConstants"); -var LocalEventTrapMixin = require("./LocalEventTrapMixin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); - -var img = ReactElement.createFactory('img'); - -/** - * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to - * capture it on the <img> element itself. There are lots of hacks we could do - * to accomplish this, but the most reliable is to make <img> a composite - * component and use `componentDidMount` to attach the event handlers. - */ -var ReactDOMImg = ReactClass.createClass({ - displayName: 'ReactDOMImg', - tagName: 'IMG', - - mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], - - render: function() { - return img(this.props); - }, - - componentDidMount: function() { - this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load'); - this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error'); - } -}); - -module.exports = ReactDOMImg; - -},{"./EventConstants":56,"./LocalEventTrapMixin":67,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103}],93:[function(require,module,exports){ +},{"./DOMChildrenOperations":67,"./DOMPropertyOperations":69,"./ReactMount":130,"./ReactPerf":136,"_process":1,"fbjs/lib/invariant":220}],104:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -12071,26 +12997,20 @@ module.exports = ReactDOMImg; 'use strict'; -var AutoFocusMixin = require("./AutoFocusMixin"); -var DOMPropertyOperations = require("./DOMPropertyOperations"); -var LinkedValueUtils = require("./LinkedValueUtils"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); -var ReactMount = require("./ReactMount"); -var ReactUpdates = require("./ReactUpdates"); +var ReactDOMIDOperations = require('./ReactDOMIDOperations'); +var LinkedValueUtils = require('./LinkedValueUtils'); +var ReactMount = require('./ReactMount'); +var ReactUpdates = require('./ReactUpdates'); -var assign = require("./Object.assign"); -var invariant = require("./invariant"); - -var input = ReactElement.createFactory('input'); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); var instancesByReactID = {}; function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); + if (this._rootNodeID) { + // DOM component is still mounted; update + ReactDOMInput.updateWrapper(this); } } @@ -12110,131 +13030,116 @@ function forceUpdateIfMounted() { * * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html */ -var ReactDOMInput = ReactClass.createClass({ - displayName: 'ReactDOMInput', - tagName: 'INPUT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], +var ReactDOMInput = { + getNativeProps: function (inst, props, context) { + var value = LinkedValueUtils.getValue(props); + var checked = LinkedValueUtils.getChecked(props); + + var nativeProps = assign({}, props, { + defaultChecked: undefined, + defaultValue: undefined, + value: value != null ? value : inst._wrapperState.initialValue, + checked: checked != null ? checked : inst._wrapperState.initialChecked, + onChange: inst._wrapperState.onChange + }); - getInitialState: function() { - var defaultValue = this.props.defaultValue; - return { - initialChecked: this.props.defaultChecked || false, - initialValue: defaultValue != null ? defaultValue : null - }; + return nativeProps; }, - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.defaultChecked = null; - props.defaultValue = null; - - var value = LinkedValueUtils.getValue(this); - props.value = value != null ? value : this.state.initialValue; - - var checked = LinkedValueUtils.getChecked(this); - props.checked = checked != null ? checked : this.state.initialChecked; - - props.onChange = this._handleChange; + mountWrapper: function (inst, props) { + if (process.env.NODE_ENV !== 'production') { + LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); + } - return input(props, this.props.children); + var defaultValue = props.defaultValue; + inst._wrapperState = { + initialChecked: props.defaultChecked || false, + initialValue: defaultValue != null ? defaultValue : null, + onChange: _handleChange.bind(inst) + }; }, - componentDidMount: function() { - var id = ReactMount.getID(this.getDOMNode()); - instancesByReactID[id] = this; + mountReadyWrapper: function (inst) { + // Can't be in mountWrapper or else server rendering leaks. + instancesByReactID[inst._rootNodeID] = inst; }, - componentWillUnmount: function() { - var rootNode = this.getDOMNode(); - var id = ReactMount.getID(rootNode); - delete instancesByReactID[id]; + unmountWrapper: function (inst) { + delete instancesByReactID[inst._rootNodeID]; }, - componentDidUpdate: function(prevProps, prevState, prevContext) { - var rootNode = this.getDOMNode(); - if (this.props.checked != null) { - DOMPropertyOperations.setValueForProperty( - rootNode, - 'checked', - this.props.checked || false - ); + updateWrapper: function (inst) { + var props = inst._currentElement.props; + + // TODO: Shouldn't this be getChecked(props)? + var checked = props.checked; + if (checked != null) { + ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false); } - var value = LinkedValueUtils.getValue(this); + var value = LinkedValueUtils.getValue(props); if (value != null) { // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); + ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value); } - }, + } +}; - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - // Here we use asap to wait until all updates have propagated, which - // is important when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - ReactUpdates.asap(forceUpdateIfMounted, this); +function _handleChange(event) { + var props = this._currentElement.props; - var name = this.props.name; - if (this.props.type === 'radio' && name != null) { - var rootNode = this.getDOMNode(); - var queryRoot = rootNode; + var returnValue = LinkedValueUtils.executeOnChange(props, event); - while (queryRoot.parentNode) { - queryRoot = queryRoot.parentNode; - } + // Here we use asap to wait until all updates have propagated, which + // is important when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + ReactUpdates.asap(forceUpdateIfMounted, this); - // If `rootNode.form` was non-null, then we could try `form.elements`, - // but that sometimes behaves strangely in IE8. We could also try using - // `form.getElementsByName`, but that will only return direct children - // and won't include inputs that use the HTML5 `form=` attribute. Since - // the input might not even be in a form, let's just use the global - // `querySelectorAll` to ensure we don't miss anything. - var group = queryRoot.querySelectorAll( - 'input[name=' + JSON.stringify('' + name) + '][type="radio"]'); + var name = props.name; + if (props.type === 'radio' && name != null) { + var rootNode = ReactMount.getNode(this._rootNodeID); + var queryRoot = rootNode; - for (var i = 0, groupLen = group.length; i < groupLen; i++) { - var otherNode = group[i]; - if (otherNode === rootNode || - otherNode.form !== rootNode.form) { - continue; - } - var otherID = ReactMount.getID(otherNode); - ("production" !== process.env.NODE_ENV ? invariant( - otherID, - 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + - 'same `name` is not supported.' - ) : invariant(otherID)); - var otherInstance = instancesByReactID[otherID]; - ("production" !== process.env.NODE_ENV ? invariant( - otherInstance, - 'ReactDOMInput: Unknown radio button ID %s.', - otherID - ) : invariant(otherInstance)); - // If this is a controlled radio button group, forcing the input that - // was previously checked to update will cause it to be come re-checked - // as appropriate. - ReactUpdates.asap(forceUpdateIfMounted, otherInstance); - } + while (queryRoot.parentNode) { + queryRoot = queryRoot.parentNode; } - return returnValue; + // If `rootNode.form` was non-null, then we could try `form.elements`, + // but that sometimes behaves strangely in IE8. We could also try using + // `form.getElementsByName`, but that will only return direct children + // and won't include inputs that use the HTML5 `form=` attribute. Since + // the input might not even be in a form, let's just use the global + // `querySelectorAll` to ensure we don't miss anything. + var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); + + for (var i = 0; i < group.length; i++) { + var otherNode = group[i]; + if (otherNode === rootNode || otherNode.form !== rootNode.form) { + continue; + } + // This will throw if radio buttons rendered by different copies of React + // and the same name are rendered into the same form (same as #1939). + // That's probably okay; we don't support it just as we don't support + // mixing React with non-React. + var otherID = ReactMount.getID(otherNode); + !otherID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined; + var otherInstance = instancesByReactID[otherID]; + !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined; + // If this is a controlled radio button group, forcing the input that + // was previously checked to update will cause it to be come re-checked + // as appropriate. + ReactUpdates.asap(forceUpdateIfMounted, otherInstance); + } } -}); + return returnValue; +} module.exports = ReactDOMInput; - }).call(this,require('_process')) -},{"./AutoFocusMixin":42,"./DOMPropertyOperations":52,"./LinkedValueUtils":66,"./Object.assign":69,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103,"./ReactMount":117,"./ReactUpdates":140,"./invariant":191,"_process":1}],94:[function(require,module,exports){ +},{"./LinkedValueUtils":81,"./Object.assign":82,"./ReactDOMIDOperations":103,"./ReactMount":130,"./ReactUpdates":154,"_process":1,"fbjs/lib/invariant":220}],105:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -12249,45 +13154,86 @@ module.exports = ReactDOMInput; 'use strict'; -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); +var ReactChildren = require('./ReactChildren'); +var ReactDOMSelect = require('./ReactDOMSelect'); -var warning = require("./warning"); +var assign = require('./Object.assign'); +var warning = require('fbjs/lib/warning'); -var option = ReactElement.createFactory('option'); +var valueContextKey = ReactDOMSelect.valueContextKey; /** * Implements an <option> native component that warns when `selected` is set. */ -var ReactDOMOption = ReactClass.createClass({ - displayName: 'ReactDOMOption', - tagName: 'OPTION', - - mixins: [ReactBrowserComponentMixin], - - componentWillMount: function() { +var ReactDOMOption = { + mountWrapper: function (inst, props, context) { // TODO (yungsters): Remove support for `selected` in <option>. - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - this.props.selected == null, - 'Use the `defaultValue` or `value` props on <select> instead of ' + - 'setting `selected` on <option>.' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined; + } + + // Look up whether this option is 'selected' via context + var selectValue = context[valueContextKey]; + + // If context key is null (e.g., no specified value or after initial mount) + // or missing (e.g., for <datalist>), we don't change props.selected + var selected = null; + if (selectValue != null) { + selected = false; + if (Array.isArray(selectValue)) { + // multiple + for (var i = 0; i < selectValue.length; i++) { + if ('' + selectValue[i] === '' + props.value) { + selected = true; + break; + } + } + } else { + selected = '' + selectValue === '' + props.value; + } } + + inst._wrapperState = { selected: selected }; }, - render: function() { - return option(this.props, this.props.children); + getNativeProps: function (inst, props, context) { + var nativeProps = assign({ selected: undefined, children: undefined }, props); + + // Read state only from initial mount because <select> updates value + // manually; we need the initial state only for server rendering + if (inst._wrapperState.selected != null) { + nativeProps.selected = inst._wrapperState.selected; + } + + var content = ''; + + // Flatten children and warn if they aren't strings or numbers; + // invalid types are ignored. + ReactChildren.forEach(props.children, function (child) { + if (child == null) { + return; + } + if (typeof child === 'string' || typeof child === 'number') { + content += child; + } else { + process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined; + } + }); + + if (content) { + nativeProps.children = content; + } + + return nativeProps; } -}); +}; module.exports = ReactDOMOption; - }).call(this,require('_process')) -},{"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103,"./warning":212,"_process":1}],95:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactChildren":90,"./ReactDOMSelect":106,"_process":1,"fbjs/lib/warning":232}],106:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -12301,68 +13247,77 @@ module.exports = ReactDOMOption; 'use strict'; -var AutoFocusMixin = require("./AutoFocusMixin"); -var LinkedValueUtils = require("./LinkedValueUtils"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); -var ReactUpdates = require("./ReactUpdates"); +var LinkedValueUtils = require('./LinkedValueUtils'); +var ReactMount = require('./ReactMount'); +var ReactUpdates = require('./ReactUpdates'); -var assign = require("./Object.assign"); +var assign = require('./Object.assign'); +var warning = require('fbjs/lib/warning'); -var select = ReactElement.createFactory('select'); +var valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2); function updateOptionsIfPendingUpdateAndMounted() { - /*jshint validthis:true */ - if (this._pendingUpdate) { - this._pendingUpdate = false; - var value = LinkedValueUtils.getValue(this); - if (value != null && this.isMounted()) { - updateOptions(this, value); + if (this._rootNodeID && this._wrapperState.pendingUpdate) { + this._wrapperState.pendingUpdate = false; + + var props = this._currentElement.props; + var value = LinkedValueUtils.getValue(props); + + if (value != null) { + updateOptions(this, Boolean(props.multiple), value); + } + } +} + +function getDeclarationErrorAddendum(owner) { + if (owner) { + var name = owner.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; } } + return ''; } +var valuePropNames = ['value', 'defaultValue']; + /** * Validation function for `value` and `defaultValue`. * @private */ -function selectValueType(props, propName, componentName) { - if (props[propName] == null) { - return null; - } - if (props.multiple) { - if (!Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be an array if ") + - ("`multiple` is true.") - ); +function checkSelectPropTypes(inst, props) { + var owner = inst._currentElement._owner; + LinkedValueUtils.checkPropTypes('select', props, owner); + + for (var i = 0; i < valuePropNames.length; i++) { + var propName = valuePropNames[i]; + if (props[propName] == null) { + continue; } - } else { - if (Array.isArray(props[propName])) { - return new Error( - ("The `" + propName + "` prop supplied to <select> must be a scalar ") + - ("value if `multiple` is false.") - ); + if (props.multiple) { + process.env.NODE_ENV !== 'production' ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : undefined; + } else { + process.env.NODE_ENV !== 'production' ? warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : undefined; } } } /** - * @param {ReactComponent} component Instance of ReactDOMSelect + * @param {ReactDOMComponent} inst + * @param {boolean} multiple * @param {*} propValue A stringable (with `multiple`, a list of stringables). * @private */ -function updateOptions(component, propValue) { - var selectedValue, i, l; - var options = component.getDOMNode().options; +function updateOptions(inst, multiple, propValue) { + var selectedValue, i; + var options = ReactMount.getNode(inst._rootNodeID).options; - if (component.props.multiple) { + if (multiple) { selectedValue = {}; - for (i = 0, l = propValue.length; i < l; i++) { + for (i = 0; i < propValue.length; i++) { selectedValue['' + propValue[i]] = true; } - for (i = 0, l = options.length; i < l; i++) { + for (i = 0; i < options.length; i++) { var selected = selectedValue.hasOwnProperty(options[i].value); if (options[i].selected !== selected) { options[i].selected = selected; @@ -12372,7 +13327,7 @@ function updateOptions(component, propValue) { // Do not set `select.value` as exact behavior isn't consistent across all // browsers for all cases. selectedValue = '' + propValue; - for (i = 0, l = options.length; i < l; i++) { + for (i = 0; i < options.length; i++) { if (options[i].value === selectedValue) { options[i].selected = true; return; @@ -12399,73 +13354,77 @@ function updateOptions(component, propValue) { * If `defaultValue` is provided, any options with the supplied values will be * selected. */ -var ReactDOMSelect = ReactClass.createClass({ - displayName: 'ReactDOMSelect', - tagName: 'SELECT', - - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], +var ReactDOMSelect = { + valueContextKey: valueContextKey, - propTypes: { - defaultValue: selectValueType, - value: selectValueType + getNativeProps: function (inst, props, context) { + return assign({}, props, { + onChange: inst._wrapperState.onChange, + value: undefined + }); }, - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - props.onChange = this._handleChange; - props.value = null; + mountWrapper: function (inst, props) { + if (process.env.NODE_ENV !== 'production') { + checkSelectPropTypes(inst, props); + } - return select(props, this.props.children); + var value = LinkedValueUtils.getValue(props); + inst._wrapperState = { + pendingUpdate: false, + initialValue: value != null ? value : props.defaultValue, + onChange: _handleChange.bind(inst), + wasMultiple: Boolean(props.multiple) + }; }, - componentWillMount: function() { - this._pendingUpdate = false; + processChildContext: function (inst, props, context) { + // Pass down initial value so initial generated markup has correct + // `selected` attributes + var childContext = assign({}, context); + childContext[valueContextKey] = inst._wrapperState.initialValue; + return childContext; }, - componentDidMount: function() { - var value = LinkedValueUtils.getValue(this); - if (value != null) { - updateOptions(this, value); - } else if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); - } - }, + postUpdateWrapper: function (inst) { + var props = inst._currentElement.props; - componentDidUpdate: function(prevProps) { - var value = LinkedValueUtils.getValue(this); + // After the initial mount, we control selected-ness manually so don't pass + // the context value down + inst._wrapperState.initialValue = undefined; + + var wasMultiple = inst._wrapperState.wasMultiple; + inst._wrapperState.wasMultiple = Boolean(props.multiple); + + var value = LinkedValueUtils.getValue(props); if (value != null) { - this._pendingUpdate = false; - updateOptions(this, value); - } else if (!prevProps.multiple !== !this.props.multiple) { + inst._wrapperState.pendingUpdate = false; + updateOptions(inst, Boolean(props.multiple), value); + } else if (wasMultiple !== Boolean(props.multiple)) { // For simplicity, reapply `defaultValue` if `multiple` is toggled. - if (this.props.defaultValue != null) { - updateOptions(this, this.props.defaultValue); + if (props.defaultValue != null) { + updateOptions(inst, Boolean(props.multiple), props.defaultValue); } else { // Revert the select back to its default unselected state. - updateOptions(this, this.props.multiple ? [] : ''); + updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : ''); } } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); - } - - this._pendingUpdate = true; - ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); - return returnValue; } +}; -}); +function _handleChange(event) { + var props = this._currentElement.props; + var returnValue = LinkedValueUtils.executeOnChange(props, event); + + this._wrapperState.pendingUpdate = true; + ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); + return returnValue; +} module.exports = ReactDOMSelect; +}).call(this,require('_process')) -},{"./AutoFocusMixin":42,"./LinkedValueUtils":66,"./Object.assign":69,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103,"./ReactUpdates":140}],96:[function(require,module,exports){ +},{"./LinkedValueUtils":81,"./Object.assign":82,"./ReactMount":130,"./ReactUpdates":154,"_process":1,"fbjs/lib/warning":232}],107:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -12479,10 +13438,10 @@ module.exports = ReactDOMSelect; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); -var getNodeForCharacterOffset = require("./getNodeForCharacterOffset"); -var getTextContentAccessor = require("./getTextContentAccessor"); +var getNodeForCharacterOffset = require('./getNodeForCharacterOffset'); +var getTextContentAccessor = require('./getTextContentAccessor'); /** * While `isCollapsed` is available on the Selection object and `collapsed` @@ -12544,15 +13503,26 @@ function getModernOffsets(node) { var currentRange = selection.getRangeAt(0); + // In Firefox, range.startContainer and range.endContainer can be "anonymous + // divs", e.g. the up/down buttons on an <input type="number">. Anonymous + // divs do not seem to expose properties, triggering a "Permission denied + // error" if any of its properties are accessed. The only seemingly possible + // way to avoid erroring is to access a property that typically works for + // non-anonymous divs and catch any error that may otherwise arise. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + try { + /* eslint-disable no-unused-expressions */ + currentRange.startContainer.nodeType; + currentRange.endContainer.nodeType; + /* eslint-enable no-unused-expressions */ + } catch (e) { + return null; + } + // If the node and offset values are the same, the selection is collapsed. // `Selection.isCollapsed` is available natively, but IE sometimes gets // this value wrong. - var isSelectionCollapsed = isCollapsed( - selection.anchorNode, - selection.anchorOffset, - selection.focusNode, - selection.focusOffset - ); + var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset); var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; @@ -12560,12 +13530,7 @@ function getModernOffsets(node) { tempRange.selectNodeContents(node); tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); - var isTempRangeCollapsed = isCollapsed( - tempRange.startContainer, - tempRange.startOffset, - tempRange.endContainer, - tempRange.endOffset - ); + var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset); var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; var end = start + rangeLength; @@ -12628,8 +13593,7 @@ function setModernOffsets(node, offsets) { var selection = window.getSelection(); var length = node[getTextContentAccessor()].length; var start = Math.min(offsets.start, length); - var end = typeof offsets.end === 'undefined' ? - start : Math.min(offsets.end, length); + var end = typeof offsets.end === 'undefined' ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method. // Flip backward selections, so we can set with a single range. @@ -12657,11 +13621,7 @@ function setModernOffsets(node, offsets) { } } -var useIEOffsets = ( - ExecutionEnvironment.canUseDOM && - 'selection' in document && - !('getSelection' in window) -); +var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window); var ReactDOMSelection = { /** @@ -12677,8 +13637,35 @@ var ReactDOMSelection = { }; module.exports = ReactDOMSelection; +},{"./getNodeForCharacterOffset":189,"./getTextContentAccessor":190,"fbjs/lib/ExecutionEnvironment":206}],108:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMServer + */ -},{"./ExecutionEnvironment":62,"./getNodeForCharacterOffset":184,"./getTextContentAccessor":186}],97:[function(require,module,exports){ +'use strict'; + +var ReactDefaultInjection = require('./ReactDefaultInjection'); +var ReactServerRendering = require('./ReactServerRendering'); +var ReactVersion = require('./ReactVersion'); + +ReactDefaultInjection.inject(); + +var ReactDOMServer = { + renderToString: ReactServerRendering.renderToString, + renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup, + version: ReactVersion +}; + +module.exports = ReactDOMServer; +},{"./ReactDefaultInjection":112,"./ReactServerRendering":146,"./ReactVersion":155}],109:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -12693,13 +13680,15 @@ module.exports = ReactDOMSelection; 'use strict'; -var DOMPropertyOperations = require("./DOMPropertyOperations"); -var ReactComponentBrowserEnvironment = - require("./ReactComponentBrowserEnvironment"); -var ReactDOMComponent = require("./ReactDOMComponent"); +var DOMChildrenOperations = require('./DOMChildrenOperations'); +var DOMPropertyOperations = require('./DOMPropertyOperations'); +var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment'); +var ReactMount = require('./ReactMount'); -var assign = require("./Object.assign"); -var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); +var assign = require('./Object.assign'); +var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); +var setTextContent = require('./setTextContent'); +var validateDOMNesting = require('./validateDOMNesting'); /** * Text nodes violate a couple assumptions that React makes about components: @@ -12716,7 +13705,7 @@ var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); * @extends ReactComponent * @internal */ -var ReactDOMTextComponent = function(props) { +var ReactDOMTextComponent = function (props) { // This constructor and its argument is currently used by mocks. }; @@ -12726,7 +13715,7 @@ assign(ReactDOMTextComponent.prototype, { * @param {ReactText} text * @internal */ - construct: function(text) { + construct: function (text) { // TODO: This is really a ReactText (ReactNode), not a ReactElement this._currentElement = text; this._stringText = '' + text; @@ -12745,22 +13734,34 @@ assign(ReactDOMTextComponent.prototype, { * @return {string} Markup for this text node. * @internal */ - mountComponent: function(rootID, transaction, context) { + mountComponent: function (rootID, transaction, context) { + if (process.env.NODE_ENV !== 'production') { + if (context[validateDOMNesting.ancestorInfoContextKey]) { + validateDOMNesting('span', null, context[validateDOMNesting.ancestorInfoContextKey]); + } + } + this._rootNodeID = rootID; - var escapedText = escapeTextContentForBrowser(this._stringText); + if (transaction.useCreateElement) { + var ownerDocument = context[ReactMount.ownerDocumentContextKey]; + var el = ownerDocument.createElement('span'); + DOMPropertyOperations.setAttributeForID(el, rootID); + // Populate node cache + ReactMount.getID(el); + setTextContent(el, this._stringText); + return el; + } else { + var escapedText = escapeTextContentForBrowser(this._stringText); - if (transaction.renderToStaticMarkup) { - // Normally we'd wrap this in a `span` for the reasons stated above, but - // since this is a situation where React won't take over (static pages), - // we can simply return the text as it is. - return escapedText; - } + if (transaction.renderToStaticMarkup) { + // Normally we'd wrap this in a `span` for the reasons stated above, but + // since this is a situation where React won't take over (static pages), + // we can simply return the text as it is. + return escapedText; + } - return ( - '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + - escapedText + - '</span>' - ); + return '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + escapedText + '</span>'; + } }, /** @@ -12770,7 +13771,7 @@ assign(ReactDOMTextComponent.prototype, { * @param {ReactReconcileTransaction} transaction * @internal */ - receiveComponent: function(nextText, transaction) { + receiveComponent: function (nextText, transaction) { if (nextText !== this._currentElement) { this._currentElement = nextText; var nextStringText = '' + nextText; @@ -12779,23 +13780,22 @@ assign(ReactDOMTextComponent.prototype, { // and/or updateComponent to do the actual update for consistency with // other component types? this._stringText = nextStringText; - ReactDOMComponent.BackendIDOperations.updateTextContentByID( - this._rootNodeID, - nextStringText - ); + var node = ReactMount.getNode(this._rootNodeID); + DOMChildrenOperations.updateTextContent(node, nextStringText); } } }, - unmountComponent: function() { + unmountComponent: function () { ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); } }); module.exports = ReactDOMTextComponent; +}).call(this,require('_process')) -},{"./DOMPropertyOperations":52,"./Object.assign":69,"./ReactComponentBrowserEnvironment":80,"./ReactDOMComponent":88,"./escapeTextContentForBrowser":172}],98:[function(require,module,exports){ +},{"./DOMChildrenOperations":67,"./DOMPropertyOperations":69,"./Object.assign":82,"./ReactComponentBrowserEnvironment":93,"./ReactMount":130,"./escapeTextContentForBrowser":180,"./setTextContent":198,"./validateDOMNesting":203,"_process":1}],110:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -12810,25 +13810,18 @@ module.exports = ReactDOMTextComponent; 'use strict'; -var AutoFocusMixin = require("./AutoFocusMixin"); -var DOMPropertyOperations = require("./DOMPropertyOperations"); -var LinkedValueUtils = require("./LinkedValueUtils"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); -var ReactUpdates = require("./ReactUpdates"); +var LinkedValueUtils = require('./LinkedValueUtils'); +var ReactDOMIDOperations = require('./ReactDOMIDOperations'); +var ReactUpdates = require('./ReactUpdates'); -var assign = require("./Object.assign"); -var invariant = require("./invariant"); - -var warning = require("./warning"); - -var textarea = ReactElement.createFactory('textarea'); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); function forceUpdateIfMounted() { - /*jshint validthis:true */ - if (this.isMounted()) { - this.forceUpdate(); + if (this._rootNodeID) { + // DOM component is still mounted; update + ReactDOMTextarea.updateWrapper(this); } } @@ -12847,33 +13840,37 @@ function forceUpdateIfMounted() { * The rendered element will be initialized with an empty value, the prop * `defaultValue` if specified, or the children content (deprecated). */ -var ReactDOMTextarea = ReactClass.createClass({ - displayName: 'ReactDOMTextarea', - tagName: 'TEXTAREA', +var ReactDOMTextarea = { + getNativeProps: function (inst, props, context) { + !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined; + + // Always set children to the same thing. In IE9, the selection range will + // get reset if `textContent` is mutated. + var nativeProps = assign({}, props, { + defaultValue: undefined, + value: undefined, + children: inst._wrapperState.initialValue, + onChange: inst._wrapperState.onChange + }); + + return nativeProps; + }, - mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], + mountWrapper: function (inst, props) { + if (process.env.NODE_ENV !== 'production') { + LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner); + } - getInitialState: function() { - var defaultValue = this.props.defaultValue; + var defaultValue = props.defaultValue; // TODO (yungsters): Remove support for children content in <textarea>. - var children = this.props.children; + var children = props.children; if (children != null) { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Use the `defaultValue` or `value` props instead of setting ' + - 'children on <textarea>.' - ) : null); - } - ("production" !== process.env.NODE_ENV ? invariant( - defaultValue == null, - 'If you supply `defaultValue` on a <textarea>, do not pass children.' - ) : invariant(defaultValue == null)); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : undefined; + } + !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : invariant(false) : undefined; if (Array.isArray(children)) { - ("production" !== process.env.NODE_ENV ? invariant( - children.length <= 1, - '<textarea> can only have at most one child.' - ) : invariant(children.length <= 1)); + !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : invariant(false) : undefined; children = children[0]; } @@ -12882,61 +13879,40 @@ var ReactDOMTextarea = ReactClass.createClass({ if (defaultValue == null) { defaultValue = ''; } - var value = LinkedValueUtils.getValue(this); - return { + var value = LinkedValueUtils.getValue(props); + + inst._wrapperState = { // We save the initial value so that `ReactDOMComponent` doesn't update // `textContent` (unnecessary since we update value). // The initial value can be a boolean or object so that's why it's // forced to be a string. - initialValue: '' + (value != null ? value : defaultValue) + initialValue: '' + (value != null ? value : defaultValue), + onChange: _handleChange.bind(inst) }; }, - render: function() { - // Clone `this.props` so we don't mutate the input. - var props = assign({}, this.props); - - ("production" !== process.env.NODE_ENV ? invariant( - props.dangerouslySetInnerHTML == null, - '`dangerouslySetInnerHTML` does not make sense on <textarea>.' - ) : invariant(props.dangerouslySetInnerHTML == null)); - - props.defaultValue = null; - props.value = null; - props.onChange = this._handleChange; - - // Always set children to the same thing. In IE9, the selection range will - // get reset if `textContent` is mutated. - return textarea(props, this.state.initialValue); - }, - - componentDidUpdate: function(prevProps, prevState, prevContext) { - var value = LinkedValueUtils.getValue(this); + updateWrapper: function (inst) { + var props = inst._currentElement.props; + var value = LinkedValueUtils.getValue(props); if (value != null) { - var rootNode = this.getDOMNode(); // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. - DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); - } - }, - - _handleChange: function(event) { - var returnValue; - var onChange = LinkedValueUtils.getOnChange(this); - if (onChange) { - returnValue = onChange.call(this, event); + ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value); } - ReactUpdates.asap(forceUpdateIfMounted, this); - return returnValue; } +}; -}); +function _handleChange(event) { + var props = this._currentElement.props; + var returnValue = LinkedValueUtils.executeOnChange(props, event); + ReactUpdates.asap(forceUpdateIfMounted, this); + return returnValue; +} module.exports = ReactDOMTextarea; - }).call(this,require('_process')) -},{"./AutoFocusMixin":42,"./DOMPropertyOperations":52,"./LinkedValueUtils":66,"./Object.assign":69,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactElement":103,"./ReactUpdates":140,"./invariant":191,"./warning":212,"_process":1}],99:[function(require,module,exports){ +},{"./LinkedValueUtils":81,"./Object.assign":82,"./ReactDOMIDOperations":103,"./ReactUpdates":154,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],111:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -12950,15 +13926,15 @@ module.exports = ReactDOMTextarea; 'use strict'; -var ReactUpdates = require("./ReactUpdates"); -var Transaction = require("./Transaction"); +var ReactUpdates = require('./ReactUpdates'); +var Transaction = require('./Transaction'); -var assign = require("./Object.assign"); -var emptyFunction = require("./emptyFunction"); +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); var RESET_BATCHED_UPDATES = { initialize: emptyFunction, - close: function() { + close: function () { ReactDefaultBatchingStrategy.isBatchingUpdates = false; } }; @@ -12974,15 +13950,11 @@ function ReactDefaultBatchingStrategyTransaction() { this.reinitializeTransaction(); } -assign( - ReactDefaultBatchingStrategyTransaction.prototype, - Transaction.Mixin, - { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - } +assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction.Mixin, { + getTransactionWrappers: function () { + return TRANSACTION_WRAPPERS; } -); +}); var transaction = new ReactDefaultBatchingStrategyTransaction(); @@ -12993,23 +13965,22 @@ var ReactDefaultBatchingStrategy = { * 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) { + batchedUpdates: function (callback, a, b, c, d, e) { var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; ReactDefaultBatchingStrategy.isBatchingUpdates = true; // The code is written this way to avoid extra allocations if (alreadyBatchingUpdates) { - callback(a, b, c, d); + callback(a, b, c, d, e); } else { - transaction.perform(callback, null, a, b, c, d); + transaction.perform(callback, null, a, b, c, d, e); } } }; module.exports = ReactDefaultBatchingStrategy; - -},{"./Object.assign":69,"./ReactUpdates":140,"./Transaction":157,"./emptyFunction":170}],100:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactUpdates":154,"./Transaction":172,"fbjs/lib/emptyFunction":212}],112:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -13024,63 +13995,40 @@ module.exports = ReactDefaultBatchingStrategy; 'use strict'; -var BeforeInputEventPlugin = require("./BeforeInputEventPlugin"); -var ChangeEventPlugin = require("./ChangeEventPlugin"); -var ClientReactRootIndex = require("./ClientReactRootIndex"); -var DefaultEventPluginOrder = require("./DefaultEventPluginOrder"); -var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var HTMLDOMPropertyConfig = require("./HTMLDOMPropertyConfig"); -var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactComponentBrowserEnvironment = - require("./ReactComponentBrowserEnvironment"); -var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy"); -var ReactDOMComponent = require("./ReactDOMComponent"); -var ReactDOMButton = require("./ReactDOMButton"); -var ReactDOMForm = require("./ReactDOMForm"); -var ReactDOMImg = require("./ReactDOMImg"); -var ReactDOMIDOperations = require("./ReactDOMIDOperations"); -var ReactDOMIframe = require("./ReactDOMIframe"); -var ReactDOMInput = require("./ReactDOMInput"); -var ReactDOMOption = require("./ReactDOMOption"); -var ReactDOMSelect = require("./ReactDOMSelect"); -var ReactDOMTextarea = require("./ReactDOMTextarea"); -var ReactDOMTextComponent = require("./ReactDOMTextComponent"); -var ReactElement = require("./ReactElement"); -var ReactEventListener = require("./ReactEventListener"); -var ReactInjection = require("./ReactInjection"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactMount = require("./ReactMount"); -var ReactReconcileTransaction = require("./ReactReconcileTransaction"); -var SelectEventPlugin = require("./SelectEventPlugin"); -var ServerReactRootIndex = require("./ServerReactRootIndex"); -var SimpleEventPlugin = require("./SimpleEventPlugin"); -var SVGDOMPropertyConfig = require("./SVGDOMPropertyConfig"); - -var createFullPageComponent = require("./createFullPageComponent"); - -function autoGenerateWrapperClass(type) { - return ReactClass.createClass({ - tagName: type.toUpperCase(), - render: function() { - return new ReactElement( - type, - null, - null, - null, - null, - this.props - ); - } - }); -} +var BeforeInputEventPlugin = require('./BeforeInputEventPlugin'); +var ChangeEventPlugin = require('./ChangeEventPlugin'); +var ClientReactRootIndex = require('./ClientReactRootIndex'); +var DefaultEventPluginOrder = require('./DefaultEventPluginOrder'); +var EnterLeaveEventPlugin = require('./EnterLeaveEventPlugin'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var HTMLDOMPropertyConfig = require('./HTMLDOMPropertyConfig'); +var ReactBrowserComponentMixin = require('./ReactBrowserComponentMixin'); +var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment'); +var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy'); +var ReactDOMComponent = require('./ReactDOMComponent'); +var ReactDOMTextComponent = require('./ReactDOMTextComponent'); +var ReactEventListener = require('./ReactEventListener'); +var ReactInjection = require('./ReactInjection'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactMount = require('./ReactMount'); +var ReactReconcileTransaction = require('./ReactReconcileTransaction'); +var SelectEventPlugin = require('./SelectEventPlugin'); +var ServerReactRootIndex = require('./ServerReactRootIndex'); +var SimpleEventPlugin = require('./SimpleEventPlugin'); +var SVGDOMPropertyConfig = require('./SVGDOMPropertyConfig'); + +var alreadyInjected = false; function inject() { - ReactInjection.EventEmitter.injectReactEventListener( - ReactEventListener - ); + if (alreadyInjected) { + // TODO: This is currently true because these injections are shared between + // the client and the server package. They should be built independently + // and not share any injection state. Then this problem will be solved. + return; + } + alreadyInjected = true; + + ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener); /** * Inject modules for resolving DOM hierarchy and plugin ordering. @@ -13097,67 +14045,32 @@ function inject() { SimpleEventPlugin: SimpleEventPlugin, EnterLeaveEventPlugin: EnterLeaveEventPlugin, ChangeEventPlugin: ChangeEventPlugin, - MobileSafariClickEventPlugin: MobileSafariClickEventPlugin, SelectEventPlugin: SelectEventPlugin, BeforeInputEventPlugin: BeforeInputEventPlugin }); - ReactInjection.NativeComponent.injectGenericComponentClass( - ReactDOMComponent - ); - - ReactInjection.NativeComponent.injectTextComponentClass( - ReactDOMTextComponent - ); + ReactInjection.NativeComponent.injectGenericComponentClass(ReactDOMComponent); - ReactInjection.NativeComponent.injectAutoWrapper( - autoGenerateWrapperClass - ); + ReactInjection.NativeComponent.injectTextComponentClass(ReactDOMTextComponent); - // This needs to happen before createFullPageComponent() otherwise the mixin - // won't be included. ReactInjection.Class.injectMixin(ReactBrowserComponentMixin); - ReactInjection.NativeComponent.injectComponentClasses({ - 'button': ReactDOMButton, - 'form': ReactDOMForm, - 'iframe': ReactDOMIframe, - 'img': ReactDOMImg, - 'input': ReactDOMInput, - 'option': ReactDOMOption, - 'select': ReactDOMSelect, - 'textarea': ReactDOMTextarea, - - 'html': createFullPageComponent('html'), - 'head': createFullPageComponent('head'), - 'body': createFullPageComponent('body') - }); - ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); ReactInjection.EmptyComponent.injectEmptyComponent('noscript'); - ReactInjection.Updates.injectReconcileTransaction( - ReactReconcileTransaction - ); - ReactInjection.Updates.injectBatchingStrategy( - ReactDefaultBatchingStrategy - ); + ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction); + ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); - ReactInjection.RootIndex.injectCreateReactRootIndex( - ExecutionEnvironment.canUseDOM ? - ClientReactRootIndex.createReactRootIndex : - ServerReactRootIndex.createReactRootIndex - ); + ReactInjection.RootIndex.injectCreateReactRootIndex(ExecutionEnvironment.canUseDOM ? ClientReactRootIndex.createReactRootIndex : ServerReactRootIndex.createReactRootIndex); ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); - ReactInjection.DOMComponent.injectIDOperations(ReactDOMIDOperations); - if ("production" !== process.env.NODE_ENV) { - var url = (ExecutionEnvironment.canUseDOM && window.location.href) || ''; - if ((/[?&]react_perf\b/).test(url)) { - var ReactDefaultPerf = require("./ReactDefaultPerf"); + if (process.env.NODE_ENV !== 'production') { + var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; + if (/[?&]react_perf\b/.test(url)) { + var ReactDefaultPerf = require('./ReactDefaultPerf'); ReactDefaultPerf.start(); } } @@ -13166,10 +14079,9 @@ function inject() { module.exports = { inject: inject }; - }).call(this,require('_process')) -},{"./BeforeInputEventPlugin":43,"./ChangeEventPlugin":48,"./ClientReactRootIndex":49,"./DefaultEventPluginOrder":54,"./EnterLeaveEventPlugin":55,"./ExecutionEnvironment":62,"./HTMLDOMPropertyConfig":64,"./MobileSafariClickEventPlugin":68,"./ReactBrowserComponentMixin":72,"./ReactClass":78,"./ReactComponentBrowserEnvironment":80,"./ReactDOMButton":87,"./ReactDOMComponent":88,"./ReactDOMForm":89,"./ReactDOMIDOperations":90,"./ReactDOMIframe":91,"./ReactDOMImg":92,"./ReactDOMInput":93,"./ReactDOMOption":94,"./ReactDOMSelect":95,"./ReactDOMTextComponent":97,"./ReactDOMTextarea":98,"./ReactDefaultBatchingStrategy":99,"./ReactDefaultPerf":101,"./ReactElement":103,"./ReactEventListener":108,"./ReactInjection":110,"./ReactInstanceHandles":112,"./ReactMount":117,"./ReactReconcileTransaction":128,"./SVGDOMPropertyConfig":142,"./SelectEventPlugin":143,"./ServerReactRootIndex":144,"./SimpleEventPlugin":145,"./createFullPageComponent":166,"_process":1}],101:[function(require,module,exports){ +},{"./BeforeInputEventPlugin":61,"./ChangeEventPlugin":65,"./ClientReactRootIndex":66,"./DefaultEventPluginOrder":71,"./EnterLeaveEventPlugin":72,"./HTMLDOMPropertyConfig":79,"./ReactBrowserComponentMixin":85,"./ReactComponentBrowserEnvironment":93,"./ReactDOMComponent":100,"./ReactDOMTextComponent":109,"./ReactDefaultBatchingStrategy":111,"./ReactDefaultPerf":113,"./ReactEventListener":121,"./ReactInjection":123,"./ReactInstanceHandles":125,"./ReactMount":130,"./ReactReconcileTransaction":141,"./SVGDOMPropertyConfig":157,"./SelectEventPlugin":158,"./ServerReactRootIndex":159,"./SimpleEventPlugin":160,"_process":1,"fbjs/lib/ExecutionEnvironment":206}],113:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -13184,12 +14096,12 @@ module.exports = { 'use strict'; -var DOMProperty = require("./DOMProperty"); -var ReactDefaultPerfAnalysis = require("./ReactDefaultPerfAnalysis"); -var ReactMount = require("./ReactMount"); -var ReactPerf = require("./ReactPerf"); +var DOMProperty = require('./DOMProperty'); +var ReactDefaultPerfAnalysis = require('./ReactDefaultPerfAnalysis'); +var ReactMount = require('./ReactMount'); +var ReactPerf = require('./ReactPerf'); -var performanceNow = require("./performanceNow"); +var performanceNow = require('fbjs/lib/performanceNow'); function roundFloat(val) { return Math.floor(val * 100) / 100; @@ -13204,7 +14116,7 @@ var ReactDefaultPerf = { _mountStack: [0], _injected: false, - start: function() { + start: function () { if (!ReactDefaultPerf._injected) { ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); } @@ -13213,18 +14125,18 @@ var ReactDefaultPerf = { ReactPerf.enableMeasure = true; }, - stop: function() { + stop: function () { ReactPerf.enableMeasure = false; }, - getLastMeasurements: function() { + getLastMeasurements: function () { return ReactDefaultPerf._allMeasurements; }, - printExclusive: function(measurements) { + printExclusive: function (measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); - console.table(summary.map(function(item) { + console.table(summary.map(function (item) { return { 'Component class name': item.componentName, 'Total inclusive time (ms)': roundFloat(item.inclusive), @@ -13239,28 +14151,22 @@ var ReactDefaultPerf = { // number. }, - printInclusive: function(measurements) { + printInclusive: function (measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); - console.table(summary.map(function(item) { + console.table(summary.map(function (item) { return { 'Owner > component': item.componentName, 'Inclusive time (ms)': roundFloat(item.time), 'Instances': item.count }; })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); + console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); }, - getMeasurementsSummaryMap: function(measurements) { - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( - measurements, - true - ); - return summary.map(function(item) { + getMeasurementsSummaryMap: function (measurements) { + var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements, true); + return summary.map(function (item) { return { 'Owner > component': item.componentName, 'Wasted time (ms)': item.time, @@ -13269,37 +14175,28 @@ var ReactDefaultPerf = { }); }, - printWasted: function(measurements) { + printWasted: function (measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements)); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); + console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); }, - printDOM: function(measurements) { + printDOM: function (measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); - console.table(summary.map(function(item) { + console.table(summary.map(function (item) { var result = {}; result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; - result['type'] = item.type; - result['args'] = JSON.stringify(item.args); + result.type = item.type; + result.args = JSON.stringify(item.args); return result; })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); + console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); }, - _recordWrite: function(id, fnName, totalTime, args) { + _recordWrite: function (id, fnName, totalTime, args) { // TODO: totalTime isn't that useful since it doesn't count paints/reflows - var writes = - ReactDefaultPerf - ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] - .writes; + var writes = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].writes; writes[id] = writes[id] || []; writes[id].push({ type: fnName, @@ -13308,14 +14205,17 @@ var ReactDefaultPerf = { }); }, - measure: function(moduleName, fnName, func) { - return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + measure: function (moduleName, fnName, func) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + var totalTime; var rv; var start; - if (fnName === '_renderNewRootComponent' || - fnName === 'flushBatchedUpdates') { + if (fnName === '_renderNewRootComponent' || fnName === 'flushBatchedUpdates') { // A "measurement" is a set of metrics recorded for each flush. We want // to group the metrics for a given flush together so we can look at the // components that rendered and the DOM operations that actually @@ -13327,16 +14227,14 @@ var ReactDefaultPerf = { counts: {}, writes: {}, displayNames: {}, - totalTime: 0 + totalTime: 0, + created: {} }); start = performanceNow(); rv = func.apply(this, args); - ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ].totalTime = performanceNow() - start; + ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].totalTime = performanceNow() - start; return rv; - } else if (fnName === '_mountImageIntoNode' || - moduleName === 'ReactDOMIDOperations') { + } else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactBrowserEventEmitter' || moduleName === 'ReactDOMIDOperations' || moduleName === 'CSSPropertyOperations' || moduleName === 'DOMChildrenOperations' || moduleName === 'DOMPropertyOperations') { start = performanceNow(); rv = func.apply(this, args); totalTime = performanceNow() - start; @@ -13346,7 +14244,7 @@ var ReactDefaultPerf = { ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); } else if (fnName === 'dangerouslyProcessChildrenUpdates') { // special format - args[0].forEach(function(update) { + args[0].forEach(function (update) { var writeArgs = {}; if (update.fromIndex !== null) { writeArgs.fromIndex = update.fromIndex; @@ -13360,46 +14258,35 @@ var ReactDefaultPerf = { if (update.markupIndex !== null) { writeArgs.markup = args[1][update.markupIndex]; } - ReactDefaultPerf._recordWrite( - update.parentID, - update.type, - totalTime, - writeArgs - ); + ReactDefaultPerf._recordWrite(update.parentID, update.type, totalTime, writeArgs); }); } else { // basic format - ReactDefaultPerf._recordWrite( - args[0], - fnName, - totalTime, - Array.prototype.slice.call(args, 1) - ); + var id = args[0]; + if (typeof id === 'object') { + id = ReactMount.getID(args[0]); + } + ReactDefaultPerf._recordWrite(id, fnName, totalTime, Array.prototype.slice.call(args, 1)); } return rv; - } else if (moduleName === 'ReactCompositeComponent' && ( - (// TODO: receiveComponent()? - (fnName === 'mountComponent' || - fnName === 'updateComponent' || fnName === '_renderValidatedComponent')))) { + } else if (moduleName === 'ReactCompositeComponent' && (fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()? + fnName === '_renderValidatedComponent')) { - if (typeof this._currentElement.type === 'string') { + if (this._currentElement.type === ReactMount.TopLevelWrapper) { return func.apply(this, args); } - var rootNodeID = fnName === 'mountComponent' ? - args[0] : - this._rootNodeID; + var rootNodeID = fnName === 'mountComponent' ? args[0] : this._rootNodeID; var isRender = fnName === '_renderValidatedComponent'; var isMount = fnName === 'mountComponent'; var mountStack = ReactDefaultPerf._mountStack; - var entry = ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ]; + var entry = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]; if (isRender) { addValue(entry.counts, rootNodeID, 1); } else if (isMount) { + entry.created[rootNodeID] = true; mountStack.push(0); } @@ -13420,9 +14307,7 @@ var ReactDefaultPerf = { entry.displayNames[rootNodeID] = { current: this.getName(), - owner: this._currentElement._owner ? - this._currentElement._owner.getName() : - '<root>' + owner: this._currentElement._owner ? this._currentElement._owner.getName() : '<root>' }; return rv; @@ -13434,8 +14319,7 @@ var ReactDefaultPerf = { }; module.exports = ReactDefaultPerf; - -},{"./DOMProperty":51,"./ReactDefaultPerfAnalysis":102,"./ReactMount":117,"./ReactPerf":122,"./performanceNow":203}],102:[function(require,module,exports){ +},{"./DOMProperty":68,"./ReactDefaultPerfAnalysis":114,"./ReactMount":130,"./ReactPerf":136,"fbjs/lib/performanceNow":229}],114:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -13447,7 +14331,9 @@ module.exports = ReactDefaultPerf; * @providesModule ReactDefaultPerfAnalysis */ -var assign = require("./Object.assign"); +'use strict'; + +var assign = require('./Object.assign'); // Don't try to save users less than 1.2ms (a number I made up) var DONT_CARE_THRESHOLD = 1.2; @@ -13456,12 +14342,14 @@ var DOM_OPERATION_TYPES = { INSERT_MARKUP: 'set innerHTML', MOVE_EXISTING: 'move', REMOVE_NODE: 'remove', + SET_MARKUP: 'set innerHTML', TEXT_CONTENT: 'set textContent', - 'updatePropertyByID': 'update attribute', - 'deletePropertyByID': 'delete attribute', - 'updateStylesByID': 'update styles', - 'updateInnerHTMLByID': 'set innerHTML', - 'dangerouslyReplaceNodeWithMarkupByID': 'replace' + 'setValueForProperty': 'update attribute', + 'setValueForAttribute': 'update attribute', + 'deleteValueForProperty': 'remove attribute', + 'setValueForStyles': 'update styles', + 'replaceNodeWithMarkup': 'replace', + 'updateTextContent': 'set textContent' }; function getTotalTime(measurements) { @@ -13479,20 +14367,17 @@ function getTotalTime(measurements) { function getDOMSummary(measurements) { var items = []; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var id; - - for (id in measurement.writes) { - measurement.writes[id].forEach(function(write) { + measurements.forEach(function (measurement) { + Object.keys(measurement.writes).forEach(function (id) { + measurement.writes[id].forEach(function (write) { items.push({ id: id, type: DOM_OPERATION_TYPES[write.type] || write.type, args: write.args }); }); - } - } + }); + }); return items; } @@ -13502,11 +14387,7 @@ function getExclusiveSummary(measurements) { for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); + var allIDs = assign({}, measurement.exclusive, measurement.inclusive); for (var id in allIDs) { displayName = measurement.displayNames[id].current; @@ -13541,7 +14422,7 @@ function getExclusiveSummary(measurements) { } } - arr.sort(function(a, b) { + arr.sort(function (a, b) { return b.exclusive - a.exclusive; }); @@ -13554,11 +14435,7 @@ function getInclusiveSummary(measurements, onlyClean) { for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); + var allIDs = assign({}, measurement.exclusive, measurement.inclusive); var cleanComponents; if (onlyClean) { @@ -13600,7 +14477,7 @@ function getInclusiveSummary(measurements, onlyClean) { } } - arr.sort(function(a, b) { + arr.sort(function (a, b) { return b.time - a.time; }); @@ -13625,6 +14502,10 @@ function getUnchangedComponents(measurement) { break; } } + // check if component newly created + if (measurement.created[id]) { + isDirty = true; + } if (!isDirty && measurement.counts[id] > 0) { cleanComponents[id] = true; } @@ -13640,8 +14521,7 @@ var ReactDefaultPerfAnalysis = { }; module.exports = ReactDefaultPerfAnalysis; - -},{"./Object.assign":69}],103:[function(require,module,exports){ +},{"./Object.assign":82}],115:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -13656,142 +14536,101 @@ module.exports = ReactDefaultPerfAnalysis; 'use strict'; -var ReactContext = require("./ReactContext"); -var ReactCurrentOwner = require("./ReactCurrentOwner"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); + +var assign = require('./Object.assign'); +var canDefineProperty = require('./canDefineProperty'); -var assign = require("./Object.assign"); -var warning = require("./warning"); +// The Symbol used to tag the ReactElement type. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; var RESERVED_PROPS = { key: true, - ref: true + ref: true, + __self: true, + __source: true }; /** - * Warn for mutations. - * - * @internal - * @param {object} object - * @param {string} key - */ -function defineWarningProperty(object, key) { - Object.defineProperty(object, key, { - - configurable: false, - enumerable: true, - - get: function() { - if (!this._store) { - return null; - } - return this._store[key]; - }, - - set: function(value) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Don\'t set the %s property of the React element. Instead, ' + - 'specify the correct value when initially creating the element.', - key - ) : null); - this._store[key] = value; - } - - }); -} - -/** - * This is updated to true if the membrane is successfully created. - */ -var useMutationMembrane = false; - -/** - * Warn for mutations. - * - * @internal - * @param {object} element - */ -function defineMutationMembrane(prototype) { - try { - var pseudoFrozenProperties = { - props: true - }; - for (var key in pseudoFrozenProperties) { - defineWarningProperty(prototype, key); - } - useMutationMembrane = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -/** * Base constructor for all React elements. This is only used to make this * work with a dynamic instanceof check. Nothing should live on this prototype. * * @param {*} type - * @param {string|object} ref * @param {*} key + * @param {string|object} ref + * @param {*} self A *temporary* helper to detect places where `this` is + * different from the `owner` when React.createElement is called, so that we + * can warn. We want to get rid of owner and replace string `ref`s with arrow + * functions, and as long as `this` and owner are the same, there will be no + * change in behavior. + * @param {*} source An annotation object (added by a transpiler or otherwise) + * indicating filename, line number, and/or other information. + * @param {*} owner * @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; +var ReactElement = function (type, key, ref, self, source, owner, props) { + var element = { + // This tag allow us to uniquely identify this as a React Element + $$typeof: REACT_ELEMENT_TYPE, - // Record the component responsible for creating this element. - this._owner = owner; + // Built-in properties that belong on the element + type: type, + key: key, + ref: ref, + props: props, - // TODO: Deprecate withContext, and then the context becomes accessible - // through the owner. - this._context = context; + // Record the component responsible for creating this element. + _owner: owner + }; - if ("production" !== process.env.NODE_ENV) { - // The validation flag and props are currently mutative. We put them on + if (process.env.NODE_ENV !== 'production') { + // The validation flag is currently mutative. We put it 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)}; + element._store = {}; // 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', { + if (canDefineProperty) { + Object.defineProperty(element._store, 'validated', { configurable: false, enumerable: false, - writable: true + writable: true, + value: false }); - } 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; + // self and source are DEV only properties. + Object.defineProperty(element, '_self', { + configurable: false, + enumerable: false, + writable: false, + value: self + }); + // Two elements created in two different places should be considered + // equal for testing purposes and therefore we hide it from enumeration. + Object.defineProperty(element, '_source', { + configurable: false, + enumerable: false, + writable: false, + value: source + }); + } else { + element._store.validated = false; + element._self = self; + element._source = source; } + Object.freeze(element.props); + Object.freeze(element); } - 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 + return element; }; -if ("production" !== process.env.NODE_ENV) { - defineMutationMembrane(ReactElement.prototype); -} - -ReactElement.createElement = function(type, config, children) { +ReactElement.createElement = function (type, config, children) { var propName; // Reserved names are extracted @@ -13799,14 +14638,17 @@ ReactElement.createElement = function(type, config, children) { var key = null; var ref = null; + var self = null; + var source = null; if (config != null) { ref = config.ref === undefined ? null : config.ref; key = config.key === undefined ? null : '' + config.key; + self = config.__self === undefined ? null : config.__self; + source = config.__source === undefined ? null : config.__source; // Remaining properties are added to a new props object for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { + if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } @@ -13835,20 +14677,13 @@ ReactElement.createElement = function(type, config, children) { } } - return new ReactElement( - type, - key, - ref, - ReactCurrentOwner.current, - ReactContext.current, - props - ); + return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); }; -ReactElement.createFactory = function(type) { +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. + // easily accessed on elements. E.g. `<Foo />.type === Foo`. // 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 @@ -13856,24 +14691,24 @@ ReactElement.createFactory = function(type) { return factory; }; -ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { - var newElement = new ReactElement( - oldElement.type, - oldElement.key, - oldElement.ref, - oldElement._owner, - oldElement._context, - newProps - ); +ReactElement.cloneAndReplaceKey = function (oldElement, newKey) { + var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props); + + return newElement; +}; - if ("production" !== process.env.NODE_ENV) { +ReactElement.cloneAndReplaceProps = function (oldElement, newProps) { + var newElement = ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, newProps); + + if (process.env.NODE_ENV !== 'production') { // 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) { +ReactElement.cloneElement = function (element, config, children) { var propName; // Original props are copied @@ -13882,6 +14717,12 @@ ReactElement.cloneElement = function(element, config, children) { // Reserved names are extracted var key = element.key; var ref = element.ref; + // Self is preserved since the owner is preserved. + var self = element._self; + // Source is preserved since cloneElement is unlikely to be targeted by a + // transpiler, and the original source is probably a better indicator of the + // true owner. + var source = element._source; // Owner will be preserved, unless ref is overridden var owner = element._owner; @@ -13897,8 +14738,7 @@ ReactElement.cloneElement = function(element, config, children) { } // Remaining properties override existing props for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { + if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } @@ -13917,14 +14757,7 @@ ReactElement.cloneElement = function(element, config, children) { props.children = childArray; } - return new ReactElement( - element.type, - key, - ref, - owner, - element._context, - props - ); + return ReactElement(element.type, key, ref, self, source, owner, props); }; /** @@ -13932,25 +14765,14 @@ ReactElement.cloneElement = function(element, config, children) { * @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; +ReactElement.isValidElement = function (object) { + return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; }; module.exports = ReactElement; - }).call(this,require('_process')) -},{"./Object.assign":69,"./ReactContext":84,"./ReactCurrentOwner":85,"./warning":212,"_process":1}],104:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactCurrentOwner":97,"./canDefineProperty":176,"_process":1}],116:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -13972,16 +14794,15 @@ module.exports = ReactElement; '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 ReactElement = require('./ReactElement'); +var ReactPropTypeLocations = require('./ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); +var ReactCurrentOwner = require('./ReactCurrentOwner'); -var getIteratorFn = require("./getIteratorFn"); -var invariant = require("./invariant"); -var warning = require("./warning"); +var canDefineProperty = require('./canDefineProperty'); +var getIteratorFn = require('./getIteratorFn'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); function getDeclarationErrorAddendum() { if (ReactCurrentOwner.current) { @@ -14002,39 +14823,6 @@ 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 @@ -14046,84 +14834,59 @@ function getCurrentOwnerDisplayName() { * @param {*} parentType element's parent's type. */ function validateExplicitKey(element, parentType) { - if (element._store.validated || element.key != null) { + if (!element._store || 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)) { + var addenda = getAddendaForKeyUse('uniqueKey', element, parentType); + if (addenda === null) { + // we already showed the warning return; } - warnAndMonitorForKeyUse( - 'Child objects should have non-numeric keys so ordering is preserved.', - element, - parentType - ); + process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined; } /** * Shared warning and monitoring code for the key warnings. * * @internal - * @param {string} message The base warning that gets output. + * @param {string} messageType A key used for de-duping warnings. * @param {ReactElement} element Component that requires a key. * @param {*} parentType element's parent's type. + * @returns {?object} A set of addenda to use in the warning message, or null + * if the warning has already been shown before (and shouldn't be shown again). */ -function warnAndMonitorForKeyUse(message, element, parentType) { - var ownerName = getCurrentOwnerDisplayName(); - var parentName = typeof parentType === 'string' ? - parentType : parentType.displayName || parentType.name; +function getAddendaForKeyUse(messageType, element, parentType) { + var addendum = getDeclarationErrorAddendum(); + if (!addendum) { + var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name; + if (parentName) { + addendum = ' Check the top-level render call using <' + parentName + '>.'; + } + } - var useName = ownerName || parentName; - var memoizer = ownerHasKeyUseWarning[message] || ( - (ownerHasKeyUseWarning[message] = {}) - ); - if (memoizer.hasOwnProperty(useName)) { - return; + var memoizer = ownerHasKeyUseWarning[messageType] || (ownerHasKeyUseWarning[messageType] = {}); + if (memoizer[addendum]) { + return null; } - memoizer[useName] = true; + memoizer[addendum] = true; - var parentOrOwnerAddendum = - ownerName ? (" Check the render method of " + ownerName + ".") : - parentName ? (" Check the React.render call using <" + parentName + ">.") : - ''; + var addenda = { + parentOrOwner: addendum, + url: ' See https://fb.me/react-warning-keys for more information.', + childOwner: null + }; // 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 + "."); + if (element && element._owner && element._owner !== ReactCurrentOwner.current) { + // Give the component that originally created this child. + addenda.childOwner = ' It was passed a child from ' + element._owner.getName() + '.'; } - ("production" !== process.env.NODE_ENV ? warning( - false, - message + '%s%s See https://fb.me/react-warning-keys for more information.', - parentOrOwnerAddendum, - childOwnerAddendum - ) : null); + return addenda; } /** @@ -14136,6 +14899,9 @@ function warnAndMonitorForKeyUse(message, element, parentType) { * @param {*} parentType node's parent's type. */ function validateChildKeys(node, parentType) { + if (typeof node !== 'object') { + return; + } if (Array.isArray(node)) { for (var i = 0; i < node.length; i++) { var child = node[i]; @@ -14145,7 +14911,9 @@ function validateChildKeys(node, parentType) { } } else if (ReactElement.isValidElement(node)) { // This element was passed in a valid location. - node._store.validated = true; + if (node._store) { + node._store.validated = true; + } } else if (node) { var iteratorFn = getIteratorFn(node); // Entry iterators provide implicit keys. @@ -14159,13 +14927,6 @@ function validateChildKeys(node, 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); - } - } } } } @@ -14189,109 +14950,19 @@ function checkPropTypes(componentName, propTypes, props, location) { try { // This is intentionally an invariant that gets caught. It's the same // behavior as without this statement except with a better message. - ("production" !== process.env.NODE_ENV ? invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ) : invariant(typeof propTypes[propName] === 'function')); + !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined; error = propTypes[propName](props, propName, componentName, location); } catch (ex) { error = ex; } + process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], propName, typeof error) : undefined; if (error instanceof Error && !(error.message in loggedTypeFailures)) { // Only monitor this failure once because there tends to be a lot of the // same error. loggedTypeFailures[error.message] = true; - var addendum = getDeclarationErrorAddendum(this); - ("production" !== process.env.NODE_ENV ? warning(false, 'Failed propType: %s%s', error.message, addendum) : null); - } - } - } -} - -var warnedPropsMutations = {}; - -/** - * Warn about mutating props when setting `propName` on `element`. - * - * @param {string} propName The string key within props that was set - * @param {ReactElement} element - */ -function warnForPropsMutation(propName, element) { - var type = element.type; - var elementName = typeof type === 'string' ? type : type.displayName; - var ownerName = element._owner ? - element._owner.getPublicInstance().constructor.displayName : null; - - var warningKey = propName + '|' + elementName + '|' + ownerName; - if (warnedPropsMutations.hasOwnProperty(warningKey)) { - return; - } - warnedPropsMutations[warningKey] = true; - - var elementInfo = ''; - if (elementName) { - elementInfo = ' <' + elementName + ' />'; - } - var ownerInfo = ''; - if (ownerName) { - ownerInfo = ' The element was created by ' + ownerName + '.'; - } - - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + - 'correct value when initially creating the element or use ' + - 'React.cloneElement to make a new element with updated props.%s', - propName, - elementInfo, - ownerInfo - ) : null); -} - -// Inline Object.is polyfill -function is(a, b) { - if (a !== a) { - // NaN - return b !== b; - } - if (a === 0 && b === 0) { - // +-0 - return 1 / a === 1 / b; - } - return a === b; -} - -/** - * Given an element, check if its props have been mutated since element - * creation (or the last call to this function). In particular, check if any - * new props have been added, which we can't directly catch by defining warning - * properties on the props object. - * - * @param {ReactElement} element - */ -function checkAndWarnForMutatedProps(element) { - if (!element._store) { - // Element was created using `new ReactElement` directly or with - // `ReactElement.createElement`; skip mutation checking - return; - } - - var originalProps = element._store.originalProps; - var props = element.props; - - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - if (!originalProps.hasOwnProperty(propName) || - !is(originalProps[propName], props[propName])) { - warnForPropsMutation(propName, element); - - // Copy over the new value so that the two props objects match again - originalProps[propName] = props[propName]; + var addendum = getDeclarationErrorAddendum(); + process.env.NODE_ENV !== 'production' ? warning(false, 'Failed propType: %s%s', error.message, addendum) : undefined; } } } @@ -14304,48 +14975,26 @@ function checkAndWarnForMutatedProps(element) { * @param {ReactElement} element */ function validatePropTypes(element) { - if (element.type == null) { - // This has already warned. Don't throw. + var componentClass = element.type; + if (typeof componentClass !== 'function') { 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 - ); + checkPropTypes(name, componentClass.propTypes, element.props, ReactPropTypeLocations.prop); } if (typeof componentClass.getDefaultProps === 'function') { - ("production" !== process.env.NODE_ENV ? warning( - componentClass.getDefaultProps.isReactClassApproved, - 'getDefaultProps is only used on classic React.createClass ' + - 'definitions. Use a static property named `defaultProps` instead.' - ) : null); + process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : undefined; } } var ReactElementValidator = { - checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, - - createElement: function(type, props, children) { + createElement: function (type, props, children) { + var validType = typeof type === 'string' || typeof type === 'function'; // We warn in this case but don't throw. We expect the element creation to // succeed and there will likely be errors in render. - ("production" !== process.env.NODE_ENV ? warning( - type != null, - 'React.createElement: type should not be null or undefined. It should ' + - 'be a string (for DOM elements) or a ReactClass (for composite ' + - 'components).' - ) : null); + process.env.NODE_ENV !== 'production' ? warning(validType, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : undefined; var element = ReactElement.createElement.apply(this, arguments); @@ -14355,8 +15004,15 @@ var ReactElementValidator = { return element; } - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); + // Skip key warning if the type isn't valid since our key validation logic + // doesn't expect a non-string/function type and can throw confusing errors. + // We don't want exception behavior to differ between dev and prod. + // (Rendering will throw with a helpful message and as soon as the type is + // fixed, the key warnings will appear.) + if (validType) { + for (var i = 2; i < arguments.length; i++) { + validateChildKeys(arguments[i], type); + } } validatePropTypes(element); @@ -14364,44 +15020,30 @@ var ReactElementValidator = { return element; }, - createFactory: function(type) { - var validatedFactory = ReactElementValidator.createElement.bind( - null, - type - ); + createFactory: function (type) { + var validatedFactory = ReactElementValidator.createElement.bind(null, type); // Legacy hook TODO: Warn if this is accessed validatedFactory.type = type; - if ("production" !== process.env.NODE_ENV) { - try { - Object.defineProperty( - validatedFactory, - 'type', - { - enumerable: false, - get: function() { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Factory.type is deprecated. Access the class directly ' + - 'before passing it to createFactory.' - ) : null); - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } + if (process.env.NODE_ENV !== 'production') { + if (canDefineProperty) { + Object.defineProperty(validatedFactory, 'type', { + enumerable: false, + get: function () { + process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : undefined; + 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) { + 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); @@ -14413,11 +15055,9 @@ var ReactElementValidator = { }; module.exports = ReactElementValidator; - }).call(this,require('_process')) -},{"./ReactCurrentOwner":85,"./ReactElement":103,"./ReactFragment":109,"./ReactNativeComponent":120,"./ReactPropTypeLocationNames":124,"./ReactPropTypeLocations":125,"./getIteratorFn":182,"./invariant":191,"./warning":212,"_process":1}],105:[function(require,module,exports){ -(function (process){ +},{"./ReactCurrentOwner":97,"./ReactElement":115,"./ReactPropTypeLocationNames":138,"./ReactPropTypeLocations":139,"./canDefineProperty":176,"./getIteratorFn":188,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],117:[function(require,module,exports){ /** * Copyright 2014-2015, Facebook, Inc. * All rights reserved. @@ -14431,52 +15071,69 @@ module.exports = ReactElementValidator; 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactInstanceMap = require("./ReactInstanceMap"); +var ReactElement = require('./ReactElement'); +var ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry'); +var ReactReconciler = require('./ReactReconciler'); -var invariant = require("./invariant"); +var assign = require('./Object.assign'); -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 placeholderElement; var ReactEmptyComponentInjection = { - injectEmptyComponent: function(emptyComponent) { - component = ReactElement.createFactory(emptyComponent); + injectEmptyComponent: function (component) { + placeholderElement = ReactElement.createElement(component); } }; -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); +var ReactEmptyComponent = function (instantiate) { + this._currentElement = null; + this._rootNodeID = null; + this._renderedComponent = instantiate(placeholderElement); }; -ReactEmptyComponentType.prototype.componentWillUnmount = function() { - var internalInstance = ReactInstanceMap.get(this); - // TODO: Get rid of this check. See TODO in componentDidMount. - if (!internalInstance) { - return; +assign(ReactEmptyComponent.prototype, { + construct: function (element) {}, + mountComponent: function (rootID, transaction, context) { + ReactEmptyComponentRegistry.registerNullComponentID(rootID); + this._rootNodeID = rootID; + return ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, context); + }, + receiveComponent: function () {}, + unmountComponent: function (rootID, transaction, context) { + ReactReconciler.unmountComponent(this._renderedComponent); + ReactEmptyComponentRegistry.deregisterNullComponentID(this._rootNodeID); + this._rootNodeID = null; + this._renderedComponent = null; } - deregisterNullComponentID(internalInstance._rootNodeID); -}; -ReactEmptyComponentType.prototype.render = function() { - ("production" !== process.env.NODE_ENV ? invariant( - component, - 'Trying to return null from a render, but no null placeholder component ' + - 'was injected.' - ) : invariant(component)); - return component(); -}; +}); + +ReactEmptyComponent.injection = ReactEmptyComponentInjection; + +module.exports = ReactEmptyComponent; +},{"./Object.assign":82,"./ReactElement":115,"./ReactEmptyComponentRegistry":118,"./ReactReconciler":142}],118:[function(require,module,exports){ +/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactEmptyComponentRegistry + */ -var emptyElement = ReactElement.createElement(ReactEmptyComponentType); +'use strict'; + +// This registry keeps track of the React IDs of the components that rendered to +// `null` (in reality a placeholder such as `noscript`) +var nullComponentIDsRegistry = {}; + +/** + * @param {string} id Component's `_rootNodeID`. + * @return {boolean} True if the component is rendered to null. + */ +function isNullComponentID(id) { + return !!nullComponentIDsRegistry[id]; +} /** * Mark the component as having rendered to null. @@ -14494,25 +15151,15 @@ 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 +var ReactEmptyComponentRegistry = { + isNullComponentID: isNullComponentID, + registerNullComponentID: registerNullComponentID, + deregisterNullComponentID: deregisterNullComponentID }; -module.exports = ReactEmptyComponent; - -}).call(this,require('_process')) - -},{"./ReactElement":103,"./ReactInstanceMap":113,"./invariant":191,"_process":1}],106:[function(require,module,exports){ +module.exports = ReactEmptyComponentRegistry; +},{}],119:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -14525,26 +15172,74 @@ module.exports = ReactEmptyComponent; * @typechecks */ -"use strict"; +'use strict'; + +var caughtError = null; + +/** + * Call a function while guarding against errors that happens within it. + * + * @param {?String} name of the guard to use for logging or debugging + * @param {Function} func The function to invoke + * @param {*} a First argument + * @param {*} b Second argument + */ +function invokeGuardedCallback(name, func, a, b) { + try { + return func(a, b); + } catch (x) { + if (caughtError === null) { + caughtError = x; + } + return undefined; + } +} var ReactErrorUtils = { + invokeGuardedCallback: invokeGuardedCallback, + /** - * 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} + * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event + * handler are sure to be rethrown by rethrowCaughtError. */ - guard: function(func, name) { - return func; + invokeGuardedCallbackWithCatch: invokeGuardedCallback, + + /** + * During execution of guarded functions we will capture the first error which + * we will rethrow to be handled by the top level error handler. + */ + rethrowCaughtError: function () { + if (caughtError) { + var error = caughtError; + caughtError = null; + throw error; + } } }; +if (process.env.NODE_ENV !== 'production') { + /** + * To help development we can get better devtools integration by simulating a + * real browser event. + */ + if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { + var fakeNode = document.createElement('react'); + ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) { + var boundFunc = func.bind(null, a, b); + var evtType = 'react-' + name; + fakeNode.addEventListener(evtType, boundFunc, false); + var evt = document.createEvent('Event'); + evt.initEvent(evtType, false, false); + fakeNode.dispatchEvent(evt); + fakeNode.removeEventListener(evtType, boundFunc, false); + }; + } +} + module.exports = ReactErrorUtils; +}).call(this,require('_process')) -},{}],107:[function(require,module,exports){ +},{"_process":1}],120:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -14558,11 +15253,11 @@ module.exports = ReactErrorUtils; 'use strict'; -var EventPluginHub = require("./EventPluginHub"); +var EventPluginHub = require('./EventPluginHub'); function runEventQueueInBatch(events) { EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(); + EventPluginHub.processEventQueue(false); } var ReactEventEmitterMixin = { @@ -14576,25 +15271,14 @@ var ReactEventEmitterMixin = { * @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 - ); - + handleTopLevel: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + var events = EventPluginHub.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget); runEventQueueInBatch(events); } }; module.exports = ReactEventEmitterMixin; - -},{"./EventPluginHub":58}],108:[function(require,module,exports){ +},{"./EventPluginHub":74}],121:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -14609,16 +15293,18 @@ module.exports = ReactEventEmitterMixin; 'use strict'; -var EventListener = require("./EventListener"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var PooledClass = require("./PooledClass"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactMount = require("./ReactMount"); -var ReactUpdates = require("./ReactUpdates"); +var EventListener = require('fbjs/lib/EventListener'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var PooledClass = require('./PooledClass'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactMount = require('./ReactMount'); +var ReactUpdates = require('./ReactUpdates'); + +var assign = require('./Object.assign'); +var getEventTarget = require('./getEventTarget'); +var getUnboundedScrollPosition = require('fbjs/lib/getUnboundedScrollPosition'); -var assign = require("./Object.assign"); -var getEventTarget = require("./getEventTarget"); -var getUnboundedScrollPosition = require("./getUnboundedScrollPosition"); +var DOCUMENT_FRAGMENT_NODE_TYPE = 11; /** * Finds the parent React component of `node`. @@ -14645,21 +15331,32 @@ function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { this.ancestors = []; } assign(TopLevelCallbackBookKeeping.prototype, { - destructor: function() { + destructor: function () { this.topLevelType = null; this.nativeEvent = null; this.ancestors.length = 0; } }); -PooledClass.addPoolingTo( - TopLevelCallbackBookKeeping, - PooledClass.twoArgumentPooler -); +PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler); function handleTopLevelImpl(bookKeeping) { - var topLevelTarget = ReactMount.getFirstReactDOM( - getEventTarget(bookKeeping.nativeEvent) - ) || window; + // TODO: Re-enable event.path handling + // + // if (bookKeeping.nativeEvent.path && bookKeeping.nativeEvent.path.length > 1) { + // // New browsers have a path attribute on native events + // handleTopLevelWithPath(bookKeeping); + // } else { + // // Legacy browsers don't have a path attribute on native events + // handleTopLevelWithoutPath(bookKeeping); + // } + + void handleTopLevelWithPath; // temporarily unused + handleTopLevelWithoutPath(bookKeeping); +} + +// Legacy browsers don't have a path attribute on native events +function handleTopLevelWithoutPath(bookKeeping) { + var topLevelTarget = ReactMount.getFirstReactDOM(getEventTarget(bookKeeping.nativeEvent)) || window; // Loop through the hierarchy, in case there's any nested components. // It's important that we build the array of ancestors before calling any @@ -14671,15 +15368,44 @@ function handleTopLevelImpl(bookKeeping) { ancestor = findParent(ancestor); } - for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) { + for (var i = 0; i < bookKeeping.ancestors.length; i++) { topLevelTarget = bookKeeping.ancestors[i]; var topLevelTargetID = ReactMount.getID(topLevelTarget) || ''; - ReactEventListener._handleTopLevel( - bookKeeping.topLevelType, - topLevelTarget, - topLevelTargetID, - bookKeeping.nativeEvent - ); + ReactEventListener._handleTopLevel(bookKeeping.topLevelType, topLevelTarget, topLevelTargetID, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); + } +} + +// New browsers have a path attribute on native events +function handleTopLevelWithPath(bookKeeping) { + var path = bookKeeping.nativeEvent.path; + var currentNativeTarget = path[0]; + var eventsFired = 0; + for (var i = 0; i < path.length; i++) { + var currentPathElement = path[i]; + if (currentPathElement.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE) { + currentNativeTarget = path[i + 1]; + } + // TODO: slow + var reactParent = ReactMount.getFirstReactDOM(currentPathElement); + if (reactParent === currentPathElement) { + var currentPathElementID = ReactMount.getID(currentPathElement); + var newRootID = ReactInstanceHandles.getReactRootIDFromNodeID(currentPathElementID); + bookKeeping.ancestors.push(currentPathElement); + + var topLevelTargetID = ReactMount.getID(currentPathElement) || ''; + eventsFired++; + ReactEventListener._handleTopLevel(bookKeeping.topLevelType, currentPathElement, topLevelTargetID, bookKeeping.nativeEvent, currentNativeTarget); + + // Jump to the root of this React render tree + while (currentPathElementID !== newRootID) { + i++; + currentPathElement = path[i]; + currentPathElementID = ReactMount.getID(currentPathElement); + } + } + } + if (eventsFired === 0) { + ReactEventListener._handleTopLevel(bookKeeping.topLevelType, window, '', bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); } } @@ -14694,39 +15420,34 @@ var ReactEventListener = { WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, - setHandleTopLevel: function(handleTopLevel) { + setHandleTopLevel: function (handleTopLevel) { ReactEventListener._handleTopLevel = handleTopLevel; }, - setEnabled: function(enabled) { + setEnabled: function (enabled) { ReactEventListener._enabled = !!enabled; }, - isEnabled: function() { + isEnabled: function () { return ReactEventListener._enabled; }, - /** * Traps top-level events by using event bubbling. * * @param {string} topLevelType Record from `EventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully + * @return {?object} An object with a remove function which will forcefully * remove the listener. * @internal */ - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { + trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { var element = handle; if (!element) { return null; } - return EventListener.listen( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); + return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); }, /** @@ -14735,36 +15456,29 @@ var ReactEventListener = { * @param {string} topLevelType Record from `EventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {object} handle Element on which to attach listener. - * @return {object} An object with a remove function which will forcefully + * @return {?object} An object with a remove function which will forcefully * remove the listener. * @internal */ - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { + trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { var element = handle; if (!element) { return null; } - return EventListener.capture( - element, - handlerBaseName, - ReactEventListener.dispatchEvent.bind(null, topLevelType) - ); + return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); }, - monitorScrollValue: function(refresh) { + monitorScrollValue: function (refresh) { var callback = scrollValueMonitor.bind(null, refresh); EventListener.listen(window, 'scroll', callback); }, - dispatchEvent: function(topLevelType, nativeEvent) { + dispatchEvent: function (topLevelType, nativeEvent) { if (!ReactEventListener._enabled) { return; } - var bookKeeping = TopLevelCallbackBookKeeping.getPooled( - topLevelType, - nativeEvent - ); + var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent); try { // Event queue being processed in the same cycle allows // `preventDefault`. @@ -14776,8 +15490,7 @@ var ReactEventListener = { }; module.exports = ReactEventListener; - -},{"./EventListener":57,"./ExecutionEnvironment":62,"./Object.assign":69,"./PooledClass":70,"./ReactInstanceHandles":112,"./ReactMount":117,"./ReactUpdates":140,"./getEventTarget":181,"./getUnboundedScrollPosition":187}],109:[function(require,module,exports){ +},{"./Object.assign":82,"./PooledClass":83,"./ReactInstanceHandles":125,"./ReactMount":130,"./ReactUpdates":154,"./getEventTarget":187,"fbjs/lib/EventListener":205,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/getUnboundedScrollPosition":217}],122:[function(require,module,exports){ (function (process){ /** * Copyright 2015, Facebook, Inc. @@ -14787,183 +15500,65 @@ module.exports = ReactEventListener; * LICENSE file in the 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 -*/ + * @providesModule ReactFragment + */ 'use strict'; -var ReactElement = require("./ReactElement"); +var ReactChildren = require('./ReactChildren'); +var ReactElement = require('./ReactElement'); -var warning = require("./warning"); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/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. + * create a keyed fragment. The resulting data structure is an array. */ -if ("production" !== process.env.NODE_ENV) { - var fragmentKey = '_reactFragment'; - var didWarnKey = '_reactDidWarn'; - var canWarnForReactFragment = false; - - try { - // Feature test. Don't even try to issue this warning if we can't use - // enumerable: false. - - var dummy = function() { - return 1; - }; - - Object.defineProperty( - {}, - fragmentKey, - {enumerable: false, value: true} - ); - - Object.defineProperty( - {}, - 'key', - {enumerable: true, get: dummy} - ); - - canWarnForReactFragment = true; - } catch (x) { } - - var proxyPropertyAccessWithWarning = function(obj, key) { - Object.defineProperty(obj, key, { - enumerable: true, - get: function() { - ("production" !== process.env.NODE_ENV ? warning( - this[didWarnKey], - 'A ReactFragment is an opaque type. Accessing any of its ' + - 'properties is deprecated. Pass it to one of the React.Children ' + - 'helpers.' - ) : null); - this[didWarnKey] = true; - return this[fragmentKey][key]; - }, - set: function(value) { - ("production" !== process.env.NODE_ENV ? warning( - this[didWarnKey], - 'A ReactFragment is an immutable opaque type. Mutating its ' + - 'properties is deprecated.' - ) : null); - this[didWarnKey] = true; - this[fragmentKey][key] = value; - } - }); - }; - - var issuedWarnings = {}; +var numericPropertyRegex = /^\d+$/; - 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 warnedAboutNumeric = false; var ReactFragment = { // Wrap a keyed object in an opaque proxy that warns you if you access any // of its properties. - create: function(object) { - if ("production" !== process.env.NODE_ENV) { - if (typeof object !== 'object' || !object || Array.isArray(object)) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'React.addons.createFragment only accepts a single object.', - object - ) : null); - return object; - } - if (ReactElement.isValidElement(object)) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'React.addons.createFragment does not accept a ReactElement ' + - 'without a wrapper object.' - ) : null); - return object; - } - if (canWarnForReactFragment) { - var proxy = {}; - Object.defineProperty(proxy, fragmentKey, { - enumerable: false, - value: object - }); - Object.defineProperty(proxy, didWarnKey, { - writable: true, - enumerable: false, - value: false - }); - for (var key in object) { - proxyPropertyAccessWithWarning(proxy, key); - } - Object.preventExtensions(proxy); - return proxy; - } - } - return object; - }, - // Extract the original keyed object from the fragment opaque type. Warn if - // a plain object is passed here. - extract: function(fragment) { - if ("production" !== process.env.NODE_ENV) { - if (canWarnForReactFragment) { - if (!fragment[fragmentKey]) { - ("production" !== process.env.NODE_ENV ? warning( - didWarnForFragment(fragment), - 'Any use of a keyed object should be wrapped in ' + - 'React.addons.createFragment(object) before being passed as a ' + - 'child.' - ) : null); - return fragment; - } - return fragment[fragmentKey]; - } + create: function (object) { + if (typeof object !== 'object' || !object || Array.isArray(object)) { + process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment only accepts a single object. Got: %s', object) : undefined; + return object; } - return fragment; - }, - // Check if this is a fragment and if so, extract the keyed object. If it - // is a fragment-like object, warn that it should be wrapped. Ignore if we - // can't determine what kind of object this is. - extractIfFragment: function(fragment) { - if ("production" !== process.env.NODE_ENV) { - if (canWarnForReactFragment) { - // If it is the opaque type, return the keyed object. - if (fragment[fragmentKey]) { - return fragment[fragmentKey]; - } - // Otherwise, check each property if it has an element, if it does - // it is probably meant as a fragment, so we can warn early. Defer, - // the warning to extract. - for (var key in fragment) { - if (fragment.hasOwnProperty(key) && - ReactElement.isValidElement(fragment[key])) { - // This looks like a fragment object, we should provide an - // early warning. - return ReactFragment.extract(fragment); - } + if (ReactElement.isValidElement(object)) { + process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment does not accept a ReactElement ' + 'without a wrapper object.') : undefined; + return object; + } + + !(object.nodeType !== 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React.addons.createFragment(...): Encountered an invalid child; DOM ' + 'elements are not valid children of React components.') : invariant(false) : undefined; + + var result = []; + + for (var key in object) { + if (process.env.NODE_ENV !== 'production') { + if (!warnedAboutNumeric && numericPropertyRegex.test(key)) { + process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment(...): Child objects should have ' + 'non-numeric keys so ordering is preserved.') : undefined; + warnedAboutNumeric = true; } } + ReactChildren.mapIntoWithKeyPrefixInternal(object[key], result, key, emptyFunction.thatReturnsArgument); } - return fragment; + + return result; } }; module.exports = ReactFragment; - }).call(this,require('_process')) -},{"./ReactElement":103,"./warning":212,"_process":1}],110:[function(require,module,exports){ +},{"./ReactChildren":90,"./ReactElement":115,"_process":1,"fbjs/lib/emptyFunction":212,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],123:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -14977,22 +15572,20 @@ module.exports = ReactFragment; 'use strict'; -var DOMProperty = require("./DOMProperty"); -var EventPluginHub = require("./EventPluginHub"); -var ReactComponentEnvironment = require("./ReactComponentEnvironment"); -var ReactClass = require("./ReactClass"); -var ReactEmptyComponent = require("./ReactEmptyComponent"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); -var ReactNativeComponent = require("./ReactNativeComponent"); -var ReactDOMComponent = require("./ReactDOMComponent"); -var ReactPerf = require("./ReactPerf"); -var ReactRootIndex = require("./ReactRootIndex"); -var ReactUpdates = require("./ReactUpdates"); +var DOMProperty = require('./DOMProperty'); +var EventPluginHub = require('./EventPluginHub'); +var ReactComponentEnvironment = require('./ReactComponentEnvironment'); +var ReactClass = require('./ReactClass'); +var ReactEmptyComponent = require('./ReactEmptyComponent'); +var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); +var ReactNativeComponent = require('./ReactNativeComponent'); +var ReactPerf = require('./ReactPerf'); +var ReactRootIndex = require('./ReactRootIndex'); +var ReactUpdates = require('./ReactUpdates'); var ReactInjection = { Component: ReactComponentEnvironment.injection, Class: ReactClass.injection, - DOMComponent: ReactDOMComponent.injection, DOMProperty: DOMProperty.injection, EmptyComponent: ReactEmptyComponent.injection, EventPluginHub: EventPluginHub.injection, @@ -15004,8 +15597,7 @@ var ReactInjection = { }; module.exports = ReactInjection; - -},{"./DOMProperty":51,"./EventPluginHub":58,"./ReactBrowserEventEmitter":73,"./ReactClass":78,"./ReactComponentEnvironment":81,"./ReactDOMComponent":88,"./ReactEmptyComponent":105,"./ReactNativeComponent":120,"./ReactPerf":122,"./ReactRootIndex":131,"./ReactUpdates":140}],111:[function(require,module,exports){ +},{"./DOMProperty":68,"./EventPluginHub":74,"./ReactBrowserEventEmitter":86,"./ReactClass":91,"./ReactComponentEnvironment":94,"./ReactEmptyComponent":117,"./ReactNativeComponent":133,"./ReactPerf":136,"./ReactRootIndex":144,"./ReactUpdates":154}],124:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -15019,11 +15611,11 @@ module.exports = ReactInjection; 'use strict'; -var ReactDOMSelection = require("./ReactDOMSelection"); +var ReactDOMSelection = require('./ReactDOMSelection'); -var containsNode = require("./containsNode"); -var focusNode = require("./focusNode"); -var getActiveElement = require("./getActiveElement"); +var containsNode = require('fbjs/lib/containsNode'); +var focusNode = require('fbjs/lib/focusNode'); +var getActiveElement = require('fbjs/lib/getActiveElement'); function isInDocument(node) { return containsNode(document.documentElement, node); @@ -15037,21 +15629,16 @@ function isInDocument(node) { */ var ReactInputSelection = { - hasSelectionCapabilities: function(elem) { - return elem && ( - ((elem.nodeName === 'INPUT' && elem.type === 'text') || - elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true') - ); + hasSelectionCapabilities: function (elem) { + var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); + return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true'); }, - getSelectionInformation: function() { + getSelectionInformation: function () { var focusedElem = getActiveElement(); return { focusedElem: focusedElem, - selectionRange: - ReactInputSelection.hasSelectionCapabilities(focusedElem) ? - ReactInputSelection.getSelection(focusedElem) : - null + selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null }; }, @@ -15060,17 +15647,13 @@ var ReactInputSelection = { * restore it. This is useful when performing operations that could remove dom * nodes and place them back in, resulting in focus being lost. */ - restoreSelection: function(priorSelectionInformation) { + restoreSelection: function (priorSelectionInformation) { var curFocusedElem = getActiveElement(); var priorFocusedElem = priorSelectionInformation.focusedElem; var priorSelectionRange = priorSelectionInformation.selectionRange; - if (curFocusedElem !== priorFocusedElem && - isInDocument(priorFocusedElem)) { + if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { - ReactInputSelection.setSelection( - priorFocusedElem, - priorSelectionRange - ); + ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange); } focusNode(priorFocusedElem); } @@ -15082,7 +15665,7 @@ var ReactInputSelection = { * -@input: Look up selection bounds of this input * -@return {start: selectionStart, end: selectionEnd} */ - getSelection: function(input) { + getSelection: function (input) { var selection; if ('selectionStart' in input) { @@ -15091,7 +15674,7 @@ var ReactInputSelection = { start: input.selectionStart, end: input.selectionEnd }; - } else if (document.selection && input.nodeName === 'INPUT') { + } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) { // IE8 input. var range = document.selection.createRange(); // There can only be one selection per document in IE, so it must @@ -15107,7 +15690,7 @@ var ReactInputSelection = { selection = ReactDOMSelection.getOffsets(input); } - return selection || {start: 0, end: 0}; + return selection || { start: 0, end: 0 }; }, /** @@ -15116,7 +15699,7 @@ var ReactInputSelection = { * -@input Set selection bounds of this input or textarea * -@offsets Object of same form that is returned from get* */ - setSelection: function(input, offsets) { + setSelection: function (input, offsets) { var start = offsets.start; var end = offsets.end; if (typeof end === 'undefined') { @@ -15126,7 +15709,7 @@ var ReactInputSelection = { if ('selectionStart' in input) { input.selectionStart = start; input.selectionEnd = Math.min(end, input.value.length); - } else if (document.selection && input.nodeName === 'INPUT') { + } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) { var range = input.createTextRange(); range.collapse(true); range.moveStart('character', start); @@ -15139,8 +15722,7 @@ var ReactInputSelection = { }; module.exports = ReactInputSelection; - -},{"./ReactDOMSelection":96,"./containsNode":164,"./focusNode":175,"./getActiveElement":177}],112:[function(require,module,exports){ +},{"./ReactDOMSelection":107,"fbjs/lib/containsNode":209,"fbjs/lib/focusNode":214,"fbjs/lib/getActiveElement":215}],125:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -15156,9 +15738,9 @@ module.exports = ReactInputSelection; 'use strict'; -var ReactRootIndex = require("./ReactRootIndex"); +var ReactRootIndex = require('./ReactRootIndex'); -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); var SEPARATOR = '.'; var SEPARATOR_LENGTH = SEPARATOR.length; @@ -15166,7 +15748,7 @@ var SEPARATOR_LENGTH = SEPARATOR.length; /** * Maximum depth of traversals before we consider the possibility of a bad ID. */ -var MAX_TREE_DEPTH = 100; +var MAX_TREE_DEPTH = 10000; /** * Creates a DOM ID prefix to use when mounting React components. @@ -15199,9 +15781,7 @@ function isBoundary(id, index) { * @private */ function isValidID(id) { - return id === '' || ( - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR - ); + return id === '' || id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR; } /** @@ -15213,10 +15793,7 @@ function isValidID(id) { * @internal */ function isAncestorIDOf(ancestorID, descendantID) { - return ( - descendantID.indexOf(ancestorID) === 0 && - isBoundary(descendantID, ancestorID.length) - ); + return descendantID.indexOf(ancestorID) === 0 && isBoundary(descendantID, ancestorID.length); } /** @@ -15240,19 +15817,8 @@ function getParentID(id) { * @private */ function getNextDescendantID(ancestorID, destinationID) { - ("production" !== process.env.NODE_ENV ? invariant( - isValidID(ancestorID) && isValidID(destinationID), - 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', - ancestorID, - destinationID - ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); - ("production" !== process.env.NODE_ENV ? invariant( - isAncestorIDOf(ancestorID, destinationID), - 'getNextDescendantID(...): React has made an invalid assumption about ' + - 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', - ancestorID, - destinationID - ) : invariant(isAncestorIDOf(ancestorID, destinationID))); + !(isValidID(ancestorID) && isValidID(destinationID)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', ancestorID, destinationID) : invariant(false) : undefined; + !isAncestorIDOf(ancestorID, destinationID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(...): React has made an invalid assumption about ' + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', ancestorID, destinationID) : invariant(false) : undefined; if (ancestorID === destinationID) { return ancestorID; } @@ -15294,13 +15860,7 @@ function getFirstCommonAncestorID(oneID, twoID) { } } var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); - ("production" !== process.env.NODE_ENV ? invariant( - isValidID(longestCommonID), - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', - oneID, - twoID, - longestCommonID - ) : invariant(isValidID(longestCommonID))); + !isValidID(longestCommonID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', oneID, twoID, longestCommonID) : invariant(false) : undefined; return longestCommonID; } @@ -15312,6 +15872,7 @@ function getFirstCommonAncestorID(oneID, twoID) { * @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 {*} arg Argument to invoke the callback with. * @param {?boolean} skipFirst Whether or not to skip the first node. * @param {?boolean} skipLast Whether or not to skip the last node. * @private @@ -15319,23 +15880,13 @@ function getFirstCommonAncestorID(oneID, twoID) { function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { start = start || ''; stop = stop || ''; - ("production" !== process.env.NODE_ENV ? invariant( - start !== stop, - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', - start - ) : invariant(start !== stop)); + !(start !== stop) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', start) : invariant(false) : undefined; var traverseUp = isAncestorIDOf(stop, start); - ("production" !== process.env.NODE_ENV ? invariant( - traverseUp || isAncestorIDOf(start, stop), - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + - 'not have a parent path.', - start, - stop - ) : invariant(traverseUp || isAncestorIDOf(start, stop))); + !(traverseUp || isAncestorIDOf(start, stop)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + 'not have a parent path.', start, stop) : invariant(false) : undefined; // 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)) { + for (var id = start;; /* until break */id = traverse(id, stop)) { var ret; if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { ret = cb(id, traverseUp, arg); @@ -15344,12 +15895,7 @@ function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { // Only break //after// visiting `stop`. break; } - ("production" !== process.env.NODE_ENV ? invariant( - depth++ < MAX_TREE_DEPTH, - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', - start, stop - ) : invariant(depth++ < MAX_TREE_DEPTH)); + !(depth++ < MAX_TREE_DEPTH) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', start, stop, id) : invariant(false) : undefined; } } @@ -15366,7 +15912,7 @@ var ReactInstanceHandles = { * Constructs a React root ID * @return {string} A React root ID. */ - createReactRootID: function() { + createReactRootID: function () { return getReactRootIDString(ReactRootIndex.createReactRootIndex()); }, @@ -15378,7 +15924,7 @@ var ReactInstanceHandles = { * @return {string} A React ID. * @internal */ - createReactID: function(rootID, name) { + createReactID: function (rootID, name) { return rootID + name; }, @@ -15390,7 +15936,7 @@ var ReactInstanceHandles = { * @return {?string} DOM ID of the React component that is the root. * @internal */ - getReactRootIDFromNodeID: function(id) { + 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; @@ -15412,7 +15958,7 @@ var ReactInstanceHandles = { * @param {*} downArg Argument to invoke the callback with on entered IDs. * @internal */ - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { + traverseEnterLeave: function (leaveID, enterID, cb, upArg, downArg) { var ancestorID = getFirstCommonAncestorID(leaveID, enterID); if (ancestorID !== leaveID) { traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); @@ -15432,7 +15978,7 @@ var ReactInstanceHandles = { * @param {*} arg Argument to invoke the callback with. * @internal */ - traverseTwoPhase: function(targetID, cb, arg) { + traverseTwoPhase: function (targetID, cb, arg) { if (targetID) { traverseParentPath('', targetID, cb, arg, true, false); traverseParentPath(targetID, '', cb, arg, false, true); @@ -15440,6 +15986,16 @@ var ReactInstanceHandles = { }, /** + * 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`. @@ -15451,15 +16007,11 @@ var ReactInstanceHandles = { * @param {*} arg Argument to invoke the callback with. * @internal */ - traverseAncestors: function(targetID, cb, arg) { + traverseAncestors: function (targetID, cb, arg) { traverseParentPath('', targetID, cb, arg, true, false); }, - /** - * Exposed for unit testing. - * @private - */ - _getFirstCommonAncestorID: getFirstCommonAncestorID, + getFirstCommonAncestorID: getFirstCommonAncestorID, /** * Exposed for unit testing. @@ -15474,10 +16026,9 @@ var ReactInstanceHandles = { }; module.exports = ReactInstanceHandles; - }).call(this,require('_process')) -},{"./ReactRootIndex":131,"./invariant":191,"_process":1}],113:[function(require,module,exports){ +},{"./ReactRootIndex":144,"_process":1,"fbjs/lib/invariant":220}],126:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -15506,64 +16057,104 @@ var ReactInstanceMap = { * transform these to strings for IE support. When this transform is fully * supported we can rename it. */ - remove: function(key) { + remove: function (key) { key._reactInternalInstance = undefined; }, - get: function(key) { + get: function (key) { return key._reactInternalInstance; }, - has: function(key) { + has: function (key) { return key._reactInternalInstance !== undefined; }, - set: function(key, value) { + set: function (key, value) { key._reactInternalInstance = value; } }; module.exports = ReactInstanceMap; - -},{}],114:[function(require,module,exports){ +},{}],127:[function(require,module,exports){ +(function (process){ /** - * Copyright 2015, Facebook, Inc. + * 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 ReactLifeCycle + * @providesModule ReactIsomorphic */ '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 ReactChildren = require('./ReactChildren'); +var ReactComponent = require('./ReactComponent'); +var ReactClass = require('./ReactClass'); +var ReactDOMFactories = require('./ReactDOMFactories'); +var ReactElement = require('./ReactElement'); +var ReactElementValidator = require('./ReactElementValidator'); +var ReactPropTypes = require('./ReactPropTypes'); +var ReactVersion = require('./ReactVersion'); + +var assign = require('./Object.assign'); +var onlyChild = require('./onlyChild'); + +var createElement = ReactElement.createElement; +var createFactory = ReactElement.createFactory; +var cloneElement = ReactElement.cloneElement; + +if (process.env.NODE_ENV !== 'production') { + createElement = ReactElementValidator.createElement; + createFactory = ReactElementValidator.createFactory; + cloneElement = ReactElementValidator.cloneElement; +} + +var React = { + + // Modern + + Children: { + map: ReactChildren.map, + forEach: ReactChildren.forEach, + count: ReactChildren.count, + toArray: ReactChildren.toArray, + only: onlyChild + }, + + Component: ReactComponent, + + createElement: createElement, + cloneElement: cloneElement, + isValidElement: ReactElement.isValidElement, + + // Classic + + PropTypes: ReactPropTypes, + createClass: ReactClass.createClass, + createFactory: createFactory, + createMixin: function (mixin) { + // Currently a noop. Will be used to validate and trace mixins. + return mixin; + }, + + // This looks DOM specific but these are actually isomorphic helpers + // since they are just generating DOM strings. + DOM: ReactDOMFactories, + + version: ReactVersion, -var ReactLifeCycle = { - currentlyMountingInstance: null, - currentlyUnmountingInstance: null + // Hook for JSX spread, don't use this for anything else. + __spread: assign }; -module.exports = ReactLifeCycle; +module.exports = React; +}).call(this,require('_process')) -},{}],115:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactChildren":90,"./ReactClass":91,"./ReactComponent":92,"./ReactDOMFactories":101,"./ReactElement":115,"./ReactElementValidator":116,"./ReactPropTypes":140,"./ReactVersion":155,"./onlyChild":194,"_process":1}],128:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -15592,7 +16183,7 @@ module.exports = ReactLifeCycle; * var valueLink = new ReactLink(this.state.value, this._handleValueChange); * return <input valueLink={valueLink} />; * }, - * this._handleValueChange: function(newValue) { + * _handleValueChange: function(newValue) { * this.setState({value: newValue}); * } * }); @@ -15601,7 +16192,7 @@ module.exports = ReactLifeCycle; * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. */ -var React = require("./React"); +var React = require('./React'); /** * @param {*} value current value of the link @@ -15622,9 +16213,7 @@ function ReactLink(value, requestChange) { */ function createLinkTypeChecker(linkType) { var shapes = { - value: typeof linkType === 'undefined' ? - React.PropTypes.any.isRequired : - linkType.isRequired, + value: typeof linkType === 'undefined' ? React.PropTypes.any.isRequired : linkType.isRequired, requestChange: React.PropTypes.func.isRequired }; return React.PropTypes.shape(shapes); @@ -15635,8 +16224,7 @@ ReactLink.PropTypes = { }; module.exports = ReactLink; - -},{"./React":71}],116:[function(require,module,exports){ +},{"./React":84}],129:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -15650,7 +16238,9 @@ module.exports = ReactLink; 'use strict'; -var adler32 = require("./adler32"); +var adler32 = require('./adler32'); + +var TAG_END = /\/?>/; var ReactMarkupChecksum = { CHECKSUM_ATTR_NAME: 'data-react-checksum', @@ -15659,12 +16249,11 @@ var ReactMarkupChecksum = { * @param {string} markup Markup string * @return {string} Markup string with checksum attribute attached */ - addChecksumToMarkup: function(markup) { + addChecksumToMarkup: function (markup) { var checksum = adler32(markup); - return markup.replace( - '>', - ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' - ); + + // Add checksum (handle both parent tags and self-closing tags) + return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '"$&'); }, /** @@ -15672,10 +16261,8 @@ var ReactMarkupChecksum = { * @param {DOMElement} element root React element * @returns {boolean} whether or not the markup is the same */ - canReuseMarkup: function(markup, element) { - var existingChecksum = element.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); + canReuseMarkup: function (markup, element) { + var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); existingChecksum = existingChecksum && parseInt(existingChecksum, 10); var markupChecksum = adler32(markup); return markupChecksum === existingChecksum; @@ -15683,8 +16270,7 @@ var ReactMarkupChecksum = { }; module.exports = ReactMarkupChecksum; - -},{"./adler32":160}],117:[function(require,module,exports){ +},{"./adler32":175}],130:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -15699,36 +16285,38 @@ module.exports = ReactMarkupChecksum; 'use strict'; -var DOMProperty = require("./DOMProperty"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); -var ReactCurrentOwner = require("./ReactCurrentOwner"); -var ReactElement = require("./ReactElement"); -var ReactElementValidator = require("./ReactElementValidator"); -var ReactEmptyComponent = require("./ReactEmptyComponent"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactInstanceMap = require("./ReactInstanceMap"); -var ReactMarkupChecksum = require("./ReactMarkupChecksum"); -var ReactPerf = require("./ReactPerf"); -var ReactReconciler = require("./ReactReconciler"); -var ReactUpdateQueue = require("./ReactUpdateQueue"); -var ReactUpdates = require("./ReactUpdates"); - -var emptyObject = require("./emptyObject"); -var containsNode = require("./containsNode"); -var getReactRootElementInContainer = require("./getReactRootElementInContainer"); -var instantiateReactComponent = require("./instantiateReactComponent"); -var invariant = require("./invariant"); -var setInnerHTML = require("./setInnerHTML"); -var shouldUpdateReactComponent = require("./shouldUpdateReactComponent"); -var warning = require("./warning"); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; +var DOMProperty = require('./DOMProperty'); +var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags'); +var ReactElement = require('./ReactElement'); +var ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactInstanceMap = require('./ReactInstanceMap'); +var ReactMarkupChecksum = require('./ReactMarkupChecksum'); +var ReactPerf = require('./ReactPerf'); +var ReactReconciler = require('./ReactReconciler'); +var ReactUpdateQueue = require('./ReactUpdateQueue'); +var ReactUpdates = require('./ReactUpdates'); + +var assign = require('./Object.assign'); +var emptyObject = require('fbjs/lib/emptyObject'); +var containsNode = require('fbjs/lib/containsNode'); +var instantiateReactComponent = require('./instantiateReactComponent'); +var invariant = require('fbjs/lib/invariant'); +var setInnerHTML = require('./setInnerHTML'); +var shouldUpdateReactComponent = require('./shouldUpdateReactComponent'); +var validateDOMNesting = require('./validateDOMNesting'); +var warning = require('fbjs/lib/warning'); var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; var nodeCache = {}; var ELEMENT_NODE_TYPE = 1; var DOC_NODE_TYPE = 9; +var DOCUMENT_FRAGMENT_NODE_TYPE = 11; + +var ownerDocumentContextKey = '__ReactMount_ownerDocument$' + Math.random().toString(36).slice(2); /** Mapping from reactRootID to React component instance. */ var instancesByReactRootID = {}; @@ -15736,7 +16324,7 @@ var instancesByReactRootID = {}; /** Mapping from reactRootID to `container` nodes. */ var containersByReactRootID = {}; -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { /** __DEV__-only mapping from reactRootID to root elements. */ var rootElementsByReactRootID = {}; } @@ -15761,6 +16349,23 @@ function firstDifferenceIndex(string1, string2) { } /** + * @param {DOMElement|DOMDocument} container DOM element that may contain + * a React component + * @return {?*} DOM element that may have the reactRoot ID, or null. + */ +function getReactRootElementInContainer(container) { + if (!container) { + return null; + } + + if (container.nodeType === DOC_NODE_TYPE) { + return container.documentElement; + } else { + return container.firstChild; + } +} + +/** * @param {DOMElement} container DOM element that may contain a React component. * @return {?string} A "reactRoot" ID, if a React component is rendered. */ @@ -15785,11 +16390,7 @@ function getID(node) { if (nodeCache.hasOwnProperty(id)) { var cached = nodeCache[id]; if (cached !== node) { - ("production" !== process.env.NODE_ENV ? invariant( - !isValid(cached, id), - 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', - ATTR_NAME, id - ) : invariant(!isValid(cached, id))); + !!isValid(cached, id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', ATTR_NAME, id) : invariant(false) : undefined; nodeCache[id] = node; } @@ -15846,7 +16447,7 @@ function getNode(id) { */ function getNodeFromInstance(instance) { var id = ReactInstanceMap.get(instance)._rootNodeID; - if (ReactEmptyComponent.isNullComponentID(id)) { + if (ReactEmptyComponentRegistry.isNullComponentID(id)) { return null; } if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { @@ -15867,11 +16468,7 @@ function getNodeFromInstance(instance) { */ function isValid(node, id) { if (node) { - ("production" !== process.env.NODE_ENV ? invariant( - internalGetID(node) === id, - 'ReactMount: Unexpected modification of `%s`', - ATTR_NAME - ) : invariant(internalGetID(node) === id)); + !(internalGetID(node) === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Unexpected modification of `%s`', ATTR_NAME) : invariant(false) : undefined; var container = ReactMount.findReactContainerForID(id); if (container && containsNode(container, node)) { @@ -15908,10 +16505,7 @@ function findDeepestCachedAncestorImpl(ancestorID) { */ function findDeepestCachedAncestor(targetID) { deepestNodeSoFar = null; - ReactInstanceHandles.traverseAncestors( - targetID, - findDeepestCachedAncestorImpl - ); + ReactInstanceHandles.traverseAncestors(targetID, findDeepestCachedAncestorImpl); var foundNode = deepestNodeSoFar; deepestNodeSoFar = null; @@ -15927,17 +16521,25 @@ function findDeepestCachedAncestor(targetID) { * @param {ReactReconcileTransaction} transaction * @param {boolean} shouldReuseMarkup If true, do not insert markup */ -function mountComponentIntoNode( - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup) { - var markup = ReactReconciler.mountComponent( - componentInstance, rootID, transaction, emptyObject - ); - componentInstance._isTopLevel = true; - ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); +function mountComponentIntoNode(componentInstance, rootID, container, transaction, shouldReuseMarkup, context) { + if (ReactDOMFeatureFlags.useCreateElement) { + context = assign({}, context); + if (container.nodeType === DOC_NODE_TYPE) { + context[ownerDocumentContextKey] = container; + } else { + context[ownerDocumentContextKey] = container.ownerDocument; + } + } + if (process.env.NODE_ENV !== 'production') { + if (context === emptyObject) { + context = {}; + } + var tag = container.nodeName.toLowerCase(); + context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(null, tag, null); + } + var markup = ReactReconciler.mountComponent(componentInstance, rootID, transaction, context); + componentInstance._renderedComponent._topLevelWrapper = componentInstance; + ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup, transaction); } /** @@ -15948,25 +16550,107 @@ function mountComponentIntoNode( * @param {DOMElement} container DOM element to mount into. * @param {boolean} shouldReuseMarkup If true, do not insert markup */ -function batchedMountComponentIntoNode( - componentInstance, - rootID, - container, - shouldReuseMarkup) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - transaction.perform( - mountComponentIntoNode, - null, - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup - ); +function batchedMountComponentIntoNode(componentInstance, rootID, container, shouldReuseMarkup, context) { + var transaction = ReactUpdates.ReactReconcileTransaction.getPooled( + /* forceHTML */shouldReuseMarkup); + transaction.perform(mountComponentIntoNode, null, componentInstance, rootID, container, transaction, shouldReuseMarkup, context); ReactUpdates.ReactReconcileTransaction.release(transaction); } /** + * Unmounts a component and removes it from the DOM. + * + * @param {ReactComponent} instance React component instance. + * @param {DOMElement} container DOM element to unmount from. + * @final + * @internal + * @see {ReactMount.unmountComponentAtNode} + */ +function unmountComponentFromNode(instance, container) { + ReactReconciler.unmountComponent(instance); + + if (container.nodeType === DOC_NODE_TYPE) { + container = container.documentElement; + } + + // http://jsperf.com/emptying-a-node + while (container.lastChild) { + container.removeChild(container.lastChild); + } +} + +/** + * True if the supplied DOM node has a direct React-rendered child that is + * not a React root element. Useful for warning in `render`, + * `unmountComponentAtNode`, etc. + * + * @param {?DOMElement} node The candidate DOM node. + * @return {boolean} True if the DOM element contains a direct child that was + * rendered by React but is not a root element. + * @internal + */ +function hasNonRootReactChild(node) { + var reactRootID = getReactRootID(node); + return reactRootID ? reactRootID !== ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) : false; +} + +/** + * Returns the first (deepest) ancestor of a node which is rendered by this copy + * of React. + */ +function findFirstReactDOMImpl(node) { + // This node might be from another React instance, so we make sure not to + // examine the node cache here + for (; node && node.parentNode !== node; node = node.parentNode) { + if (node.nodeType !== 1) { + // Not a DOMElement, therefore not a React component + continue; + } + var nodeID = internalGetID(node); + if (!nodeID) { + continue; + } + var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID); + + // If containersByReactRootID contains the container we find by crawling up + // the tree, we know that this instance of React rendered the node. + // nb. isValid's strategy (with containsNode) does not work because render + // trees may be nested and we don't want a false positive in that case. + var current = node; + var lastID; + do { + lastID = internalGetID(current); + current = current.parentNode; + if (current == null) { + // The passed-in node has been detached from the container it was + // originally rendered into. + return null; + } + } while (lastID !== reactRootID); + + if (current === containersByReactRootID[reactRootID]) { + return node; + } + } + return null; +} + +/** + * Temporary (?) hack so that we can store all top-level pending updates on + * composites instead of having to worry about different types of components + * here. + */ +var TopLevelWrapper = function () {}; +TopLevelWrapper.prototype.isReactComponent = {}; +if (process.env.NODE_ENV !== 'production') { + TopLevelWrapper.displayName = 'TopLevelWrapper'; +} +TopLevelWrapper.prototype.render = function () { + // this.props is actually a ReactElement + return this.props; +}; + +/** * Mounting is the process of initializing a React component by creating its * representative DOM elements and inserting them into a supplied `container`. * Any prior content inside `container` is destroyed in the process. @@ -15985,6 +16669,9 @@ function batchedMountComponentIntoNode( * Inside of `container`, the first element rendered is the "reactRoot". */ var ReactMount = { + + TopLevelWrapper: TopLevelWrapper, + /** Exposed for debugging purposes **/ _instancesByReactRootID: instancesByReactRootID, @@ -15996,7 +16683,7 @@ var ReactMount = { * @param {DOMElement} container The `container` being rendered into. * @param {function} renderCallback This must be called once to do the render. */ - scrollMonitor: function(container, renderCallback) { + scrollMonitor: function (container, renderCallback) { renderCallback(); }, @@ -16007,26 +16694,17 @@ var ReactMount = { * @param {DOMElement} container container to render into * @param {?function} callback function triggered on completion */ - _updateRootComponent: function( - prevComponent, - nextElement, - container, - callback) { - if ("production" !== process.env.NODE_ENV) { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - ReactMount.scrollMonitor(container, function() { + _updateRootComponent: function (prevComponent, nextElement, container, callback) { + ReactMount.scrollMonitor(container, function () { ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); if (callback) { ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); } }); - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[getReactRootID(container)] = - getReactRootElementInContainer(container); + rootElementsByReactRootID[getReactRootID(container)] = getReactRootElementInContainer(container); } return prevComponent; @@ -16039,15 +16717,8 @@ var ReactMount = { * @param {DOMElement} container container to render into * @return {string} reactRoot ID prefix */ - _registerComponent: function(nextComponent, container) { - ("production" !== process.env.NODE_ENV ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - '_registerComponent(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); + _registerComponent: function (nextComponent, container) { + !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : invariant(false) : undefined; ReactBrowserEventEmitter.ensureScrollValueMonitoring(); @@ -16063,44 +16734,24 @@ var ReactMount = { * @param {boolean} shouldReuseMarkup if we should skip the markup insertion * @return {ReactComponent} nextComponent */ - _renderNewRootComponent: function( - nextElement, - container, - shouldReuseMarkup - ) { + _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. - ("production" !== process.env.NODE_ENV ? warning( - ReactCurrentOwner.current == null, - '_renderNewRootComponent(): Render methods should be a pure function ' + - 'of props and state; triggering nested component updates from ' + - 'render is not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); + process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined; var componentInstance = instantiateReactComponent(nextElement, null); - var reactRootID = ReactMount._registerComponent( - componentInstance, - container - ); + var reactRootID = ReactMount._registerComponent(componentInstance, container); // The initial render is synchronous but any updates that happen during // rendering, in componentWillMount or componentDidMount, will be batched // according to the current batching strategy. - ReactUpdates.batchedUpdates( - batchedMountComponentIntoNode, - componentInstance, - reactRootID, - container, - shouldReuseMarkup - ); + ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, reactRootID, container, shouldReuseMarkup, context); - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[reactRootID] = - getReactRootElementInContainer(container); + rootElementsByReactRootID[reactRootID] = getReactRootElementInContainer(container); } return componentInstance; @@ -16113,76 +16764,64 @@ var ReactMount = { * perform an update on it and only mutate the DOM as necessary to reflect the * latest React component. * + * @param {ReactComponent} parentComponent The conceptual parent of this render tree. * @param {ReactElement} nextElement Component element to render. * @param {DOMElement} container DOM element to render into. * @param {?function} callback function triggered on completion * @return {ReactComponent} Component instance rendered in `container`. */ - render: function(nextElement, container, callback) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactElement.isValidElement(nextElement), - 'React.render(): Invalid component element.%s', - ( - typeof nextElement === 'string' ? - ' Instead of passing an element string, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - typeof nextElement === 'function' ? - ' Instead of passing a component class, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? - ' This may be caused by unintentionally loading two independent ' + - 'copies of React.' : - '' - ) - ) : invariant(ReactElement.isValidElement(nextElement))); + renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { + !(parentComponent != null && parentComponent._reactInternalInstance != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : invariant(false) : undefined; + return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback); + }, + + _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { + !ReactElement.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing an element string, make sure to instantiate ' + 'it by passing it to React.createElement.' : typeof nextElement === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : + // Check if it quacks like an element + nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : invariant(false) : undefined; + + process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : undefined; + + var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement); var prevComponent = instancesByReactRootID[getReactRootID(container)]; if (prevComponent) { - var prevElement = prevComponent._currentElement; + var prevWrappedElement = prevComponent._currentElement; + var prevElement = prevWrappedElement.props; if (shouldUpdateReactComponent(prevElement, nextElement)) { - return ReactMount._updateRootComponent( - prevComponent, - nextElement, - container, - callback - ).getPublicInstance(); + var publicInst = prevComponent._renderedComponent.getPublicInstance(); + var updatedCallback = callback && function () { + callback.call(publicInst); + }; + ReactMount._updateRootComponent(prevComponent, nextWrappedElement, container, updatedCallback); + return publicInst; } else { ReactMount.unmountComponentAtNode(container); } } var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = - reactRootElement && ReactMount.isRenderedByReact(reactRootElement); + var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement); + var containerHasNonRootReactChild = hasNonRootReactChild(container); + + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : undefined; - if ("production" !== process.env.NODE_ENV) { if (!containerHasReactMarkup || reactRootElement.nextSibling) { var rootElementSibling = reactRootElement; while (rootElementSibling) { - if (ReactMount.isRenderedByReact(rootElementSibling)) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'render(): Target node has markup rendered by React, but there ' + - 'are unrelated nodes as well. This is most commonly caused by ' + - 'white-space inserted around server-rendered markup.' - ) : null); + if (internalGetID(rootElementSibling)) { + process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : undefined; break; } - rootElementSibling = rootElementSibling.nextSibling; } } } - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; - - var component = ReactMount._renderNewRootComponent( - nextElement, - container, - shouldReuseMarkup - ).getPublicInstance(); + var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild; + var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, parentComponent != null ? parentComponent._reactInternalInstance._processChildContext(parentComponent._reactInternalInstance._context) : emptyObject)._renderedComponent.getPublicInstance(); if (callback) { callback.call(component); } @@ -16190,36 +16829,19 @@ var ReactMount = { }, /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into the supplied `container`. + * Renders a React component into the DOM in the supplied `container`. * - * @param {function} constructor React component constructor. - * @param {?object} props Initial props of the component instance. + * If the React component was previously rendered into `container`, this will + * perform an update on it and only mutate the DOM as necessary to reflect the + * latest React component. + * + * @param {ReactElement} nextElement Component element to render. * @param {DOMElement} container DOM element to render into. + * @param {?function} callback function triggered on completion * @return {ReactComponent} Component instance rendered in `container`. */ - constructAndRenderComponent: function(constructor, props, container) { - var element = ReactElement.createElement(constructor, props); - return ReactMount.render(element, container); - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into a container node identified by supplied `id`. - * - * @param {function} componentConstructor React component constructor - * @param {?object} props Initial props of the component instance. - * @param {string} id ID of the DOM element to render into. - * @return {ReactComponent} Component instance rendered in the container node. - */ - constructAndRenderComponentByID: function(constructor, props, id) { - var domNode = document.getElementById(id); - ("production" !== process.env.NODE_ENV ? invariant( - domNode, - 'Tried to get element with id of "%s" but it is not present on the page.', - id - ) : invariant(domNode)); - return ReactMount.constructAndRenderComponent(constructor, props, domNode); + render: function (nextElement, container, callback) { + return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback); }, /** @@ -16230,7 +16852,7 @@ var ReactMount = { * @param {DOMElement} container DOM element to register as a container. * @return {string} The "reactRoot" ID of elements rendered within. */ - registerContainer: function(container) { + registerContainer: function (container) { var reactRootID = getReactRootID(container); if (reactRootID) { // If one exists, make sure it is a valid "reactRoot" ID. @@ -16251,101 +16873,68 @@ var ReactMount = { * @return {boolean} True if a component was found in and unmounted from * `container` */ - unmountComponentAtNode: function(container) { + unmountComponentAtNode: function (container) { // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. (Strictly speaking, unmounting won't cause a // render but we still don't expect to be in a render call here.) - ("production" !== process.env.NODE_ENV ? warning( - ReactCurrentOwner.current == null, - 'unmountComponentAtNode(): Render methods should be a pure function of ' + - 'props and state; triggering nested component updates from render is ' + - 'not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); - - ("production" !== process.env.NODE_ENV ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'unmountComponentAtNode(...): Target container is not a DOM element.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); + process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined; + + !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : invariant(false) : undefined; var reactRootID = getReactRootID(container); var component = instancesByReactRootID[reactRootID]; if (!component) { + // Check if the node being unmounted was rendered by React, but isn't a + // root node. + var containerHasNonRootReactChild = hasNonRootReactChild(container); + + // Check if the container itself is a React root node. + var containerID = internalGetID(container); + var isContainerReactRoot = containerID && containerID === ReactInstanceHandles.getReactRootIDFromNodeID(containerID); + + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : undefined; + } + return false; } - ReactMount.unmountComponentFromNode(component, container); + ReactUpdates.batchedUpdates(unmountComponentFromNode, component, container); delete instancesByReactRootID[reactRootID]; delete containersByReactRootID[reactRootID]; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { delete rootElementsByReactRootID[reactRootID]; } return true; }, /** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ - unmountComponentFromNode: function(instance, container) { - ReactReconciler.unmountComponent(instance); - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } - }, - - /** * Finds the container DOM element that contains React component to which the * supplied DOM `id` belongs. * * @param {string} id The ID of an element rendered by a React component. * @return {?DOMElement} DOM element that contains the `id`. */ - findReactContainerForID: function(id) { + findReactContainerForID: function (id) { var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); var container = containersByReactRootID[reactRootID]; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { var rootElement = rootElementsByReactRootID[reactRootID]; if (rootElement && rootElement.parentNode !== container) { - ("production" !== process.env.NODE_ENV ? invariant( - // Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID, - 'ReactMount: Root element ID differed from reactRootID.' - ) : invariant(// Call internalGetID here because getID calls isValid which calls + process.env.NODE_ENV !== 'production' ? warning( + // Call internalGetID here because getID calls isValid which calls // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID)); - + internalGetID(rootElement) === reactRootID, 'ReactMount: Root element ID differed from reactRootID.') : undefined; var containerChild = container.firstChild; - if (containerChild && - reactRootID === internalGetID(containerChild)) { + if (containerChild && reactRootID === internalGetID(containerChild)) { // If the container has a new child with the same ID as the old // root element, then rootElementsByReactRootID[reactRootID] is // just stale and needs to be updated. The case that deserves a // warning is when the container is empty. rootElementsByReactRootID[reactRootID] = containerChild; } else { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'ReactMount: Root element has been removed from its original ' + - 'container. New container:', rootElement.parentNode - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'ReactMount: Root element has been removed from its original ' + 'container. New container: %s', rootElement.parentNode) : undefined; } } } @@ -16359,44 +16948,21 @@ var ReactMount = { * @param {string} id ID of a DOM node in the React component. * @return {DOMElement} Root DOM node of the React component. */ - findReactNodeByID: function(id) { + findReactNodeByID: function (id) { var reactRoot = ReactMount.findReactContainerForID(id); return ReactMount.findComponentRoot(reactRoot, id); }, /** - * True if the supplied `node` is rendered by React. - * - * @param {*} node DOM Element to check. - * @return {boolean} True if the DOM Element appears to be rendered by React. - * @internal - */ - isRenderedByReact: function(node) { - if (node.nodeType !== 1) { - // Not a DOMElement, therefore not a React component - return false; - } - var id = ReactMount.getID(node); - return id ? id.charAt(0) === SEPARATOR : false; - }, - - /** * Traverses up the ancestors of the supplied node to find a node that is a - * DOM representation of a React component. + * DOM representation of a React component rendered by this copy of React. * * @param {*} node * @return {?DOMEventTarget} * @internal */ - getFirstReactDOM: function(node) { - var current = node; - while (current && current.parentNode !== current) { - if (ReactMount.isRenderedByReact(current)) { - return current; - } - current = current.parentNode; - } - return null; + getFirstReactDOM: function (node) { + return findFirstReactDOMImpl(node); }, /** @@ -16409,12 +16975,17 @@ var ReactMount = { * @return {DOMEventTarget} DOM node with the supplied `targetID`. * @internal */ - findComponentRoot: function(ancestorNode, targetID) { + findComponentRoot: function (ancestorNode, targetID) { var firstChildren = findComponentRootReusableArray; var childIndex = 0; var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; + if (process.env.NODE_ENV !== 'production') { + // This will throw on the next line; give an early warning + process.env.NODE_ENV !== 'production' ? warning(deepestAncestor != null, 'React can\'t find the root component node for data-reactid value ' + '`%s`. If you\'re seeing this message, it probably means that ' + 'you\'ve loaded two copies of React on the page. At this time, only ' + 'a single copy of React can be loaded at a time.', targetID) : undefined; + } + firstChildren[0] = deepestAncestor.firstChild; firstChildren.length = 1; @@ -16440,7 +17011,6 @@ var ReactMount = { firstChildren.length = childIndex = 0; firstChildren.push(child.firstChild); } - } else { // If this child had no ID, then there's a chance that it was // injected automatically by the browser, as when a `<table>` @@ -16465,91 +17035,68 @@ var ReactMount = { firstChildren.length = 0; - ("production" !== process.env.NODE_ENV ? invariant( - false, - 'findComponentRoot(..., %s): Unable to find element. This probably ' + - 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + - 'usually due to forgetting a <tbody> when using tables, nesting tags ' + - 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + - 'parent. ' + - 'Try inspecting the child nodes of the element with React ID `%s`.', - targetID, - ReactMount.getID(ancestorNode) - ) : invariant(false)); - }, - - _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { - ("production" !== process.env.NODE_ENV ? invariant( - container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ), - 'mountComponentIntoNode(...): Target container is not valid.' - ) : invariant(container && ( - (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) - ))); + !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findComponentRoot(..., %s): Unable to find element. This probably ' + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 'usually due to forgetting a <tbody> when using tables, nesting tags ' + 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + 'parent. ' + 'Try inspecting the child nodes of the element with React ID `%s`.', targetID, ReactMount.getID(ancestorNode)) : invariant(false) : undefined; + }, + + _mountImageIntoNode: function (markup, container, shouldReuseMarkup, transaction) { + !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : invariant(false) : undefined; if (shouldReuseMarkup) { var rootElement = getReactRootElementInContainer(container); if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { return; } else { - var checksum = rootElement.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); + var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME, - checksum - ); - - var diffIndex = firstDifferenceIndex(markup, rootMarkup); - var difference = ' (client) ' + - markup.substring(diffIndex - 20, diffIndex + 20) + - '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - ("production" !== process.env.NODE_ENV ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document using ' + - 'server rendering but the checksum was invalid. This usually ' + - 'means you rendered a different component type or props on ' + - 'the client from the one on the server, or your render() ' + - 'methods are impure. React cannot handle this case due to ' + - 'cross-browser quirks by rendering at the document root. You ' + - 'should look for environment dependent code in your components ' + - 'and ensure the props are the same client and server side:\n%s', - difference - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - false, - 'React attempted to reuse markup in a container but the ' + - 'checksum was invalid. This generally means that you are ' + - 'using server rendering and the markup generated on the ' + - 'server was not what the client was expecting. React injected ' + - 'new markup to compensate which works but you have lost many ' + - 'of the benefits of server rendering. Instead, figure out ' + - 'why the markup being generated is different on the client ' + - 'or server:\n%s', - difference - ) : null); + rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum); + + var normalizedMarkup = markup; + if (process.env.NODE_ENV !== 'production') { + // because rootMarkup is retrieved from the DOM, various normalizations + // will have occurred which will not be present in `markup`. Here, + // insert markup into a <div> or <iframe> depending on the container + // type to perform the same normalizations before comparing. + var normalizer; + if (container.nodeType === ELEMENT_NODE_TYPE) { + normalizer = document.createElement('div'); + normalizer.innerHTML = markup; + normalizedMarkup = normalizer.innerHTML; + } else { + normalizer = document.createElement('iframe'); + document.body.appendChild(normalizer); + normalizer.contentDocument.write(markup); + normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML; + document.body.removeChild(normalizer); + } + } + + var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup); + var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); + + !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document using ' + 'server rendering but the checksum was invalid. This usually ' + 'means you rendered a different component type or props on ' + 'the client from the one on the server, or your render() ' + 'methods are impure. React cannot handle this case due to ' + 'cross-browser quirks by rendering at the document root. You ' + 'should look for environment dependent code in your components ' + 'and ensure the props are the same client and server side:\n%s', difference) : invariant(false) : undefined; + + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\n%s', difference) : undefined; } } } - ("production" !== process.env.NODE_ENV ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document but ' + - 'you didn\'t use server rendering. We can\'t do this ' + - 'without using server rendering due to cross-browser quirks. ' + - 'See React.renderToString() for server rendering.' - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); + !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but ' + 'you didn\'t use server rendering. We can\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined; - setInnerHTML(container, markup); + if (transaction.useCreateElement) { + while (container.lastChild) { + container.removeChild(container.lastChild); + } + container.appendChild(markup); + } else { + setInnerHTML(container, markup); + } }, + ownerDocumentContextKey: ownerDocumentContextKey, + /** * React ID utilities. */ @@ -16564,6 +17111,8 @@ var ReactMount = { getNodeFromInstance: getNodeFromInstance, + isValid: isValid, + purgeID: purgeID }; @@ -16573,10 +17122,10 @@ ReactPerf.measureMethods(ReactMount, 'ReactMount', { }); module.exports = ReactMount; - }).call(this,require('_process')) -},{"./DOMProperty":51,"./ReactBrowserEventEmitter":73,"./ReactCurrentOwner":85,"./ReactElement":103,"./ReactElementValidator":104,"./ReactEmptyComponent":105,"./ReactInstanceHandles":112,"./ReactInstanceMap":113,"./ReactMarkupChecksum":116,"./ReactPerf":122,"./ReactReconciler":129,"./ReactUpdateQueue":139,"./ReactUpdates":140,"./containsNode":164,"./emptyObject":171,"./getReactRootElementInContainer":185,"./instantiateReactComponent":190,"./invariant":191,"./setInnerHTML":205,"./shouldUpdateReactComponent":208,"./warning":212,"_process":1}],118:[function(require,module,exports){ +},{"./DOMProperty":68,"./Object.assign":82,"./ReactBrowserEventEmitter":86,"./ReactCurrentOwner":97,"./ReactDOMFeatureFlags":102,"./ReactElement":115,"./ReactEmptyComponentRegistry":118,"./ReactInstanceHandles":125,"./ReactInstanceMap":126,"./ReactMarkupChecksum":129,"./ReactPerf":136,"./ReactReconciler":142,"./ReactUpdateQueue":153,"./ReactUpdates":154,"./instantiateReactComponent":191,"./setInnerHTML":197,"./shouldUpdateReactComponent":200,"./validateDOMNesting":203,"_process":1,"fbjs/lib/containsNode":209,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],131:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -16591,11 +17140,14 @@ module.exports = ReactMount; 'use strict'; -var ReactComponentEnvironment = require("./ReactComponentEnvironment"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); +var ReactComponentEnvironment = require('./ReactComponentEnvironment'); +var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes'); -var ReactReconciler = require("./ReactReconciler"); -var ReactChildReconciler = require("./ReactChildReconciler"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactReconciler = require('./ReactReconciler'); +var ReactChildReconciler = require('./ReactChildReconciler'); + +var flattenChildren = require('./flattenChildren'); /** * Updating children of a component may trigger recursive updates. The depth is @@ -16632,14 +17184,14 @@ var markupQueue = []; * @param {number} toIndex Destination index. * @private */ -function enqueueMarkup(parentID, markup, toIndex) { +function enqueueInsertMarkup(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, + content: null, fromIndex: null, toIndex: toIndex }); @@ -16660,7 +17212,7 @@ function enqueueMove(parentID, fromIndex, toIndex) { parentNode: null, type: ReactMultiChildUpdateTypes.MOVE_EXISTING, markupIndex: null, - textContent: null, + content: null, fromIndex: fromIndex, toIndex: toIndex }); @@ -16680,13 +17232,33 @@ function enqueueRemove(parentID, fromIndex) { parentNode: null, type: ReactMultiChildUpdateTypes.REMOVE_NODE, markupIndex: null, - textContent: null, + content: null, fromIndex: fromIndex, toIndex: null }); } /** + * Enqueues setting the markup of a node. + * + * @param {string} parentID ID of the parent component. + * @param {string} markup Markup that renders into an element. + * @private + */ +function enqueueSetMarkup(parentID, markup) { + // NOTE: Null values reduce hidden classes. + updateQueue.push({ + parentID: parentID, + parentNode: null, + type: ReactMultiChildUpdateTypes.SET_MARKUP, + markupIndex: null, + content: markup, + fromIndex: null, + toIndex: null + }); +} + +/** * Enqueues setting the text content. * * @param {string} parentID ID of the parent component. @@ -16700,7 +17272,7 @@ function enqueueTextContent(parentID, textContent) { parentNode: null, type: ReactMultiChildUpdateTypes.TEXT_CONTENT, markupIndex: null, - textContent: textContent, + content: textContent, fromIndex: null, toIndex: null }); @@ -16713,10 +17285,7 @@ function enqueueTextContent(parentID, textContent) { */ function processQueue() { if (updateQueue.length) { - ReactComponentEnvironment.processChildrenUpdates( - updateQueue, - markupQueue - ); + ReactComponentEnvironment.processChildrenUpdates(updateQueue, markupQueue); clearQueue(); } } @@ -16748,6 +17317,37 @@ var ReactMultiChild = { */ Mixin: { + _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) { + if (process.env.NODE_ENV !== 'production') { + if (this._currentElement) { + try { + ReactCurrentOwner.current = this._currentElement._owner; + return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context); + } finally { + ReactCurrentOwner.current = null; + } + } + } + return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context); + }, + + _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, transaction, context) { + var nextChildren; + if (process.env.NODE_ENV !== 'production') { + if (this._currentElement) { + try { + ReactCurrentOwner.current = this._currentElement._owner; + nextChildren = flattenChildren(nextNestedChildrenElements); + } finally { + ReactCurrentOwner.current = null; + } + return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context); + } + } + nextChildren = flattenChildren(nextNestedChildrenElements); + return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context); + }, + /** * Generates a "mount image" for each of the supplied children. In the case * of `ReactDOMComponent`, a mount image is a string of markup. @@ -16756,10 +17356,8 @@ var ReactMultiChild = { * @return {array} An array of mounted representations. * @internal */ - mountChildren: function(nestedChildren, transaction, context) { - var children = ReactChildReconciler.instantiateChildren( - nestedChildren, transaction, context - ); + mountChildren: function (nestedChildren, transaction, context) { + var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context); this._renderedChildren = children; var mountImages = []; var index = 0; @@ -16768,15 +17366,9 @@ var ReactMultiChild = { 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; + var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context); + child._mountIndex = index++; mountImages.push(mountImage); - index++; } } return mountImages; @@ -16788,7 +17380,7 @@ var ReactMultiChild = { * @param {string} nextContent String of content. * @internal */ - updateTextContent: function(nextContent) { + updateTextContent: function (nextContent) { updateDepth++; var errorThrown = true; try { @@ -16798,7 +17390,7 @@ var ReactMultiChild = { // TODO: The setTextContent operation should be enough for (var name in prevChildren) { if (prevChildren.hasOwnProperty(name)) { - this._unmountChildByName(prevChildren[name], name); + this._unmountChild(prevChildren[name]); } } // Set new text content. @@ -16817,17 +17409,49 @@ var ReactMultiChild = { }, /** + * Replaces any rendered children with a markup string. + * + * @param {string} nextMarkup String of markup. + * @internal + */ + updateMarkup: function (nextMarkup) { + updateDepth++; + var errorThrown = true; + try { + var prevChildren = this._renderedChildren; + // Remove any rendered children. + ReactChildReconciler.unmountChildren(prevChildren); + for (var name in prevChildren) { + if (prevChildren.hasOwnProperty(name)) { + this._unmountChildByName(prevChildren[name], name); + } + } + this.setMarkup(nextMarkup); + 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 {?object} nextNestedChildrenElements Nested child element maps. * @param {ReactReconcileTransaction} transaction * @internal */ - updateChildren: function(nextNestedChildren, transaction, context) { + updateChildren: function (nextNestedChildrenElements, transaction, context) { updateDepth++; var errorThrown = true; try { - this._updateChildren(nextNestedChildren, transaction, context); + this._updateChildren(nextNestedChildrenElements, transaction, context); errorThrown = false; } finally { updateDepth--; @@ -16838,7 +17462,6 @@ var ReactMultiChild = { processQueue(); } } - } }, @@ -16846,16 +17469,14 @@ var ReactMultiChild = { * Improve performance by isolating this hot code path from the try/catch * block in `updateChildren`. * - * @param {?object} nextNestedChildren Nested child maps. + * @param {?object} nextNestedChildrenElements Nested child element maps. * @param {ReactReconcileTransaction} transaction * @final * @protected */ - _updateChildren: function(nextNestedChildren, transaction, context) { + _updateChildren: function (nextNestedChildrenElements, transaction, context) { var prevChildren = this._renderedChildren; - var nextChildren = ReactChildReconciler.updateChildren( - prevChildren, nextNestedChildren, transaction, context - ); + var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, transaction, context); this._renderedChildren = nextChildren; if (!nextChildren && !prevChildren) { return; @@ -16879,20 +17500,17 @@ var ReactMultiChild = { if (prevChild) { // Update `lastIndex` before `_mountIndex` gets unset by unmounting. lastIndex = Math.max(prevChild._mountIndex, lastIndex); - this._unmountChildByName(prevChild, name); + this._unmountChild(prevChild); } // The child must be instantiated before it's mounted. - this._mountChildByNameAtIndex( - nextChild, name, nextIndex, transaction, context - ); + 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); + if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { + this._unmountChild(prevChildren[name]); } } }, @@ -16903,7 +17521,7 @@ var ReactMultiChild = { * * @internal */ - unmountChildren: function() { + unmountChildren: function () { var renderedChildren = this._renderedChildren; ReactChildReconciler.unmountChildren(renderedChildren); this._renderedChildren = null; @@ -16917,7 +17535,7 @@ var ReactMultiChild = { * @param {number} lastIndex Last index visited of the siblings of `child`. * @protected */ - moveChild: function(child, toIndex, lastIndex) { + 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`. @@ -16933,8 +17551,8 @@ var ReactMultiChild = { * @param {string} mountImage Markup to insert. * @protected */ - createChild: function(child, mountImage) { - enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex); + createChild: function (child, mountImage) { + enqueueInsertMarkup(this._rootNodeID, mountImage, child._mountIndex); }, /** @@ -16943,7 +17561,7 @@ var ReactMultiChild = { * @param {ReactComponent} child Child to remove. * @protected */ - removeChild: function(child) { + removeChild: function (child) { enqueueRemove(this._rootNodeID, child._mountIndex); }, @@ -16953,11 +17571,21 @@ var ReactMultiChild = { * @param {string} textContent Text content to set. * @protected */ - setTextContent: function(textContent) { + setTextContent: function (textContent) { enqueueTextContent(this._rootNodeID, textContent); }, /** + * Sets this markup string. + * + * @param {string} markup Markup to set. + * @protected + */ + setMarkup: function (markup) { + enqueueSetMarkup(this._rootNodeID, markup); + }, + + /** * Mounts a child with the supplied name. * * NOTE: This is part of `updateChildren` and is here for readability. @@ -16968,34 +17596,23 @@ var ReactMultiChild = { * @param {ReactReconcileTransaction} transaction * @private */ - _mountChildByNameAtIndex: function( - child, - name, - index, - transaction, - context) { + _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 - ); + var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context); child._mountIndex = index; this.createChild(child, mountImage); }, /** - * Unmounts a rendered child by name. + * Unmounts a rendered child. * * 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) { + _unmountChild: function (child) { this.removeChild(child); child._mountIndex = null; } @@ -17005,8 +17622,9 @@ var ReactMultiChild = { }; module.exports = ReactMultiChild; +}).call(this,require('_process')) -},{"./ReactChildReconciler":76,"./ReactComponentEnvironment":81,"./ReactMultiChildUpdateTypes":119,"./ReactReconciler":129}],119:[function(require,module,exports){ +},{"./ReactChildReconciler":89,"./ReactComponentEnvironment":94,"./ReactCurrentOwner":97,"./ReactMultiChildUpdateTypes":132,"./ReactReconciler":142,"./flattenChildren":182,"_process":1}],132:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -17020,7 +17638,7 @@ module.exports = ReactMultiChild; 'use strict'; -var keyMirror = require("./keyMirror"); +var keyMirror = require('fbjs/lib/keyMirror'); /** * When a component's children are updated, a series of update configuration @@ -17034,12 +17652,12 @@ var ReactMultiChildUpdateTypes = keyMirror({ INSERT_MARKUP: null, MOVE_EXISTING: null, REMOVE_NODE: null, + SET_MARKUP: null, TEXT_CONTENT: null }); module.exports = ReactMultiChildUpdateTypes; - -},{"./keyMirror":197}],120:[function(require,module,exports){ +},{"fbjs/lib/keyMirror":224}],133:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -17054,35 +17672,30 @@ module.exports = ReactMultiChildUpdateTypes; 'use strict'; -var assign = require("./Object.assign"); -var invariant = require("./invariant"); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); var autoGenerateWrapperClass = null; var genericComponentClass = null; -// This registry keeps track of wrapper classes around native tags +// 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) { + injectGenericComponentClass: function (componentClass) { genericComponentClass = componentClass; }, // This accepts a text component class that takes the text string to be // rendered as props. - injectTextComponentClass: function(componentClass) { + 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) { + 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; } }; @@ -17111,11 +17724,7 @@ function getComponentClassForElement(element) { * @return {function} The internal class constructor function. */ function createInternalComponent(element) { - ("production" !== process.env.NODE_ENV ? invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - element.type - ) : invariant(genericComponentClass)); + !genericComponentClass ? process.env.NODE_ENV !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : invariant(false) : undefined; return new genericComponentClass(element.type, element.props); } @@ -17144,10 +17753,131 @@ var ReactNativeComponent = { }; module.exports = ReactNativeComponent; +}).call(this,require('_process')) + +},{"./Object.assign":82,"_process":1,"fbjs/lib/invariant":220}],134:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactNoopUpdateQueue + */ + +'use strict'; + +var warning = require('fbjs/lib/warning'); + +function warnTDZ(publicInstance, callerName) { + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor && publicInstance.constructor.displayName || '') : undefined; + } +} + +/** + * This is the abstract API for an update queue. + */ +var ReactNoopUpdateQueue = { + + /** + * Checks whether or not this composite component is mounted. + * @param {ReactClass} publicInstance The instance we want to test. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function (publicInstance) { + return false; + }, + + /** + * 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) {}, + + /** + * 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 {ReactClass} publicInstance The instance that should rerender. + * @internal + */ + enqueueForceUpdate: function (publicInstance) { + warnTDZ(publicInstance, 'forceUpdate'); + }, + + /** + * 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) { + warnTDZ(publicInstance, 'replaceState'); + }, + + /** + * 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) { + warnTDZ(publicInstance, 'setState'); + }, + + /** + * 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) { + warnTDZ(publicInstance, 'setProps'); + }, + /** + * Replaces all of the props. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} props New props. + * @internal + */ + enqueueReplaceProps: function (publicInstance, props) { + warnTDZ(publicInstance, 'replaceProps'); + } + +}; + +module.exports = ReactNoopUpdateQueue; }).call(this,require('_process')) -},{"./Object.assign":69,"./invariant":191,"_process":1}],121:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/warning":232}],135:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -17162,7 +17892,7 @@ module.exports = ReactNativeComponent; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * ReactOwners are capable of storing references to owned components. @@ -17201,11 +17931,8 @@ var ReactOwner = { * @return {boolean} True if `object` is a valid owner. * @final */ - isValidOwner: function(object) { - return !!( - (object && - typeof object.attachRef === 'function' && typeof object.detachRef === 'function') - ); + isValidOwner: function (object) { + return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function'); }, /** @@ -17217,15 +17944,8 @@ var ReactOwner = { * @final * @internal */ - addComponentAsRefTo: function(component, ref, owner) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactOwner.isValidOwner(owner), - 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to add a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); + addComponentAsRefTo: function (component, ref, owner) { + !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might ' + 'be adding a ref to a component that was not created inside a component\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined; owner.attachRef(ref, component); }, @@ -17238,15 +17958,8 @@ var ReactOwner = { * @final * @internal */ - removeComponentAsRefFrom: function(component, ref, owner) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactOwner.isValidOwner(owner), - 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to remove a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ) : invariant(ReactOwner.isValidOwner(owner))); + removeComponentAsRefFrom: function (component, ref, owner) { + !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might ' + 'be removing a ref to a component that was not created inside a component\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined; // 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()) { @@ -17257,10 +17970,9 @@ var ReactOwner = { }; module.exports = ReactOwner; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],122:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],136:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -17298,17 +18010,13 @@ var ReactPerf = { * @param {string} objectName * @param {object<string>} methodNames */ - measureMethods: function(object, objectName, methodNames) { - if ("production" !== process.env.NODE_ENV) { + measureMethods: function (object, objectName, methodNames) { + if (process.env.NODE_ENV !== 'production') { for (var key in methodNames) { if (!methodNames.hasOwnProperty(key)) { continue; } - object[key] = ReactPerf.measure( - objectName, - methodNames[key], - object[key] - ); + object[key] = ReactPerf.measure(objectName, methodNames[key], object[key]); } } }, @@ -17321,10 +18029,10 @@ var ReactPerf = { * @param {function} func * @return {function} */ - measure: function(objName, fnName, func) { - if ("production" !== process.env.NODE_ENV) { + measure: function (objName, fnName, func) { + if (process.env.NODE_ENV !== 'production') { var measuredFunc = null; - var wrapper = function() { + var wrapper = function () { if (ReactPerf.enableMeasure) { if (!measuredFunc) { measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); @@ -17343,7 +18051,7 @@ var ReactPerf = { /** * @param {function} measure */ - injectMeasure: function(measure) { + injectMeasure: function (measure) { ReactPerf.storedMeasure = measure; } } @@ -17362,10 +18070,9 @@ function _noMeasure(objName, fnName, func) { } module.exports = ReactPerf; - }).call(this,require('_process')) -},{"_process":1}],123:[function(require,module,exports){ +},{"_process":1}],137:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -17379,9 +18086,9 @@ module.exports = ReactPerf; 'use strict'; -var assign = require("./Object.assign"); -var emptyFunction = require("./emptyFunction"); -var joinClasses = require("./joinClasses"); +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var joinClasses = require('fbjs/lib/joinClasses'); /** * Creates a transfer strategy that will merge prop values using the supplied @@ -17391,7 +18098,7 @@ var joinClasses = require("./joinClasses"); * @return {function} */ function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { + return function (props, key, value) { if (!props.hasOwnProperty(key)) { props[key] = value; } else { @@ -17400,7 +18107,7 @@ function createTransferStrategy(mergeStrategy) { }; } -var transferStrategyMerge = createTransferStrategy(function(a, b) { +var transferStrategyMerge = createTransferStrategy(function (a, b) { // `merge` overrides the first object's (`props[key]` above) keys using the // second object's (`value`) keys. An object's style's existing `propA` would // get overridden. Flip the order here. @@ -17467,15 +18174,14 @@ var ReactPropTransferer = { * @param {object} newProps new props to merge in * @return {object} a new object containing both sets of props merged. */ - mergeProps: function(oldProps, newProps) { + mergeProps: function (oldProps, newProps) { return transferInto(assign({}, oldProps), newProps); } }; module.exports = ReactPropTransferer; - -},{"./Object.assign":69,"./emptyFunction":170,"./joinClasses":196}],124:[function(require,module,exports){ +},{"./Object.assign":82,"fbjs/lib/emptyFunction":212,"fbjs/lib/joinClasses":223}],138:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -17492,7 +18198,7 @@ module.exports = ReactPropTransferer; var ReactPropTypeLocationNames = {}; -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { ReactPropTypeLocationNames = { prop: 'prop', context: 'context', @@ -17501,10 +18207,9 @@ if ("production" !== process.env.NODE_ENV) { } module.exports = ReactPropTypeLocationNames; - }).call(this,require('_process')) -},{"_process":1}],125:[function(require,module,exports){ +},{"_process":1}],139:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -17518,7 +18223,7 @@ module.exports = ReactPropTypeLocationNames; 'use strict'; -var keyMirror = require("./keyMirror"); +var keyMirror = require('fbjs/lib/keyMirror'); var ReactPropTypeLocations = keyMirror({ prop: null, @@ -17527,8 +18232,7 @@ var ReactPropTypeLocations = keyMirror({ }); module.exports = ReactPropTypeLocations; - -},{"./keyMirror":197}],126:[function(require,module,exports){ +},{"fbjs/lib/keyMirror":224}],140:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -17542,11 +18246,11 @@ module.exports = ReactPropTypeLocations; 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactFragment = require("./ReactFragment"); -var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames"); +var ReactElement = require('./ReactElement'); +var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); -var emptyFunction = require("./emptyFunction"); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var getIteratorFn = require('./getIteratorFn'); /** * Collection of methods that allow declaration and validation of props that are @@ -17597,9 +18301,6 @@ var emptyFunction = require("./emptyFunction"); var ANONYMOUS = '<<anonymous>>'; -var elementTypeChecker = createElementTypeChecker(); -var nodeTypeChecker = createNodeChecker(); - var ReactPropTypes = { array: createPrimitiveTypeChecker('array'), bool: createPrimitiveTypeChecker('boolean'), @@ -17610,9 +18311,9 @@ var ReactPropTypes = { any: createAnyTypeChecker(), arrayOf: createArrayOfTypeChecker, - element: elementTypeChecker, + element: createElementTypeChecker(), instanceOf: createInstanceTypeChecker, - node: nodeTypeChecker, + node: createNodeChecker(), objectOf: createObjectOfTypeChecker, oneOf: createEnumTypeChecker, oneOfType: createUnionTypeChecker, @@ -17620,19 +18321,17 @@ var ReactPropTypes = { }; function createChainableTypeChecker(validate) { - function checkType(isRequired, props, propName, componentName, location) { + function checkType(isRequired, props, propName, componentName, location, propFullName) { componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; if (props[propName] == null) { var locationName = ReactPropTypeLocationNames[location]; if (isRequired) { - return new Error( - ("Required " + locationName + " `" + propName + "` was not specified in ") + - ("`" + componentName + "`.") - ); + return new Error('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.')); } return null; } else { - return validate(props, propName, componentName, location); + return validate(props, propName, componentName, location, propFullName); } } @@ -17643,7 +18342,7 @@ function createChainableTypeChecker(validate) { } function createPrimitiveTypeChecker(expectedType) { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== expectedType) { @@ -17653,10 +18352,7 @@ function createPrimitiveTypeChecker(expectedType) { // 'of type `object`'. var preciseType = getPreciseType(propValue); - return new Error( - ("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") + - ("supplied to `" + componentName + "`, expected `" + expectedType + "`.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); } return null; } @@ -17668,18 +18364,15 @@ function createAnyTypeChecker() { } function createArrayOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { 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.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); } for (var i = 0; i < propValue.length; i++) { - var error = typeChecker(propValue, i, componentName, location); + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']'); if (error instanceof Error) { return error; } @@ -17690,13 +18383,10 @@ function createArrayOfTypeChecker(typeChecker) { } function createElementTypeChecker() { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { if (!ReactElement.isValidElement(props[propName])) { var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactElement.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a single ReactElement.')); } return null; } @@ -17704,14 +18394,12 @@ function createElementTypeChecker() { } function createInstanceTypeChecker(expectedClass) { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { 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 + "`.") - ); + var actualClassName = getClassName(props[propName]); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); } return null; } @@ -17719,7 +18407,13 @@ function createInstanceTypeChecker(expectedClass) { } function createEnumTypeChecker(expectedValues) { - function validate(props, propName, componentName, location) { + if (!Array.isArray(expectedValues)) { + return createChainableTypeChecker(function () { + return new Error('Invalid argument supplied to oneOf, expected an instance of array.'); + }); + } + + function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; for (var i = 0; i < expectedValues.length; i++) { if (propValue === expectedValues[i]) { @@ -17729,28 +18423,22 @@ function createEnumTypeChecker(expectedValues) { 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 new Error('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); } return createChainableTypeChecker(validate); } function createObjectOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { 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.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` 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); + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key); if (error instanceof Error) { return error; } @@ -17762,31 +18450,31 @@ function createObjectOfTypeChecker(typeChecker) { } function createUnionTypeChecker(arrayOfTypeCheckers) { - function validate(props, propName, componentName, location) { + if (!Array.isArray(arrayOfTypeCheckers)) { + return createChainableTypeChecker(function () { + return new Error('Invalid argument supplied to oneOfType, expected an instance of array.'); + }); + } + + function validate(props, propName, componentName, location, propFullName) { for (var i = 0; i < arrayOfTypeCheckers.length; i++) { var checker = arrayOfTypeCheckers[i]; - if (checker(props, propName, componentName, location) == null) { + if (checker(props, propName, componentName, location, propFullName) == null) { return null; } } var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); } return createChainableTypeChecker(validate); } function createNodeChecker() { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { if (!isNode(props[propName])) { var locationName = ReactPropTypeLocationNames[location]; - return new Error( - ("Invalid " + locationName + " `" + propName + "` supplied to ") + - ("`" + componentName + "`, expected a ReactNode.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); } return null; } @@ -17794,22 +18482,19 @@ function createNodeChecker() { } function createShapeTypeChecker(shapeTypes) { - function validate(props, propName, componentName, location) { + function validate(props, propName, componentName, location, propFullName) { 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`.") - ); + return new Error('Invalid ' + locationName + ' `' + propFullName + '` 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); + var error = checker(propValue, key, componentName, location, propFullName + '.' + key); if (error) { return error; } @@ -17834,12 +18519,32 @@ function isNode(propValue) { if (propValue === null || ReactElement.isValidElement(propValue)) { return true; } - propValue = ReactFragment.extractIfFragment(propValue); - for (var k in propValue) { - if (!isNode(propValue[k])) { - return false; + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } } + } else { + return false; } + return true; default: return false; @@ -17875,65 +18580,16 @@ function getPreciseType(propValue) { return propType; } -module.exports = ReactPropTypes; - -},{"./ReactElement":103,"./ReactFragment":109,"./ReactPropTypeLocationNames":124,"./emptyFunction":170}],127:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPutListenerQueue - */ - -'use strict'; - -var PooledClass = require("./PooledClass"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); - -var assign = require("./Object.assign"); - -function ReactPutListenerQueue() { - this.listenersToPut = []; -} - -assign(ReactPutListenerQueue.prototype, { - enqueuePutListener: function(rootNodeID, propKey, propValue) { - this.listenersToPut.push({ - rootNodeID: rootNodeID, - propKey: propKey, - propValue: propValue - }); - }, - - putListeners: function() { - for (var i = 0; i < this.listenersToPut.length; i++) { - var listenerToPut = this.listenersToPut[i]; - ReactBrowserEventEmitter.putListener( - listenerToPut.rootNodeID, - listenerToPut.propKey, - listenerToPut.propValue - ); - } - }, - - reset: function() { - this.listenersToPut.length = 0; - }, - - destructor: function() { - this.reset(); +// Returns class name of the object, if any. +function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return '<<anonymous>>'; } -}); - -PooledClass.addPoolingTo(ReactPutListenerQueue); - -module.exports = ReactPutListenerQueue; + return propValue.constructor.name; +} -},{"./Object.assign":69,"./PooledClass":70,"./ReactBrowserEventEmitter":73}],128:[function(require,module,exports){ +module.exports = ReactPropTypes; +},{"./ReactElement":115,"./ReactPropTypeLocationNames":138,"./getIteratorFn":188,"fbjs/lib/emptyFunction":212}],141:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -17948,14 +18604,14 @@ module.exports = ReactPutListenerQueue; 'use strict'; -var CallbackQueue = require("./CallbackQueue"); -var PooledClass = require("./PooledClass"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); -var ReactInputSelection = require("./ReactInputSelection"); -var ReactPutListenerQueue = require("./ReactPutListenerQueue"); -var Transaction = require("./Transaction"); +var CallbackQueue = require('./CallbackQueue'); +var PooledClass = require('./PooledClass'); +var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); +var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags'); +var ReactInputSelection = require('./ReactInputSelection'); +var Transaction = require('./Transaction'); -var assign = require("./Object.assign"); +var assign = require('./Object.assign'); /** * Ensures that, when possible, the selection range (currently selected text @@ -17982,7 +18638,7 @@ var EVENT_SUPPRESSION = { * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before * the reconciliation. */ - initialize: function() { + initialize: function () { var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); ReactBrowserEventEmitter.setEnabled(false); return currentlyEnabled; @@ -17990,10 +18646,10 @@ var EVENT_SUPPRESSION = { /** * @param {boolean} previouslyEnabled Enabled status of - * `ReactBrowserEventEmitter` before the reconciliation occured. `close` + * `ReactBrowserEventEmitter` before the reconciliation occurred. `close` * restores the previous value. */ - close: function(previouslyEnabled) { + close: function (previouslyEnabled) { ReactBrowserEventEmitter.setEnabled(previouslyEnabled); } }; @@ -18006,39 +18662,24 @@ var ON_DOM_READY_QUEUEING = { /** * Initializes the internal `onDOMReady` queue. */ - initialize: function() { + initialize: function () { this.reactMountReady.reset(); }, /** * After DOM is flushed, invoke all registered `onDOMReady` callbacks. */ - close: function() { + close: function () { this.reactMountReady.notifyAll(); } }; -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: function() { - this.putListenerQueue.putListeners(); - } -}; - /** * Executed within the scope of the `Transaction` instance. Consider these as * being member methods, but with an implied ordering while being isolated from * each other. */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - SELECTION_RESTORATION, - EVENT_SUPPRESSION, - ON_DOM_READY_QUEUEING -]; +var TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING]; /** * Currently: @@ -18054,7 +18695,7 @@ var TRANSACTION_WRAPPERS = [ * * @class ReactReconcileTransaction */ -function ReactReconcileTransaction() { +function ReactReconcileTransaction(forceHTML) { this.reinitializeTransaction(); // Only server-side rendering really needs this option (see // `ReactServerRendering`), but server-side uses @@ -18063,7 +18704,7 @@ function ReactReconcileTransaction() { // `ReactTextComponent` checks it in `mountComponent`.` this.renderToStaticMarkup = false; this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); + this.useCreateElement = !forceHTML && ReactDOMFeatureFlags.useCreateElement; } var Mixin = { @@ -18071,46 +18712,36 @@ var Mixin = { * @see Transaction * @abstract * @final - * @return {array<object>} List of operation wrap proceedures. + * @return {array<object>} List of operation wrap procedures. * TODO: convert to array<TransactionWrapper> */ - getTransactionWrappers: function() { + getTransactionWrappers: function () { return TRANSACTION_WRAPPERS; }, /** * @return {object} The queue to collect `onDOMReady` callbacks with. */ - getReactMountReady: function() { + getReactMountReady: function () { return this.reactMountReady; }, - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - /** * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. + * instance to be reused. */ - destructor: function() { + destructor: function () { CallbackQueue.release(this.reactMountReady); this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; } }; - assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin); PooledClass.addPoolingTo(ReactReconcileTransaction); module.exports = ReactReconcileTransaction; - -},{"./CallbackQueue":47,"./Object.assign":69,"./PooledClass":70,"./ReactBrowserEventEmitter":73,"./ReactInputSelection":111,"./ReactPutListenerQueue":127,"./Transaction":157}],129:[function(require,module,exports){ -(function (process){ +},{"./CallbackQueue":64,"./Object.assign":82,"./PooledClass":83,"./ReactBrowserEventEmitter":86,"./ReactDOMFeatureFlags":102,"./ReactInputSelection":124,"./Transaction":172}],142:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -18124,8 +18755,7 @@ module.exports = ReactReconcileTransaction; 'use strict'; -var ReactRef = require("./ReactRef"); -var ReactElementValidator = require("./ReactElementValidator"); +var ReactRef = require('./ReactRef'); /** * Helper to call ReactRef.attachRefs with this composite component, split out @@ -18147,14 +18777,11 @@ var ReactReconciler = { * @final * @internal */ - mountComponent: function(internalInstance, rootID, transaction, context) { + mountComponent: function (internalInstance, rootID, transaction, context) { var markup = internalInstance.mountComponent(rootID, transaction, context); - if ("production" !== process.env.NODE_ENV) { - ReactElementValidator.checkAndWarnForMutatedProps( - internalInstance._currentElement - ); + if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { + transaction.getReactMountReady().enqueue(attachRefs, internalInstance); } - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); return markup; }, @@ -18164,7 +18791,7 @@ var ReactReconciler = { * @final * @internal */ - unmountComponent: function(internalInstance) { + unmountComponent: function (internalInstance) { ReactRef.detachRefs(internalInstance, internalInstance._currentElement); internalInstance.unmountComponent(); }, @@ -18178,12 +18805,10 @@ var ReactReconciler = { * @param {object} context * @internal */ - receiveComponent: function( - internalInstance, nextElement, transaction, context - ) { + receiveComponent: function (internalInstance, nextElement, transaction, context) { var prevElement = internalInstance._currentElement; - if (nextElement === prevElement && nextElement._owner != null) { + if (nextElement === prevElement && context === internalInstance._context) { // 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 @@ -18191,17 +18816,13 @@ var ReactReconciler = { // the element. We explicitly check for the existence of an owner since // it's possible for an element created outside a composite to be // deeply mutated and reused. - return; - } - if ("production" !== process.env.NODE_ENV) { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); + // TODO: Bailing out early is just a perf optimization right? + // TODO: Removing the return statement should affect correctness? + return; } - var refsChanged = ReactRef.shouldUpdateRefs( - prevElement, - nextElement - ); + var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); if (refsChanged) { ReactRef.detachRefs(internalInstance, prevElement); @@ -18209,7 +18830,7 @@ var ReactReconciler = { internalInstance.receiveComponent(nextElement, transaction, context); - if (refsChanged) { + if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) { transaction.getReactMountReady().enqueue(attachRefs, internalInstance); } }, @@ -18221,20 +18842,14 @@ var ReactReconciler = { * @param {ReactReconcileTransaction} transaction * @internal */ - performUpdateIfNecessary: function( - internalInstance, - transaction - ) { + performUpdateIfNecessary: function (internalInstance, transaction) { internalInstance.performUpdateIfNecessary(transaction); } }; module.exports = ReactReconciler; - -}).call(this,require('_process')) - -},{"./ReactElementValidator":104,"./ReactRef":130,"_process":1}],130:[function(require,module,exports){ +},{"./ReactRef":143}],143:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -18248,7 +18863,7 @@ module.exports = ReactReconciler; 'use strict'; -var ReactOwner = require("./ReactOwner"); +var ReactOwner = require('./ReactOwner'); var ReactRef = {}; @@ -18270,14 +18885,17 @@ function detachRef(ref, component, owner) { } } -ReactRef.attachRefs = function(instance, element) { +ReactRef.attachRefs = function (instance, element) { + if (element === null || element === false) { + return; + } var ref = element.ref; if (ref != null) { attachRef(ref, instance, element._owner); } }; -ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { +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 @@ -18290,13 +18908,19 @@ ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { // is made. It probably belongs where the key checking and // instantiateReactComponent is done. - return ( - nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref + var prevEmpty = prevElement === null || prevElement === false; + var nextEmpty = nextElement === null || nextElement === false; + + return( + // This has a few false positives w/r/t empty components. + prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref ); }; -ReactRef.detachRefs = function(instance, element) { +ReactRef.detachRefs = function (instance, element) { + if (element === null || element === false) { + return; + } var ref = element.ref; if (ref != null) { detachRef(ref, instance, element._owner); @@ -18304,8 +18928,7 @@ ReactRef.detachRefs = function(instance, element) { }; module.exports = ReactRef; - -},{"./ReactOwner":121}],131:[function(require,module,exports){ +},{"./ReactOwner":135}],144:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -18324,7 +18947,7 @@ var ReactRootIndexInjection = { /** * @param {function} _createReactRootIndex */ - injectCreateReactRootIndex: function(_createReactRootIndex) { + injectCreateReactRootIndex: function (_createReactRootIndex) { ReactRootIndex.createReactRootIndex = _createReactRootIndex; } }; @@ -18335,8 +18958,31 @@ var ReactRootIndex = { }; module.exports = ReactRootIndex; +},{}],145:[function(require,module,exports){ +/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactServerBatchingStrategy + * @typechecks + */ + +'use strict'; + +var ReactServerBatchingStrategy = { + isBatchingUpdates: false, + batchedUpdates: function (callback) { + // Don't do anything here. During the server rendering we don't want to + // schedule any updates. We will simply ignore them. + } +}; -},{}],132:[function(require,module,exports){ +module.exports = ReactServerBatchingStrategy; +},{}],146:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -18351,39 +18997,42 @@ module.exports = ReactRootIndex; */ 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactMarkupChecksum = require("./ReactMarkupChecksum"); -var ReactServerRenderingTransaction = - require("./ReactServerRenderingTransaction"); +var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy'); +var ReactElement = require('./ReactElement'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactMarkupChecksum = require('./ReactMarkupChecksum'); +var ReactServerBatchingStrategy = require('./ReactServerBatchingStrategy'); +var ReactServerRenderingTransaction = require('./ReactServerRenderingTransaction'); +var ReactUpdates = require('./ReactUpdates'); -var emptyObject = require("./emptyObject"); -var instantiateReactComponent = require("./instantiateReactComponent"); -var invariant = require("./invariant"); +var emptyObject = require('fbjs/lib/emptyObject'); +var instantiateReactComponent = require('./instantiateReactComponent'); +var invariant = require('fbjs/lib/invariant'); /** * @param {ReactElement} element * @return {string} the HTML markup */ function renderToString(element) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactElement.isValidElement(element), - 'renderToString(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); + !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToString(): You must pass a valid ReactElement.') : invariant(false) : undefined; var transaction; try { + ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy); + var id = ReactInstanceHandles.createReactRootID(); transaction = ReactServerRenderingTransaction.getPooled(false); - return transaction.perform(function() { + return transaction.perform(function () { var componentInstance = instantiateReactComponent(element, null); - var markup = - componentInstance.mountComponent(id, transaction, emptyObject); + var markup = componentInstance.mountComponent(id, transaction, emptyObject); return ReactMarkupChecksum.addChecksumToMarkup(markup); }, null); } finally { ReactServerRenderingTransaction.release(transaction); + // Revert to the DOM batching strategy since these two renderers + // currently share these stateful modules. + ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy); } } @@ -18393,22 +19042,24 @@ function renderToString(element) { * (for generating static pages) */ function renderToStaticMarkup(element) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactElement.isValidElement(element), - 'renderToStaticMarkup(): You must pass a valid ReactElement.' - ) : invariant(ReactElement.isValidElement(element))); + !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToStaticMarkup(): You must pass a valid ReactElement.') : invariant(false) : undefined; var transaction; try { + ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy); + var id = ReactInstanceHandles.createReactRootID(); transaction = ReactServerRenderingTransaction.getPooled(true); - return transaction.perform(function() { + return transaction.perform(function () { var componentInstance = instantiateReactComponent(element, null); return componentInstance.mountComponent(id, transaction, emptyObject); }, null); } finally { ReactServerRenderingTransaction.release(transaction); + // Revert to the DOM batching strategy since these two renderers + // currently share these stateful modules. + ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy); } } @@ -18416,10 +19067,9 @@ module.exports = { renderToString: renderToString, renderToStaticMarkup: renderToStaticMarkup }; - }).call(this,require('_process')) -},{"./ReactElement":103,"./ReactInstanceHandles":112,"./ReactMarkupChecksum":116,"./ReactServerRenderingTransaction":133,"./emptyObject":171,"./instantiateReactComponent":190,"./invariant":191,"_process":1}],133:[function(require,module,exports){ +},{"./ReactDefaultBatchingStrategy":111,"./ReactElement":115,"./ReactInstanceHandles":125,"./ReactMarkupChecksum":129,"./ReactServerBatchingStrategy":145,"./ReactServerRenderingTransaction":147,"./ReactUpdates":154,"./instantiateReactComponent":191,"_process":1,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220}],147:[function(require,module,exports){ /** * Copyright 2014-2015, Facebook, Inc. * All rights reserved. @@ -18434,13 +19084,12 @@ module.exports = { 'use strict'; -var PooledClass = require("./PooledClass"); -var CallbackQueue = require("./CallbackQueue"); -var ReactPutListenerQueue = require("./ReactPutListenerQueue"); -var Transaction = require("./Transaction"); +var PooledClass = require('./PooledClass'); +var CallbackQueue = require('./CallbackQueue'); +var Transaction = require('./Transaction'); -var assign = require("./Object.assign"); -var emptyFunction = require("./emptyFunction"); +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); /** * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks @@ -18450,30 +19099,19 @@ var ON_DOM_READY_QUEUEING = { /** * Initializes the internal `onDOMReady` queue. */ - initialize: function() { + initialize: function () { this.reactMountReady.reset(); }, close: emptyFunction }; -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, - - close: emptyFunction -}; - /** * Executed within the scope of the `Transaction` instance. Consider these as * being member methods, but with an implied ordering while being isolated from * each other. */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - ON_DOM_READY_QUEUEING -]; +var TRANSACTION_WRAPPERS = [ON_DOM_READY_QUEUEING]; /** * @class ReactServerRenderingTransaction @@ -18483,7 +19121,7 @@ function ReactServerRenderingTransaction(renderToStaticMarkup) { this.reinitializeTransaction(); this.renderToStaticMarkup = renderToStaticMarkup; this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); + this.useCreateElement = false; } var Mixin = { @@ -18491,48 +19129,35 @@ var Mixin = { * @see Transaction * @abstract * @final - * @return {array} Empty list of operation wrap proceedures. + * @return {array} Empty list of operation wrap procedures. */ - getTransactionWrappers: function() { + getTransactionWrappers: function () { return TRANSACTION_WRAPPERS; }, /** * @return {object} The queue to collect `onDOMReady` callbacks with. */ - getReactMountReady: function() { + getReactMountReady: function () { return this.reactMountReady; }, - getPutListenerQueue: function() { - return this.putListenerQueue; - }, - /** * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. + * instance to be reused. */ - destructor: function() { + destructor: function () { CallbackQueue.release(this.reactMountReady); this.reactMountReady = null; - - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; } }; - -assign( - ReactServerRenderingTransaction.prototype, - Transaction.Mixin, - Mixin -); +assign(ReactServerRenderingTransaction.prototype, Transaction.Mixin, Mixin); PooledClass.addPoolingTo(ReactServerRenderingTransaction); module.exports = ReactServerRenderingTransaction; - -},{"./CallbackQueue":47,"./Object.assign":69,"./PooledClass":70,"./ReactPutListenerQueue":127,"./Transaction":157,"./emptyFunction":170}],134:[function(require,module,exports){ +},{"./CallbackQueue":64,"./Object.assign":82,"./PooledClass":83,"./Transaction":172,"fbjs/lib/emptyFunction":212}],148:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -18557,8 +19182,8 @@ var ReactStateSetters = { * @return {function} callback that when invoked uses funcReturningState to * determined the object literal to setState. */ - createStateSetter: function(component, funcReturningState) { - return function(a, b, c, d, e, f) { + createStateSetter: function (component, funcReturningState) { + return function (a, b, c, d, e, f) { var partialState = funcReturningState.call(component, a, b, c, d, e, f); if (partialState) { component.setState(partialState); @@ -18577,7 +19202,7 @@ var ReactStateSetters = { * @return {function} callback of 1 argument which calls setState() with * the provided keyName and callback argument. */ - createStateKeySetter: function(component, key) { + createStateKeySetter: function (component, key) { // Memoize the setters. var cache = component.__keySetters || (component.__keySetters = {}); return cache[key] || (cache[key] = createStateKeySetter(component, key)); @@ -18612,7 +19237,7 @@ ReactStateSetters.Mixin = { * @return {function} callback that when invoked uses funcReturningState to * determined the object literal to setState. */ - createStateSetter: function(funcReturningState) { + createStateSetter: function (funcReturningState) { return ReactStateSetters.createStateSetter(this, funcReturningState); }, @@ -18631,14 +19256,14 @@ ReactStateSetters.Mixin = { * @return {function} callback of 1 argument which calls setState() with * the provided keyName and callback argument. */ - createStateKeySetter: function(key) { + createStateKeySetter: function (key) { return ReactStateSetters.createStateKeySetter(this, key); } }; module.exports = ReactStateSetters; - -},{}],135:[function(require,module,exports){ +},{}],149:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -18652,22 +19277,24 @@ module.exports = ReactStateSetters; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var React = require("./React"); -var ReactElement = require("./ReactElement"); -var ReactEmptyComponent = require("./ReactEmptyComponent"); -var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter"); -var ReactCompositeComponent = require("./ReactCompositeComponent"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); -var ReactInstanceMap = require("./ReactInstanceMap"); -var ReactMount = require("./ReactMount"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); - -var assign = require("./Object.assign"); -var emptyObject = require("./emptyObject"); +var EventConstants = require('./EventConstants'); +var EventPluginHub = require('./EventPluginHub'); +var EventPropagators = require('./EventPropagators'); +var React = require('./React'); +var ReactDOM = require('./ReactDOM'); +var ReactElement = require('./ReactElement'); +var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); +var ReactCompositeComponent = require('./ReactCompositeComponent'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactInstanceMap = require('./ReactInstanceMap'); +var ReactMount = require('./ReactMount'); +var ReactUpdates = require('./ReactUpdates'); +var SyntheticEvent = require('./SyntheticEvent'); + +var assign = require('./Object.assign'); +var emptyObject = require('fbjs/lib/emptyObject'); +var findDOMNode = require('./findDOMNode'); +var invariant = require('fbjs/lib/invariant'); var topLevelTypes = EventConstants.topLevelTypes; @@ -18677,74 +19304,97 @@ function Event(suffix) {} * @class ReactTestUtils */ +function findAllInRenderedTreeInternal(inst, test) { + if (!inst || !inst.getPublicInstance) { + return []; + } + var publicInst = inst.getPublicInstance(); + var ret = test(publicInst) ? [publicInst] : []; + var currentElement = inst._currentElement; + if (ReactTestUtils.isDOMComponent(publicInst)) { + var renderedChildren = inst._renderedChildren; + var key; + for (key in renderedChildren) { + if (!renderedChildren.hasOwnProperty(key)) { + continue; + } + ret = ret.concat(findAllInRenderedTreeInternal(renderedChildren[key], test)); + } + } else if (ReactElement.isValidElement(currentElement) && typeof currentElement.type === 'function') { + ret = ret.concat(findAllInRenderedTreeInternal(inst._renderedComponent, test)); + } + return ret; +} + /** * Todo: Support the entire DOM.scry query syntax. For now, these simple * utilities will suffice for testing purposes. * @lends ReactTestUtils */ var ReactTestUtils = { - renderIntoDocument: function(instance) { + renderIntoDocument: function (instance) { var div = document.createElement('div'); // None of our tests actually require attaching the container to the // DOM, and doing so creates a mess that we rely on test isolation to // clean up, so we're going to stop honoring the name of this method // (and probably rename it eventually) if no problems arise. // document.documentElement.appendChild(div); - return React.render(instance, div); + return ReactDOM.render(instance, div); }, - isElement: function(element) { + isElement: function (element) { return ReactElement.isValidElement(element); }, - isElementOfType: function(inst, convenienceConstructor) { - return ( - ReactElement.isValidElement(inst) && - inst.type === convenienceConstructor - ); + isElementOfType: function (inst, convenienceConstructor) { + return ReactElement.isValidElement(inst) && inst.type === convenienceConstructor; }, - isDOMComponent: function(inst) { - // TODO: Fix this heuristic. It's just here because composites can currently - // pretend to be DOM components. - return !!(inst && inst.tagName && inst.getDOMNode); + isDOMComponent: function (inst) { + return !!(inst && inst.nodeType === 1 && inst.tagName); }, - isDOMComponentElement: function(inst) { - return !!(inst && - ReactElement.isValidElement(inst) && - !!inst.tagName); + isDOMComponentElement: function (inst) { + return !!(inst && ReactElement.isValidElement(inst) && !!inst.tagName); }, - isCompositeComponent: function(inst) { - return typeof inst.render === 'function' && - typeof inst.setState === 'function'; + isCompositeComponent: function (inst) { + if (ReactTestUtils.isDOMComponent(inst)) { + // Accessing inst.setState warns; just return false as that'll be what + // this returns when we have DOM nodes as refs directly + return false; + } + return inst != null && typeof inst.render === 'function' && typeof inst.setState === 'function'; }, - isCompositeComponentWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponent(inst) && - (inst.constructor === type)); + isCompositeComponentWithType: function (inst, type) { + if (!ReactTestUtils.isCompositeComponent(inst)) { + return false; + } + var internalInstance = ReactInstanceMap.get(inst); + var constructor = internalInstance._currentElement.type; + + return constructor === type; }, - isCompositeComponentElement: function(inst) { + isCompositeComponentElement: function (inst) { if (!ReactElement.isValidElement(inst)) { return false; } // We check the prototype of the type that will get mounted, not the // instance itself. This is a future proof way of duck typing. var prototype = inst.type.prototype; - return ( - typeof prototype.render === 'function' && - typeof prototype.setState === 'function' - ); + return typeof prototype.render === 'function' && typeof prototype.setState === 'function'; }, - isCompositeComponentElementWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponentElement(inst) && - (inst.constructor === type)); + isCompositeComponentElementWithType: function (inst, type) { + var internalInstance = ReactInstanceMap.get(inst); + var constructor = internalInstance._currentElement.type; + + return !!(ReactTestUtils.isCompositeComponentElement(inst) && constructor === type); }, - getRenderedChildOfCompositeComponent: function(inst) { + getRenderedChildOfCompositeComponent: function (inst) { if (!ReactTestUtils.isCompositeComponent(inst)) { return null; } @@ -18752,53 +19402,36 @@ var ReactTestUtils = { return internalInstance._renderedComponent.getPublicInstance(); }, - findAllInRenderedTree: function(inst, test) { + findAllInRenderedTree: function (inst, test) { if (!inst) { return []; } - var ret = test(inst) ? [inst] : []; - if (ReactTestUtils.isDOMComponent(inst)) { - var internalInstance = ReactInstanceMap.get(inst); - var renderedChildren = internalInstance - ._renderedComponent - ._renderedChildren; - var key; - for (key in renderedChildren) { - if (!renderedChildren.hasOwnProperty(key)) { - continue; - } - if (!renderedChildren[key].getPublicInstance) { - continue; - } - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - renderedChildren[key].getPublicInstance(), - test - ) - ); - } - } else if (ReactTestUtils.isCompositeComponent(inst)) { - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - ReactTestUtils.getRenderedChildOfCompositeComponent(inst), - test - ) - ); - } - return ret; + !ReactTestUtils.isCompositeComponent(inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findAllInRenderedTree(...): instance must be a composite component') : invariant(false) : undefined; + return findAllInRenderedTreeInternal(ReactInstanceMap.get(inst), test); }, /** * Finds all instance of components in the rendered tree that are DOM * components with the class name matching `className`. - * @return an array of all the matches. - */ - scryRenderedDOMComponentsWithClass: function(root, className) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - var instClassName = inst.props.className; - return ReactTestUtils.isDOMComponent(inst) && ( - (instClassName && (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1) - ); + * @return {array} an array of all the matches. + */ + scryRenderedDOMComponentsWithClass: function (root, classNames) { + if (!Array.isArray(classNames)) { + classNames = classNames.split(/\s+/); + } + return ReactTestUtils.findAllInRenderedTree(root, function (inst) { + if (ReactTestUtils.isDOMComponent(inst)) { + var className = inst.className; + if (typeof className !== 'string') { + // SVG, probably. + className = inst.getAttribute('class') || ''; + } + var classList = className.split(/\s+/); + return classNames.every(function (name) { + return classList.indexOf(name) !== -1; + }); + } + return false; }); }, @@ -18808,27 +19441,22 @@ var ReactTestUtils = { * number of matches besides one. * @return {!ReactDOMComponent} The one match. */ - findRenderedDOMComponentWithClass: function(root, className) { - var all = - ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); + findRenderedDOMComponentWithClass: function (root, className) { + var all = ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); if (all.length !== 1) { - throw new Error('Did not find exactly one match ' + - '(found: ' + all.length + ') for class:' + className - ); + throw new Error('Did not find exactly one match ' + '(found: ' + all.length + ') for class:' + className); } return all[0]; }, - /** * Finds all instance of components in the rendered tree that are DOM * components with the tag name matching `tagName`. - * @return an array of all the matches. + * @return {array} an array of all the matches. */ - scryRenderedDOMComponentsWithTag: function(root, tagName) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isDOMComponent(inst) && - inst.tagName === tagName.toUpperCase(); + scryRenderedDOMComponentsWithTag: function (root, tagName) { + return ReactTestUtils.findAllInRenderedTree(root, function (inst) { + return ReactTestUtils.isDOMComponent(inst) && inst.tagName.toUpperCase() === tagName.toUpperCase(); }); }, @@ -18838,7 +19466,7 @@ var ReactTestUtils = { * number of matches besides one. * @return {!ReactDOMComponent} The one match. */ - findRenderedDOMComponentWithTag: function(root, tagName) { + findRenderedDOMComponentWithTag: function (root, tagName) { var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); if (all.length !== 1) { throw new Error('Did not find exactly one match for tag:' + tagName); @@ -18846,17 +19474,13 @@ var ReactTestUtils = { return all[0]; }, - /** * Finds all instances of components with type equal to `componentType`. - * @return an array of all the matches. + * @return {array} an array of all the matches. */ - scryRenderedComponentsWithType: function(root, componentType) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isCompositeComponentWithType( - inst, - componentType - ); + scryRenderedComponentsWithType: function (root, componentType) { + return ReactTestUtils.findAllInRenderedTree(root, function (inst) { + return ReactTestUtils.isCompositeComponentWithType(inst, componentType); }); }, @@ -18866,15 +19490,10 @@ var ReactTestUtils = { * number of matches besides one. * @return {!ReactComponent} The one match. */ - findRenderedComponentWithType: function(root, componentType) { - var all = ReactTestUtils.scryRenderedComponentsWithType( - root, - componentType - ); + findRenderedComponentWithType: function (root, componentType) { + var all = ReactTestUtils.scryRenderedComponentsWithType(root, componentType); if (all.length !== 1) { - throw new Error( - 'Did not find exactly one match for componentType:' + componentType - ); + throw new Error('Did not find exactly one match for componentType:' + componentType + ' (found ' + all.length + ')'); } return all[0]; }, @@ -18892,62 +19511,46 @@ var ReactTestUtils = { * module.mockTagName if provided) * @return {object} the ReactTestUtils object (for chaining) */ - mockComponent: function(module, mockTagName) { - mockTagName = mockTagName || module.mockTagName || "div"; + mockComponent: function (module, mockTagName) { + mockTagName = mockTagName || module.mockTagName || 'div'; - module.prototype.render.mockImplementation(function() { - return React.createElement( - mockTagName, - null, - this.props.children - ); + module.prototype.render.mockImplementation(function () { + return React.createElement(mockTagName, null, this.props.children); }); return this; }, /** - * Simulates a top level event being dispatched from a raw event that occured + * Simulates a top level event being dispatched from a raw event that occurred * on an `Element` node. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` + * @param {Object} topLevelType A type from `EventConstants.topLevelTypes` * @param {!Element} node The dom to simulate an event occurring on. * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. */ - simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { + simulateNativeEventOnNode: function (topLevelType, node, fakeNativeEvent) { fakeNativeEvent.target = node; - ReactBrowserEventEmitter.ReactEventListener.dispatchEvent( - topLevelType, - fakeNativeEvent - ); + ReactBrowserEventEmitter.ReactEventListener.dispatchEvent(topLevelType, fakeNativeEvent); }, /** - * Simulates a top level event being dispatched from a raw event that occured + * Simulates a top level event being dispatched from a raw event that occurred * on the `ReactDOMComponent` `comp`. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. - * @param comp {!ReactDOMComponent} + * @param {Object} topLevelType A type from `EventConstants.topLevelTypes`. + * @param {!ReactDOMComponent} comp * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. */ - simulateNativeEventOnDOMComponent: function( - topLevelType, - comp, - fakeNativeEvent) { - ReactTestUtils.simulateNativeEventOnNode( - topLevelType, - comp.getDOMNode(), - fakeNativeEvent - ); + simulateNativeEventOnDOMComponent: function (topLevelType, comp, fakeNativeEvent) { + ReactTestUtils.simulateNativeEventOnNode(topLevelType, findDOMNode(comp), fakeNativeEvent); }, - nativeTouchData: function(x, y) { + nativeTouchData: function (x, y) { return { - touches: [ - {pageX: x, pageY: y} - ] + touches: [{ pageX: x, pageY: y }] }; }, - createRenderer: function() { + createRenderer: function () { return new ReactShallowRenderer(); }, @@ -18958,73 +19561,70 @@ var ReactTestUtils = { /** * @class ReactShallowRenderer */ -var ReactShallowRenderer = function() { +var ReactShallowRenderer = function () { this._instance = null; }; -ReactShallowRenderer.prototype.getRenderOutput = function() { - return ( - (this._instance && this._instance._renderedComponent && - this._instance._renderedComponent._renderedOutput) - || null - ); +ReactShallowRenderer.prototype.getRenderOutput = function () { + return this._instance && this._instance._renderedComponent && this._instance._renderedComponent._renderedOutput || null; }; -var NoopInternalComponent = function(element) { +var NoopInternalComponent = function (element) { this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; + this._currentElement = element; }; NoopInternalComponent.prototype = { - mountComponent: function() { - }, + mountComponent: function () {}, - receiveComponent: function(element) { + receiveComponent: function (element) { this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; + this._currentElement = element; }, - unmountComponent: function() { - } + unmountComponent: function () {}, + getPublicInstance: function () { + return null; + } }; -var ShallowComponentWrapper = function() { }; -assign( - ShallowComponentWrapper.prototype, - ReactCompositeComponent.Mixin, { - _instantiateReactComponent: function(element) { - return new NoopInternalComponent(element); - }, - _replaceNodeWithMarkupByID: function() {}, - _renderValidatedComponent: - ReactCompositeComponent.Mixin. - _renderValidatedComponentWithoutOwnerOrContext - } -); +var ShallowComponentWrapper = function () {}; +assign(ShallowComponentWrapper.prototype, ReactCompositeComponent.Mixin, { + _instantiateReactComponent: function (element) { + return new NoopInternalComponent(element); + }, + _replaceNodeWithMarkupByID: function () {}, + _renderValidatedComponent: ReactCompositeComponent.Mixin._renderValidatedComponentWithoutOwnerOrContext +}); + +ReactShallowRenderer.prototype.render = function (element, context) { + !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : invariant(false) : undefined; + !(typeof element.type !== 'string') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Shallow rendering works only with custom ' + 'components, not primitives (%s). Instead of calling `.render(el)` and ' + 'inspecting the rendered output, look at `el.props` directly instead.', element.type) : invariant(false) : undefined; -ReactShallowRenderer.prototype.render = function(element, context) { if (!context) { context = emptyObject; } - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - this._render(element, transaction, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); + ReactUpdates.batchedUpdates(_batchedRender, this, element, context); }; -ReactShallowRenderer.prototype.unmount = function() { +function _batchedRender(renderer, element, context) { + var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(false); + renderer._render(element, transaction, context); + ReactUpdates.ReactReconcileTransaction.release(transaction); +} + +ReactShallowRenderer.prototype.unmount = function () { if (this._instance) { this._instance.unmountComponent(); } }; -ReactShallowRenderer.prototype._render = function(element, transaction, context) { - if (!this._instance) { +ReactShallowRenderer.prototype._render = function (element, transaction, context) { + if (this._instance) { + this._instance.receiveComponent(element, transaction, context); + } else { var rootID = ReactInstanceHandles.createReactRootID(); var instance = new ShallowComponentWrapper(element.type); instance.construct(element); @@ -19032,8 +19632,6 @@ ReactShallowRenderer.prototype._render = function(element, transaction, context) instance.mountComponent(rootID, transaction, context); this._instance = instance; - } else { - this._instance.receiveComponent(element, transaction, context); } }; @@ -19046,29 +19644,32 @@ ReactShallowRenderer.prototype._render = function(element, transaction, context) * - ... (All keys from event plugin `eventTypes` objects) */ function makeSimulator(eventType) { - return function(domComponentOrNode, eventData) { + return function (domComponentOrNode, eventData) { var node; if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - node = domComponentOrNode.getDOMNode(); + node = findDOMNode(domComponentOrNode); } else if (domComponentOrNode.tagName) { node = domComponentOrNode; } + var dispatchConfig = ReactBrowserEventEmitter.eventNameDispatchConfigs[eventType]; + var fakeNativeEvent = new Event(); fakeNativeEvent.target = node; // We don't use SyntheticEvent.getPooled in order to not have to worry about // properly destroying any properties assigned from `eventData` upon release - var event = new SyntheticEvent( - ReactBrowserEventEmitter.eventNameDispatchConfigs[eventType], - ReactMount.getID(node), - fakeNativeEvent - ); + var event = new SyntheticEvent(dispatchConfig, ReactMount.getID(node), fakeNativeEvent, node); assign(event, eventData); - EventPropagators.accumulateTwoPhaseDispatches(event); - ReactUpdates.batchedUpdates(function() { + if (dispatchConfig.phasedRegistrationNames) { + EventPropagators.accumulateTwoPhaseDispatches(event); + } else { + EventPropagators.accumulateDirectDispatches(event); + } + + ReactUpdates.batchedUpdates(function () { EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); + EventPluginHub.processEventQueue(true); }); }; } @@ -19079,7 +19680,7 @@ function buildSimulators() { var eventType; for (eventType in ReactBrowserEventEmitter.eventNameDispatchConfigs) { /** - * @param {!Element || ReactDOMComponent} domComponentOrNode + * @param {!Element|ReactDOMComponent} domComponentOrNode * @param {?object} eventData Fake event data to use in SyntheticEvent. */ ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); @@ -19088,12 +19689,12 @@ function buildSimulators() { // Rebuild ReactTestUtils.Simulate whenever event plugins are injected var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; -EventPluginHub.injection.injectEventPluginOrder = function() { +EventPluginHub.injection.injectEventPluginOrder = function () { oldInjectEventPluginOrder.apply(this, arguments); buildSimulators(); }; var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; -EventPluginHub.injection.injectEventPluginsByName = function() { +EventPluginHub.injection.injectEventPluginsByName = function () { oldInjectEventPlugins.apply(this, arguments); buildSimulators(); }; @@ -19117,42 +19718,32 @@ buildSimulators(); */ function makeNativeSimulator(eventType) { - return function(domComponentOrNode, nativeEventData) { + return function (domComponentOrNode, nativeEventData) { var fakeNativeEvent = new Event(eventType); assign(fakeNativeEvent, nativeEventData); if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - ReactTestUtils.simulateNativeEventOnDOMComponent( - eventType, - domComponentOrNode, - fakeNativeEvent - ); - } else if (!!domComponentOrNode.tagName) { + ReactTestUtils.simulateNativeEventOnDOMComponent(eventType, domComponentOrNode, fakeNativeEvent); + } else if (domComponentOrNode.tagName) { // Will allow on actual dom nodes. - ReactTestUtils.simulateNativeEventOnNode( - eventType, - domComponentOrNode, - fakeNativeEvent - ); + ReactTestUtils.simulateNativeEventOnNode(eventType, domComponentOrNode, fakeNativeEvent); } }; } -var eventType; -for (eventType in topLevelTypes) { +Object.keys(topLevelTypes).forEach(function (eventType) { // Event type is stored as 'topClick' - we transform that to 'click' - var convenienceName = eventType.indexOf('top') === 0 ? - eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; + var convenienceName = eventType.indexOf('top') === 0 ? eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; /** - * @param {!Element || ReactDOMComponent} domComponentOrNode + * @param {!Element|ReactDOMComponent} domComponentOrNode * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. */ - ReactTestUtils.SimulateNative[convenienceName] = - makeNativeSimulator(eventType); -} + ReactTestUtils.SimulateNative[convenienceName] = makeNativeSimulator(eventType); +}); module.exports = ReactTestUtils; +}).call(this,require('_process')) -},{"./EventConstants":56,"./EventPluginHub":58,"./EventPropagators":61,"./Object.assign":69,"./React":71,"./ReactBrowserEventEmitter":73,"./ReactCompositeComponent":83,"./ReactElement":103,"./ReactEmptyComponent":105,"./ReactInstanceHandles":112,"./ReactInstanceMap":113,"./ReactMount":117,"./ReactUpdates":140,"./SyntheticEvent":149,"./emptyObject":171}],136:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPluginHub":74,"./EventPropagators":77,"./Object.assign":82,"./React":84,"./ReactBrowserEventEmitter":86,"./ReactCompositeComponent":96,"./ReactDOM":98,"./ReactElement":115,"./ReactInstanceHandles":125,"./ReactInstanceMap":126,"./ReactMount":130,"./ReactUpdates":154,"./SyntheticEvent":164,"./findDOMNode":181,"_process":1,"fbjs/lib/emptyObject":213,"fbjs/lib/invariant":220}],150:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -19167,24 +19758,21 @@ module.exports = ReactTestUtils; 'use strict'; -var ReactChildren = require("./ReactChildren"); -var ReactFragment = require("./ReactFragment"); +var flattenChildren = require('./flattenChildren'); var ReactTransitionChildMapping = { /** * Given `this.props.children`, return an object mapping key to child. Just - * simple syntactic sugar around ReactChildren.map(). + * simple syntactic sugar around flattenChildren(). * * @param {*} children `this.props.children` * @return {object} Mapping of key to child */ - getChildMapping: function(children) { + getChildMapping: function (children) { if (!children) { return children; } - return ReactFragment.extract(ReactChildren.map(children, function(child) { - return child; - })); + return flattenChildren(children); }, /** @@ -19204,7 +19792,7 @@ var ReactTransitionChildMapping = { * @return {object} a key set that contains all keys in `prev` and all keys * in `next` in a reasonable order. */ - mergeChildMappings: function(prev, next) { + mergeChildMappings: function (prev, next) { prev = prev || {}; next = next || {}; @@ -19238,9 +19826,7 @@ var ReactTransitionChildMapping = { if (nextKeysPending.hasOwnProperty(nextKey)) { for (i = 0; i < nextKeysPending[nextKey].length; i++) { var pendingNextKey = nextKeysPending[nextKey][i]; - childMapping[nextKeysPending[nextKey][i]] = getValueForKey( - pendingNextKey - ); + childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey); } } childMapping[nextKey] = getValueForKey(nextKey); @@ -19256,8 +19842,7 @@ var ReactTransitionChildMapping = { }; module.exports = ReactTransitionChildMapping; - -},{"./ReactChildren":77,"./ReactFragment":109}],137:[function(require,module,exports){ +},{"./flattenChildren":182}],151:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -19271,7 +19856,7 @@ module.exports = ReactTransitionChildMapping; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); /** * EVENT_NAME_MAP is used to determine which event fired when a @@ -19344,31 +19929,30 @@ function removeEventListener(node, eventName, eventListener) { } var ReactTransitionEvents = { - addEndEventListener: function(node, eventListener) { + addEndEventListener: function (node, eventListener) { if (endEvents.length === 0) { // If CSS transitions are not supported, trigger an "end animation" // event immediately. window.setTimeout(eventListener, 0); return; } - endEvents.forEach(function(endEvent) { + endEvents.forEach(function (endEvent) { addEventListener(node, endEvent, eventListener); }); }, - removeEndEventListener: function(node, eventListener) { + removeEndEventListener: function (node, eventListener) { if (endEvents.length === 0) { return; } - endEvents.forEach(function(endEvent) { + endEvents.forEach(function (endEvent) { removeEventListener(node, endEvent, eventListener); }); } }; module.exports = ReactTransitionEvents; - -},{"./ExecutionEnvironment":62}],138:[function(require,module,exports){ +},{"fbjs/lib/ExecutionEnvironment":206}],152:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -19382,12 +19966,11 @@ module.exports = ReactTransitionEvents; 'use strict'; -var React = require("./React"); -var ReactTransitionChildMapping = require("./ReactTransitionChildMapping"); +var React = require('./React'); +var ReactTransitionChildMapping = require('./ReactTransitionChildMapping'); -var assign = require("./Object.assign"); -var cloneWithProps = require("./cloneWithProps"); -var emptyFunction = require("./emptyFunction"); +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); var ReactTransitionGroup = React.createClass({ displayName: 'ReactTransitionGroup', @@ -19397,26 +19980,26 @@ var ReactTransitionGroup = React.createClass({ childFactory: React.PropTypes.func }, - getDefaultProps: function() { + getDefaultProps: function () { return { component: 'span', childFactory: emptyFunction.thatReturnsArgument }; }, - getInitialState: function() { + getInitialState: function () { return { children: ReactTransitionChildMapping.getChildMapping(this.props.children) }; }, - componentWillMount: function() { + componentWillMount: function () { this.currentlyTransitioningKeys = {}; this.keysToEnter = []; this.keysToLeave = []; }, - componentDidMount: function() { + componentDidMount: function () { var initialChildMapping = this.state.children; for (var key in initialChildMapping) { if (initialChildMapping[key]) { @@ -19425,33 +20008,26 @@ var ReactTransitionGroup = React.createClass({ } }, - componentWillReceiveProps: function(nextProps) { - var nextChildMapping = ReactTransitionChildMapping.getChildMapping( - nextProps.children - ); + componentWillReceiveProps: function (nextProps) { + var nextChildMapping = ReactTransitionChildMapping.getChildMapping(nextProps.children); var prevChildMapping = this.state.children; this.setState({ - children: ReactTransitionChildMapping.mergeChildMappings( - prevChildMapping, - nextChildMapping - ) + children: ReactTransitionChildMapping.mergeChildMappings(prevChildMapping, nextChildMapping) }); var key; for (key in nextChildMapping) { var hasPrev = prevChildMapping && prevChildMapping.hasOwnProperty(key); - if (nextChildMapping[key] && !hasPrev && - !this.currentlyTransitioningKeys[key]) { + if (nextChildMapping[key] && !hasPrev && !this.currentlyTransitioningKeys[key]) { this.keysToEnter.push(key); } } for (key in prevChildMapping) { var hasNext = nextChildMapping && nextChildMapping.hasOwnProperty(key); - if (prevChildMapping[key] && !hasNext && - !this.currentlyTransitioningKeys[key]) { + if (prevChildMapping[key] && !hasNext && !this.currentlyTransitioningKeys[key]) { this.keysToLeave.push(key); } } @@ -19459,7 +20035,7 @@ var ReactTransitionGroup = React.createClass({ // If we want to someday check for reordering, we could do it here. }, - componentDidUpdate: function() { + componentDidUpdate: function () { var keysToEnter = this.keysToEnter; this.keysToEnter = []; keysToEnter.forEach(this.performEnter); @@ -19469,21 +20045,19 @@ var ReactTransitionGroup = React.createClass({ keysToLeave.forEach(this.performLeave); }, - performAppear: function(key) { + performAppear: function (key) { this.currentlyTransitioningKeys[key] = true; var component = this.refs[key]; if (component.componentWillAppear) { - component.componentWillAppear( - this._handleDoneAppearing.bind(this, key) - ); + component.componentWillAppear(this._handleDoneAppearing.bind(this, key)); } else { this._handleDoneAppearing(key); } }, - _handleDoneAppearing: function(key) { + _handleDoneAppearing: function (key) { var component = this.refs[key]; if (component.componentDidAppear) { component.componentDidAppear(); @@ -19491,9 +20065,7 @@ var ReactTransitionGroup = React.createClass({ delete this.currentlyTransitioningKeys[key]; - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); + var currentChildMapping = ReactTransitionChildMapping.getChildMapping(this.props.children); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully appeared. Remove it. @@ -19501,21 +20073,19 @@ var ReactTransitionGroup = React.createClass({ } }, - performEnter: function(key) { + performEnter: function (key) { this.currentlyTransitioningKeys[key] = true; var component = this.refs[key]; if (component.componentWillEnter) { - component.componentWillEnter( - this._handleDoneEntering.bind(this, key) - ); + component.componentWillEnter(this._handleDoneEntering.bind(this, key)); } else { this._handleDoneEntering(key); } }, - _handleDoneEntering: function(key) { + _handleDoneEntering: function (key) { var component = this.refs[key]; if (component.componentDidEnter) { component.componentDidEnter(); @@ -19523,9 +20093,7 @@ var ReactTransitionGroup = React.createClass({ delete this.currentlyTransitioningKeys[key]; - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); + var currentChildMapping = ReactTransitionChildMapping.getChildMapping(this.props.children); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully entered. Remove it. @@ -19533,7 +20101,7 @@ var ReactTransitionGroup = React.createClass({ } }, - performLeave: function(key) { + performLeave: function (key) { this.currentlyTransitioningKeys[key] = true; var component = this.refs[key]; @@ -19547,7 +20115,7 @@ var ReactTransitionGroup = React.createClass({ } }, - _handleDoneLeaving: function(key) { + _handleDoneLeaving: function (key) { var component = this.refs[key]; if (component.componentDidLeave) { @@ -19556,21 +20124,21 @@ var ReactTransitionGroup = React.createClass({ delete this.currentlyTransitioningKeys[key]; - var currentChildMapping = ReactTransitionChildMapping.getChildMapping( - this.props.children - ); + var currentChildMapping = ReactTransitionChildMapping.getChildMapping(this.props.children); if (currentChildMapping && currentChildMapping.hasOwnProperty(key)) { // This entered again before it fully left. Add it again. this.performEnter(key); } else { - var newChildren = assign({}, this.state.children); - delete newChildren[key]; - this.setState({children: newChildren}); + this.setState(function (state) { + var newChildren = assign({}, state.children); + delete newChildren[key]; + return { children: newChildren }; + }); } }, - render: function() { + render: function () { // TODO: we could get rid of the need for the wrapper node // by cloning a single child var childrenToRender = []; @@ -19582,23 +20150,15 @@ var ReactTransitionGroup = React.createClass({ // already been removed. In case you need this behavior you can provide // a childFactory function to wrap every child, even the ones that are // leaving. - childrenToRender.push(cloneWithProps( - this.props.childFactory(child), - {ref: key, key: key} - )); + childrenToRender.push(React.cloneElement(this.props.childFactory(child), { ref: key, key: key })); } } - return React.createElement( - this.props.component, - this.props, - childrenToRender - ); + return React.createElement(this.props.component, this.props, childrenToRender); } }); module.exports = ReactTransitionGroup; - -},{"./Object.assign":69,"./React":71,"./ReactTransitionChildMapping":136,"./cloneWithProps":163,"./emptyFunction":170}],139:[function(require,module,exports){ +},{"./Object.assign":82,"./React":84,"./ReactTransitionChildMapping":150,"fbjs/lib/emptyFunction":212}],153:[function(require,module,exports){ (function (process){ /** * Copyright 2015, Facebook, Inc. @@ -19613,55 +20173,33 @@ module.exports = ReactTransitionGroup; 'use strict'; -var ReactLifeCycle = require("./ReactLifeCycle"); -var ReactCurrentOwner = require("./ReactCurrentOwner"); -var ReactElement = require("./ReactElement"); -var ReactInstanceMap = require("./ReactInstanceMap"); -var ReactUpdates = require("./ReactUpdates"); +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"); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/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); - } + ReactUpdates.enqueueUpdate(internalInstance); } function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactCurrentOwner.current == null, - '%s(...): Cannot update during an existing state transition ' + - '(such as within `render`). Render methods should be a pure function ' + - 'of props and state.', - callerName - ) : invariant(ReactCurrentOwner.current == null)); - var internalInstance = ReactInstanceMap.get(publicInstance); if (!internalInstance) { - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { // Only warn when we have a callerName. Otherwise we should be silent. // We're probably calling from enqueueCallback. We don't want to warn // there because we already warned for the corresponding lifecycle method. - ("production" !== process.env.NODE_ENV ? warning( - !callerName, - '%s(...): Can only update a mounted or mounting component. ' + - 'This usually means you called %s() on an unmounted ' + - 'component. This is a no-op.', - callerName, - callerName - ) : null); + process.env.NODE_ENV !== 'production' ? 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. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor.displayName) : undefined; } return null; } - if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { - return null; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(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) : undefined; } return internalInstance; @@ -19674,6 +20212,32 @@ function getInternalInstanceReadyForUpdate(publicInstance, callerName) { var ReactUpdateQueue = { /** + * Checks whether or not this composite component is mounted. + * @param {ReactClass} publicInstance The instance we want to test. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function (publicInstance) { + if (process.env.NODE_ENV !== 'production') { + var owner = ReactCurrentOwner.current; + if (owner !== null) { + process.env.NODE_ENV !== 'production' ? 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') : undefined; + owner._warnedAboutRefsInRender = true; + } + } + var internalInstance = ReactInstanceMap.get(publicInstance); + if (internalInstance) { + // During componentWillMount and render this will still be null but after + // that will always render to something. At least for now. So we can use + // this hack. + return !!internalInstance._renderedComponent; + } else { + return false; + } + }, + + /** * Enqueue a callback that will be executed after all the pending updates * have processed. * @@ -19681,13 +20245,8 @@ var ReactUpdateQueue = { * @param {?function} callback Called after state is updated. * @internal */ - enqueueCallback: function(publicInstance, callback) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); + enqueueCallback: function (publicInstance, callback) { + !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\'t callable.') : invariant(false) : undefined; var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); // Previously we would throw an error if we didn't have an internal @@ -19695,8 +20254,7 @@ var ReactUpdateQueue = { // behavior we have in other enqueue* methods. // We also need to ignore callbacks in componentWillMount. See // enqueueUpdates. - if (!internalInstance || - internalInstance === ReactLifeCycle.currentlyMountingInstance) { + if (!internalInstance) { return null; } @@ -19712,13 +20270,8 @@ var ReactUpdateQueue = { enqueueUpdate(internalInstance); }, - enqueueCallbackInternal: function(internalInstance, callback) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ) : invariant(typeof callback === 'function')); + enqueueCallbackInternal: function (internalInstance, callback) { + !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\'t callable.') : invariant(false) : undefined; if (internalInstance._pendingCallbacks) { internalInstance._pendingCallbacks.push(callback); } else { @@ -19734,17 +20287,14 @@ var ReactUpdateQueue = { * 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 + * This will not invoke `shouldComponentUpdate`, but it will invoke * `componentWillUpdate` and `componentDidUpdate`. * * @param {ReactClass} publicInstance The instance that should rerender. * @internal */ - enqueueForceUpdate: function(publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'forceUpdate' - ); + enqueueForceUpdate: function (publicInstance) { + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate'); if (!internalInstance) { return; @@ -19766,11 +20316,8 @@ var ReactUpdateQueue = { * @param {object} completeState Next state. * @internal */ - enqueueReplaceState: function(publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceState' - ); + enqueueReplaceState: function (publicInstance, completeState) { + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); if (!internalInstance) { return; @@ -19792,19 +20339,14 @@ var ReactUpdateQueue = { * @param {object} partialState Next partial state to be merged with state. * @internal */ - enqueueSetState: function(publicInstance, partialState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setState' - ); + enqueueSetState: function (publicInstance, partialState) { + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); if (!internalInstance) { return; } - var queue = - internalInstance._pendingStateQueue || - (internalInstance._pendingStateQueue = []); + var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); queue.push(partialState); enqueueUpdate(internalInstance); @@ -19817,36 +20359,26 @@ var ReactUpdateQueue = { * @param {object} partialProps Subset of the next props. * @internal */ - enqueueSetProps: function(publicInstance, partialProps) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setProps' - ); - + enqueueSetProps: function (publicInstance, partialProps) { + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setProps'); if (!internalInstance) { return; } + ReactUpdateQueue.enqueueSetPropsInternal(internalInstance, partialProps); + }, - ("production" !== process.env.NODE_ENV ? invariant( - internalInstance._isTopLevel, - 'setProps(...): You called `setProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); + enqueueSetPropsInternal: function (internalInstance, partialProps) { + var topLevelWrapper = internalInstance._topLevelWrapper; + !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setProps(...): You called `setProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined; // Merge with the pending element if it exists, otherwise with existing // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; + var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement; + var element = wrapElement.props; var props = assign({}, element.props, partialProps); - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); + topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props)); - enqueueUpdate(internalInstance); + enqueueUpdate(topLevelWrapper); }, /** @@ -19856,38 +20388,28 @@ var ReactUpdateQueue = { * @param {object} props New props. * @internal */ - enqueueReplaceProps: function(publicInstance, props) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceProps' - ); - + enqueueReplaceProps: function (publicInstance, props) { + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceProps'); if (!internalInstance) { return; } + ReactUpdateQueue.enqueueReplacePropsInternal(internalInstance, props); + }, - ("production" !== process.env.NODE_ENV ? invariant( - internalInstance._isTopLevel, - 'replaceProps(...): You called `replaceProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(internalInstance._isTopLevel)); + enqueueReplacePropsInternal: function (internalInstance, props) { + var topLevelWrapper = internalInstance._topLevelWrapper; + !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'replaceProps(...): You called `replaceProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined; // 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 - ); + var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement; + var element = wrapElement.props; + topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props)); - enqueueUpdate(internalInstance); + enqueueUpdate(topLevelWrapper); }, - enqueueElementInternal: function(internalInstance, newElement) { + enqueueElementInternal: function (internalInstance, newElement) { internalInstance._pendingElement = newElement; enqueueUpdate(internalInstance); } @@ -19895,10 +20417,9 @@ var ReactUpdateQueue = { }; module.exports = ReactUpdateQueue; - }).call(this,require('_process')) -},{"./Object.assign":69,"./ReactCurrentOwner":85,"./ReactElement":103,"./ReactInstanceMap":113,"./ReactLifeCycle":114,"./ReactUpdates":140,"./invariant":191,"./warning":212,"_process":1}],140:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactCurrentOwner":97,"./ReactElement":115,"./ReactInstanceMap":126,"./ReactUpdates":154,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],154:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -19913,16 +20434,14 @@ module.exports = ReactUpdateQueue; '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 CallbackQueue = require('./CallbackQueue'); +var PooledClass = require('./PooledClass'); +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 assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); var dirtyComponents = []; var asapCallbackQueue = CallbackQueue.getPooled(); @@ -19931,18 +20450,14 @@ var asapEnqueued = false; var batchingStrategy = null; function ensureInjected() { - ("production" !== process.env.NODE_ENV ? invariant( - ReactUpdates.ReactReconcileTransaction && batchingStrategy, - 'ReactUpdates: must inject a reconcile transaction class and batching ' + - 'strategy' - ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy)); + !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching ' + 'strategy') : invariant(false) : undefined; } var NESTED_UPDATES = { - initialize: function() { + initialize: function () { this.dirtyComponentsLength = dirtyComponents.length; }, - close: function() { + 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 @@ -19958,10 +20473,10 @@ var NESTED_UPDATES = { }; var UPDATE_QUEUEING = { - initialize: function() { + initialize: function () { this.callbackQueue.reset(); }, - close: function() { + close: function () { this.callbackQueue.notifyAll(); } }; @@ -19972,18 +20487,15 @@ function ReactUpdatesFlushTransaction() { this.reinitializeTransaction(); this.dirtyComponentsLength = null; this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = - ReactUpdates.ReactReconcileTransaction.getPooled(); + this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( /* forceHTML */false); } -assign( - ReactUpdatesFlushTransaction.prototype, - Transaction.Mixin, { - getTransactionWrappers: function() { +assign(ReactUpdatesFlushTransaction.prototype, Transaction.Mixin, { + getTransactionWrappers: function () { return TRANSACTION_WRAPPERS; }, - destructor: function() { + destructor: function () { this.dirtyComponentsLength = null; CallbackQueue.release(this.callbackQueue); this.callbackQueue = null; @@ -19991,25 +20503,18 @@ assign( this.reconcileTransaction = null; }, - perform: function(method, scope, a) { + 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 - ); + return Transaction.Mixin.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); } }); PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); -function batchedUpdates(callback, a, b, c, d) { +function batchedUpdates(callback, a, b, c, d, e) { ensureInjected(); - batchingStrategy.batchedUpdates(callback, a, b, c, d); + batchingStrategy.batchedUpdates(callback, a, b, c, d, e); } /** @@ -20025,13 +20530,7 @@ function mountOrderComparator(c1, c2) { function runBatchedUpdates(transaction) { var len = transaction.dirtyComponentsLength; - ("production" !== process.env.NODE_ENV ? invariant( - len === dirtyComponents.length, - 'Expected flush transaction\'s stored dirty-components length (%s) to ' + - 'match dirty-components array length (%s).', - len, - dirtyComponents.length - ) : invariant(len === dirtyComponents.length)); + !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to ' + 'match dirty-components array length (%s).', len, dirtyComponents.length) : invariant(false) : undefined; // Since reconciling a component higher in the owner hierarchy usually (not // always -- see shouldComponentUpdate()) will reconcile children, reconcile @@ -20050,23 +20549,17 @@ function runBatchedUpdates(transaction) { var callbacks = component._pendingCallbacks; component._pendingCallbacks = null; - ReactReconciler.performUpdateIfNecessary( - component, - transaction.reconcileTransaction - ); + ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction); if (callbacks) { for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue( - callbacks[j], - component.getPublicInstance() - ); + transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); } } } } -var flushBatchedUpdates = function() { +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 @@ -20087,11 +20580,7 @@ var flushBatchedUpdates = function() { } } }; -flushBatchedUpdates = ReactPerf.measure( - 'ReactUpdates', - 'flushBatchedUpdates', - flushBatchedUpdates -); +flushBatchedUpdates = ReactPerf.measure('ReactUpdates', 'flushBatchedUpdates', flushBatchedUpdates); /** * Mark a component as needing a rerender, adding an optional callback to a @@ -20105,13 +20594,6 @@ function enqueueUpdate(component) { // verify that that's the case. (This is called by each top-level update // function, like setProps, setState, forceUpdate, etc.; creation and // destruction of top-level components is guarded in ReactMount.) - ("production" !== process.env.NODE_ENV ? warning( - ReactCurrentOwner.current == null, - 'enqueueUpdate(): Render methods should be a pure function of props ' + - 'and state; triggering nested component updates from render is not ' + - 'allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ) : null); if (!batchingStrategy.isBatchingUpdates) { batchingStrategy.batchedUpdates(enqueueUpdate, component); @@ -20126,37 +20608,21 @@ function enqueueUpdate(component) { * if no updates are currently being performed. */ function asap(callback, context) { - ("production" !== process.env.NODE_ENV ? invariant( - batchingStrategy.isBatchingUpdates, - 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + - 'updates are not being batched.' - ) : invariant(batchingStrategy.isBatchingUpdates)); + !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + 'updates are not being batched.') : invariant(false) : undefined; asapCallbackQueue.enqueue(callback, context); asapEnqueued = true; } var ReactUpdatesInjection = { - injectReconcileTransaction: function(ReconcileTransaction) { - ("production" !== process.env.NODE_ENV ? invariant( - ReconcileTransaction, - 'ReactUpdates: must provide a reconcile transaction class' - ) : invariant(ReconcileTransaction)); + injectReconcileTransaction: function (ReconcileTransaction) { + !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : invariant(false) : undefined; ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; }, - injectBatchingStrategy: function(_batchingStrategy) { - ("production" !== process.env.NODE_ENV ? invariant( - _batchingStrategy, - 'ReactUpdates: must provide a batching strategy' - ) : invariant(_batchingStrategy)); - ("production" !== process.env.NODE_ENV ? invariant( - typeof _batchingStrategy.batchedUpdates === 'function', - 'ReactUpdates: must provide a batchedUpdates() function' - ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); - ("production" !== process.env.NODE_ENV ? invariant( - typeof _batchingStrategy.isBatchingUpdates === 'boolean', - 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' - ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); + injectBatchingStrategy: function (_batchingStrategy) { + !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : invariant(false) : undefined; + !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : invariant(false) : undefined; + !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : invariant(false) : undefined; batchingStrategy = _batchingStrategy; } }; @@ -20178,10 +20644,24 @@ var ReactUpdates = { }; module.exports = ReactUpdates; - }).call(this,require('_process')) -},{"./CallbackQueue":47,"./Object.assign":69,"./PooledClass":70,"./ReactCurrentOwner":85,"./ReactPerf":122,"./ReactReconciler":129,"./Transaction":157,"./invariant":191,"./warning":212,"_process":1}],141:[function(require,module,exports){ +},{"./CallbackQueue":64,"./Object.assign":82,"./PooledClass":83,"./ReactPerf":136,"./ReactReconciler":142,"./Transaction":172,"_process":1,"fbjs/lib/invariant":220}],155:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactVersion + */ + +'use strict'; + +module.exports = '0.14.7'; +},{}],156:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -20203,18 +20683,20 @@ module.exports = ReactUpdates; 'use strict'; -var LinkedStateMixin = require("./LinkedStateMixin"); -var React = require("./React"); -var ReactComponentWithPureRenderMixin = - require("./ReactComponentWithPureRenderMixin"); -var ReactCSSTransitionGroup = require("./ReactCSSTransitionGroup"); -var ReactFragment = require("./ReactFragment"); -var ReactTransitionGroup = require("./ReactTransitionGroup"); -var ReactUpdates = require("./ReactUpdates"); +var LinkedStateMixin = require('./LinkedStateMixin'); +var React = require('./React'); +var ReactComponentWithPureRenderMixin = require('./ReactComponentWithPureRenderMixin'); +var ReactCSSTransitionGroup = require('./ReactCSSTransitionGroup'); +var ReactFragment = require('./ReactFragment'); +var ReactTransitionGroup = require('./ReactTransitionGroup'); +var ReactUpdates = require('./ReactUpdates'); -var cx = require("./cx"); -var cloneWithProps = require("./cloneWithProps"); -var update = require("./update"); +var cloneWithProps = require('./cloneWithProps'); +var shallowCompare = require('./shallowCompare'); +var update = require('./update'); +var warning = require('fbjs/lib/warning'); + +var warnedAboutBatchedUpdates = false; React.addons = { CSSTransitionGroup: ReactCSSTransitionGroup, @@ -20222,23 +20704,28 @@ React.addons = { PureRenderMixin: ReactComponentWithPureRenderMixin, TransitionGroup: ReactTransitionGroup, - batchedUpdates: ReactUpdates.batchedUpdates, - classSet: cx, + batchedUpdates: function () { + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(warnedAboutBatchedUpdates, 'React.addons.batchedUpdates is deprecated. Use ' + 'ReactDOM.unstable_batchedUpdates instead.') : undefined; + warnedAboutBatchedUpdates = true; + } + return ReactUpdates.batchedUpdates.apply(this, arguments); + }, cloneWithProps: cloneWithProps, createFragment: ReactFragment.create, + shallowCompare: shallowCompare, update: update }; -if ("production" !== process.env.NODE_ENV) { - React.addons.Perf = require("./ReactDefaultPerf"); - React.addons.TestUtils = require("./ReactTestUtils"); +if (process.env.NODE_ENV !== 'production') { + React.addons.Perf = require('./ReactDefaultPerf'); + React.addons.TestUtils = require('./ReactTestUtils'); } module.exports = React; - }).call(this,require('_process')) -},{"./LinkedStateMixin":65,"./React":71,"./ReactCSSTransitionGroup":74,"./ReactComponentWithPureRenderMixin":82,"./ReactDefaultPerf":101,"./ReactFragment":109,"./ReactTestUtils":135,"./ReactTransitionGroup":138,"./ReactUpdates":140,"./cloneWithProps":163,"./cx":168,"./update":211,"_process":1}],142:[function(require,module,exports){ +},{"./LinkedStateMixin":80,"./React":84,"./ReactCSSTransitionGroup":87,"./ReactComponentWithPureRenderMixin":95,"./ReactDefaultPerf":113,"./ReactFragment":122,"./ReactTestUtils":149,"./ReactTransitionGroup":152,"./ReactUpdates":154,"./cloneWithProps":177,"./shallowCompare":199,"./update":202,"_process":1,"fbjs/lib/warning":232}],157:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -20250,14 +20737,17 @@ module.exports = React; * @providesModule SVGDOMPropertyConfig */ -/*jslint bitwise: true*/ - 'use strict'; -var DOMProperty = require("./DOMProperty"); +var DOMProperty = require('./DOMProperty'); var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; +var NS = { + xlink: 'http://www.w3.org/1999/xlink', + xml: 'http://www.w3.org/XML/1998/namespace' +}; + var SVGDOMPropertyConfig = { Properties: { clipPath: MUST_USE_ATTRIBUTE, @@ -20301,10 +20791,32 @@ var SVGDOMPropertyConfig = { x1: MUST_USE_ATTRIBUTE, x2: MUST_USE_ATTRIBUTE, x: MUST_USE_ATTRIBUTE, + xlinkActuate: MUST_USE_ATTRIBUTE, + xlinkArcrole: MUST_USE_ATTRIBUTE, + xlinkHref: MUST_USE_ATTRIBUTE, + xlinkRole: MUST_USE_ATTRIBUTE, + xlinkShow: MUST_USE_ATTRIBUTE, + xlinkTitle: MUST_USE_ATTRIBUTE, + xlinkType: MUST_USE_ATTRIBUTE, + xmlBase: MUST_USE_ATTRIBUTE, + xmlLang: MUST_USE_ATTRIBUTE, + xmlSpace: MUST_USE_ATTRIBUTE, y1: MUST_USE_ATTRIBUTE, y2: MUST_USE_ATTRIBUTE, y: MUST_USE_ATTRIBUTE }, + DOMAttributeNamespaces: { + xlinkActuate: NS.xlink, + xlinkArcrole: NS.xlink, + xlinkHref: NS.xlink, + xlinkRole: NS.xlink, + xlinkShow: NS.xlink, + xlinkTitle: NS.xlink, + xlinkType: NS.xlink, + xmlBase: NS.xml, + xmlLang: NS.xml, + xmlSpace: NS.xml + }, DOMAttributeNames: { clipPath: 'clip-path', fillOpacity: 'fill-opacity', @@ -20326,13 +20838,22 @@ var SVGDOMPropertyConfig = { strokeOpacity: 'stroke-opacity', strokeWidth: 'stroke-width', textAnchor: 'text-anchor', - viewBox: 'viewBox' + viewBox: 'viewBox', + xlinkActuate: 'xlink:actuate', + xlinkArcrole: 'xlink:arcrole', + xlinkHref: 'xlink:href', + xlinkRole: 'xlink:role', + xlinkShow: 'xlink:show', + xlinkTitle: 'xlink:title', + xlinkType: 'xlink:type', + xmlBase: 'xml:base', + xmlLang: 'xml:lang', + xmlSpace: 'xml:space' } }; module.exports = SVGDOMPropertyConfig; - -},{"./DOMProperty":51}],143:[function(require,module,exports){ +},{"./DOMProperty":68}],158:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -20346,33 +20867,28 @@ module.exports = SVGDOMPropertyConfig; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ReactInputSelection = require("./ReactInputSelection"); -var SyntheticEvent = require("./SyntheticEvent"); +var EventConstants = require('./EventConstants'); +var EventPropagators = require('./EventPropagators'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var ReactInputSelection = require('./ReactInputSelection'); +var SyntheticEvent = require('./SyntheticEvent'); -var getActiveElement = require("./getActiveElement"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); -var shallowEqual = require("./shallowEqual"); +var getActiveElement = require('fbjs/lib/getActiveElement'); +var isTextInputElement = require('./isTextInputElement'); +var keyOf = require('fbjs/lib/keyOf'); +var shallowEqual = require('fbjs/lib/shallowEqual'); var topLevelTypes = EventConstants.topLevelTypes; +var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; + var eventTypes = { select: { phasedRegistrationNames: { - bubbled: keyOf({onSelect: null}), - captured: keyOf({onSelectCapture: null}) + bubbled: keyOf({ onSelect: null }), + captured: keyOf({ onSelectCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topContextMenu, - topLevelTypes.topFocus, - topLevelTypes.topKeyDown, - topLevelTypes.topMouseDown, - topLevelTypes.topMouseUp, - topLevelTypes.topSelectionChange - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topContextMenu, topLevelTypes.topFocus, topLevelTypes.topKeyDown, topLevelTypes.topMouseDown, topLevelTypes.topMouseUp, topLevelTypes.topSelectionChange] } }; @@ -20381,6 +20897,11 @@ var activeElementID = null; var lastSelection = null; var mouseDown = false; +// Track whether a listener exists for this plugin. If none exist, we do +// not extract events. +var hasListener = false; +var ON_SELECT_KEY = keyOf({ onSelect: null }); + /** * Get an object which is a unique representation of the current selection. * @@ -20388,11 +20909,10 @@ var mouseDown = false; * two identical selections on the same node will return identical objects. * * @param {DOMElement} node - * @param {object} + * @return {object} */ function getSelection(node) { - if ('selectionStart' in node && - ReactInputSelection.hasSelectionCapabilities(node)) { + if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) { return { start: node.selectionStart, end: node.selectionEnd @@ -20422,14 +20942,12 @@ function getSelection(node) { * @param {object} nativeEvent * @return {?SyntheticEvent} */ -function constructSelectEvent(nativeEvent) { +function constructSelectEvent(nativeEvent, nativeEventTarget) { // Ensure we have the right element, and that the user is not dragging a // selection (this matches native `select` event behavior). In HTML5, select // fires only on input and textarea thus if there's no focused element we // won't dispatch. - if (mouseDown || - activeElement == null || - activeElement !== getActiveElement()) { + if (mouseDown || activeElement == null || activeElement !== getActiveElement()) { return null; } @@ -20438,11 +20956,7 @@ function constructSelectEvent(nativeEvent) { if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { lastSelection = currentSelection; - var syntheticEvent = SyntheticEvent.getPooled( - eventTypes.select, - activeElementID, - nativeEvent - ); + var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementID, nativeEvent, nativeEventTarget); syntheticEvent.type = 'select'; syntheticEvent.target = activeElement; @@ -20451,6 +20965,8 @@ function constructSelectEvent(nativeEvent) { return syntheticEvent; } + + return null; } /** @@ -20479,17 +20995,15 @@ var SelectEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + if (!hasListener) { + return null; + } switch (topLevelType) { // Track the input node that has focus. case topLevelTypes.topFocus: - if (isTextInputElement(topLevelTarget) || - topLevelTarget.contentEditable === 'true') { + if (isTextInputElement(topLevelTarget) || topLevelTarget.contentEditable === 'true') { activeElement = topLevelTarget; activeElementID = topLevelTargetID; lastSelection = null; @@ -20509,25 +21023,39 @@ var SelectEventPlugin = { case topLevelTypes.topContextMenu: case topLevelTypes.topMouseUp: mouseDown = false; - return constructSelectEvent(nativeEvent); + return constructSelectEvent(nativeEvent, nativeEventTarget); // Chrome and IE fire non-standard event when selection is changed (and - // sometimes when it hasn't). + // sometimes when it hasn't). IE's event fires out of order with respect + // to key and input events on deletion, so we discard it. + // // Firefox doesn't support selectionchange, so check selection status // after each key entry. The selection changes after keydown and before // keyup, but we check on keydown as well in the case of holding down a // key, when multiple keydown events are fired but only one keyup is. + // This is also our approach for IE handling, for the reason above. case topLevelTypes.topSelectionChange: + if (skipSelectionChangeEvent) { + break; + } + // falls through case topLevelTypes.topKeyDown: case topLevelTypes.topKeyUp: - return constructSelectEvent(nativeEvent); + return constructSelectEvent(nativeEvent, nativeEventTarget); + } + + return null; + }, + + didPutListener: function (id, registrationName, listener) { + if (registrationName === ON_SELECT_KEY) { + hasListener = true; } } }; module.exports = SelectEventPlugin; - -},{"./EventConstants":56,"./EventPropagators":61,"./ReactInputSelection":111,"./SyntheticEvent":149,"./getActiveElement":177,"./isTextInputElement":194,"./keyOf":198,"./shallowEqual":207}],144:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPropagators":77,"./ReactInputSelection":124,"./SyntheticEvent":164,"./isTextInputElement":193,"fbjs/lib/ExecutionEnvironment":206,"fbjs/lib/getActiveElement":215,"fbjs/lib/keyOf":225,"fbjs/lib/shallowEqual":230}],159:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -20551,14 +21079,13 @@ module.exports = SelectEventPlugin; var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53); var ServerReactRootIndex = { - createReactRootIndex: function() { + createReactRootIndex: function () { return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX); } }; module.exports = ServerReactRootIndex; - -},{}],145:[function(require,module,exports){ +},{}],160:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -20573,313 +21100,446 @@ module.exports = ServerReactRootIndex; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginUtils = require("./EventPluginUtils"); -var EventPropagators = require("./EventPropagators"); -var SyntheticClipboardEvent = require("./SyntheticClipboardEvent"); -var SyntheticEvent = require("./SyntheticEvent"); -var SyntheticFocusEvent = require("./SyntheticFocusEvent"); -var SyntheticKeyboardEvent = require("./SyntheticKeyboardEvent"); -var SyntheticMouseEvent = require("./SyntheticMouseEvent"); -var SyntheticDragEvent = require("./SyntheticDragEvent"); -var SyntheticTouchEvent = require("./SyntheticTouchEvent"); -var SyntheticUIEvent = require("./SyntheticUIEvent"); -var SyntheticWheelEvent = require("./SyntheticWheelEvent"); - -var getEventCharCode = require("./getEventCharCode"); - -var invariant = require("./invariant"); -var keyOf = require("./keyOf"); -var warning = require("./warning"); +var EventConstants = require('./EventConstants'); +var EventListener = require('fbjs/lib/EventListener'); +var EventPropagators = require('./EventPropagators'); +var ReactMount = require('./ReactMount'); +var SyntheticClipboardEvent = require('./SyntheticClipboardEvent'); +var SyntheticEvent = require('./SyntheticEvent'); +var SyntheticFocusEvent = require('./SyntheticFocusEvent'); +var SyntheticKeyboardEvent = require('./SyntheticKeyboardEvent'); +var SyntheticMouseEvent = require('./SyntheticMouseEvent'); +var SyntheticDragEvent = require('./SyntheticDragEvent'); +var SyntheticTouchEvent = require('./SyntheticTouchEvent'); +var SyntheticUIEvent = require('./SyntheticUIEvent'); +var SyntheticWheelEvent = require('./SyntheticWheelEvent'); + +var emptyFunction = require('fbjs/lib/emptyFunction'); +var getEventCharCode = require('./getEventCharCode'); +var invariant = require('fbjs/lib/invariant'); +var keyOf = require('fbjs/lib/keyOf'); var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { + abort: { + phasedRegistrationNames: { + bubbled: keyOf({ onAbort: true }), + captured: keyOf({ onAbortCapture: true }) + } + }, blur: { phasedRegistrationNames: { - bubbled: keyOf({onBlur: true}), - captured: keyOf({onBlurCapture: true}) + bubbled: keyOf({ onBlur: true }), + captured: keyOf({ onBlurCapture: true }) + } + }, + canPlay: { + phasedRegistrationNames: { + bubbled: keyOf({ onCanPlay: true }), + captured: keyOf({ onCanPlayCapture: true }) + } + }, + canPlayThrough: { + phasedRegistrationNames: { + bubbled: keyOf({ onCanPlayThrough: true }), + captured: keyOf({ onCanPlayThroughCapture: true }) } }, click: { phasedRegistrationNames: { - bubbled: keyOf({onClick: true}), - captured: keyOf({onClickCapture: true}) + bubbled: keyOf({ onClick: true }), + captured: keyOf({ onClickCapture: true }) } }, contextMenu: { phasedRegistrationNames: { - bubbled: keyOf({onContextMenu: true}), - captured: keyOf({onContextMenuCapture: true}) + bubbled: keyOf({ onContextMenu: true }), + captured: keyOf({ onContextMenuCapture: true }) } }, copy: { phasedRegistrationNames: { - bubbled: keyOf({onCopy: true}), - captured: keyOf({onCopyCapture: true}) + bubbled: keyOf({ onCopy: true }), + captured: keyOf({ onCopyCapture: true }) } }, cut: { phasedRegistrationNames: { - bubbled: keyOf({onCut: true}), - captured: keyOf({onCutCapture: true}) + bubbled: keyOf({ onCut: true }), + captured: keyOf({ onCutCapture: true }) } }, doubleClick: { phasedRegistrationNames: { - bubbled: keyOf({onDoubleClick: true}), - captured: keyOf({onDoubleClickCapture: true}) + bubbled: keyOf({ onDoubleClick: true }), + captured: keyOf({ onDoubleClickCapture: true }) } }, drag: { phasedRegistrationNames: { - bubbled: keyOf({onDrag: true}), - captured: keyOf({onDragCapture: true}) + bubbled: keyOf({ onDrag: true }), + captured: keyOf({ onDragCapture: true }) } }, dragEnd: { phasedRegistrationNames: { - bubbled: keyOf({onDragEnd: true}), - captured: keyOf({onDragEndCapture: true}) + bubbled: keyOf({ onDragEnd: true }), + captured: keyOf({ onDragEndCapture: true }) } }, dragEnter: { phasedRegistrationNames: { - bubbled: keyOf({onDragEnter: true}), - captured: keyOf({onDragEnterCapture: true}) + bubbled: keyOf({ onDragEnter: true }), + captured: keyOf({ onDragEnterCapture: true }) } }, dragExit: { phasedRegistrationNames: { - bubbled: keyOf({onDragExit: true}), - captured: keyOf({onDragExitCapture: true}) + bubbled: keyOf({ onDragExit: true }), + captured: keyOf({ onDragExitCapture: true }) } }, dragLeave: { phasedRegistrationNames: { - bubbled: keyOf({onDragLeave: true}), - captured: keyOf({onDragLeaveCapture: true}) + bubbled: keyOf({ onDragLeave: true }), + captured: keyOf({ onDragLeaveCapture: true }) } }, dragOver: { phasedRegistrationNames: { - bubbled: keyOf({onDragOver: true}), - captured: keyOf({onDragOverCapture: true}) + bubbled: keyOf({ onDragOver: true }), + captured: keyOf({ onDragOverCapture: true }) } }, dragStart: { phasedRegistrationNames: { - bubbled: keyOf({onDragStart: true}), - captured: keyOf({onDragStartCapture: true}) + bubbled: keyOf({ onDragStart: true }), + captured: keyOf({ onDragStartCapture: true }) } }, drop: { phasedRegistrationNames: { - bubbled: keyOf({onDrop: true}), - captured: keyOf({onDropCapture: true}) + bubbled: keyOf({ onDrop: true }), + captured: keyOf({ onDropCapture: true }) + } + }, + durationChange: { + phasedRegistrationNames: { + bubbled: keyOf({ onDurationChange: true }), + captured: keyOf({ onDurationChangeCapture: true }) + } + }, + emptied: { + phasedRegistrationNames: { + bubbled: keyOf({ onEmptied: true }), + captured: keyOf({ onEmptiedCapture: true }) + } + }, + encrypted: { + phasedRegistrationNames: { + bubbled: keyOf({ onEncrypted: true }), + captured: keyOf({ onEncryptedCapture: true }) + } + }, + ended: { + phasedRegistrationNames: { + bubbled: keyOf({ onEnded: true }), + captured: keyOf({ onEndedCapture: true }) + } + }, + error: { + phasedRegistrationNames: { + bubbled: keyOf({ onError: true }), + captured: keyOf({ onErrorCapture: true }) } }, focus: { phasedRegistrationNames: { - bubbled: keyOf({onFocus: true}), - captured: keyOf({onFocusCapture: true}) + bubbled: keyOf({ onFocus: true }), + captured: keyOf({ onFocusCapture: true }) } }, input: { phasedRegistrationNames: { - bubbled: keyOf({onInput: true}), - captured: keyOf({onInputCapture: true}) + bubbled: keyOf({ onInput: true }), + captured: keyOf({ onInputCapture: true }) } }, keyDown: { phasedRegistrationNames: { - bubbled: keyOf({onKeyDown: true}), - captured: keyOf({onKeyDownCapture: true}) + bubbled: keyOf({ onKeyDown: true }), + captured: keyOf({ onKeyDownCapture: true }) } }, keyPress: { phasedRegistrationNames: { - bubbled: keyOf({onKeyPress: true}), - captured: keyOf({onKeyPressCapture: true}) + bubbled: keyOf({ onKeyPress: true }), + captured: keyOf({ onKeyPressCapture: true }) } }, keyUp: { phasedRegistrationNames: { - bubbled: keyOf({onKeyUp: true}), - captured: keyOf({onKeyUpCapture: true}) + bubbled: keyOf({ onKeyUp: true }), + captured: keyOf({ onKeyUpCapture: true }) } }, load: { phasedRegistrationNames: { - bubbled: keyOf({onLoad: true}), - captured: keyOf({onLoadCapture: true}) + bubbled: keyOf({ onLoad: true }), + captured: keyOf({ onLoadCapture: true }) } }, - error: { + loadedData: { phasedRegistrationNames: { - bubbled: keyOf({onError: true}), - captured: keyOf({onErrorCapture: true}) + bubbled: keyOf({ onLoadedData: true }), + captured: keyOf({ onLoadedDataCapture: true }) + } + }, + loadedMetadata: { + phasedRegistrationNames: { + bubbled: keyOf({ onLoadedMetadata: true }), + captured: keyOf({ onLoadedMetadataCapture: true }) + } + }, + loadStart: { + phasedRegistrationNames: { + bubbled: keyOf({ onLoadStart: true }), + captured: keyOf({ onLoadStartCapture: true }) } }, // Note: We do not allow listening to mouseOver events. Instead, use the // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`. mouseDown: { phasedRegistrationNames: { - bubbled: keyOf({onMouseDown: true}), - captured: keyOf({onMouseDownCapture: true}) + bubbled: keyOf({ onMouseDown: true }), + captured: keyOf({ onMouseDownCapture: true }) } }, mouseMove: { phasedRegistrationNames: { - bubbled: keyOf({onMouseMove: true}), - captured: keyOf({onMouseMoveCapture: true}) + bubbled: keyOf({ onMouseMove: true }), + captured: keyOf({ onMouseMoveCapture: true }) } }, mouseOut: { phasedRegistrationNames: { - bubbled: keyOf({onMouseOut: true}), - captured: keyOf({onMouseOutCapture: true}) + bubbled: keyOf({ onMouseOut: true }), + captured: keyOf({ onMouseOutCapture: true }) } }, mouseOver: { phasedRegistrationNames: { - bubbled: keyOf({onMouseOver: true}), - captured: keyOf({onMouseOverCapture: true}) + bubbled: keyOf({ onMouseOver: true }), + captured: keyOf({ onMouseOverCapture: true }) } }, mouseUp: { phasedRegistrationNames: { - bubbled: keyOf({onMouseUp: true}), - captured: keyOf({onMouseUpCapture: true}) + bubbled: keyOf({ onMouseUp: true }), + captured: keyOf({ onMouseUpCapture: true }) } }, paste: { phasedRegistrationNames: { - bubbled: keyOf({onPaste: true}), - captured: keyOf({onPasteCapture: true}) + bubbled: keyOf({ onPaste: true }), + captured: keyOf({ onPasteCapture: true }) + } + }, + pause: { + phasedRegistrationNames: { + bubbled: keyOf({ onPause: true }), + captured: keyOf({ onPauseCapture: true }) + } + }, + play: { + phasedRegistrationNames: { + bubbled: keyOf({ onPlay: true }), + captured: keyOf({ onPlayCapture: true }) + } + }, + playing: { + phasedRegistrationNames: { + bubbled: keyOf({ onPlaying: true }), + captured: keyOf({ onPlayingCapture: true }) + } + }, + progress: { + phasedRegistrationNames: { + bubbled: keyOf({ onProgress: true }), + captured: keyOf({ onProgressCapture: true }) + } + }, + rateChange: { + phasedRegistrationNames: { + bubbled: keyOf({ onRateChange: true }), + captured: keyOf({ onRateChangeCapture: true }) } }, reset: { phasedRegistrationNames: { - bubbled: keyOf({onReset: true}), - captured: keyOf({onResetCapture: true}) + bubbled: keyOf({ onReset: true }), + captured: keyOf({ onResetCapture: true }) } }, scroll: { phasedRegistrationNames: { - bubbled: keyOf({onScroll: true}), - captured: keyOf({onScrollCapture: true}) + bubbled: keyOf({ onScroll: true }), + captured: keyOf({ onScrollCapture: true }) + } + }, + seeked: { + phasedRegistrationNames: { + bubbled: keyOf({ onSeeked: true }), + captured: keyOf({ onSeekedCapture: true }) + } + }, + seeking: { + phasedRegistrationNames: { + bubbled: keyOf({ onSeeking: true }), + captured: keyOf({ onSeekingCapture: true }) + } + }, + stalled: { + phasedRegistrationNames: { + bubbled: keyOf({ onStalled: true }), + captured: keyOf({ onStalledCapture: true }) } }, submit: { phasedRegistrationNames: { - bubbled: keyOf({onSubmit: true}), - captured: keyOf({onSubmitCapture: true}) + bubbled: keyOf({ onSubmit: true }), + captured: keyOf({ onSubmitCapture: true }) + } + }, + suspend: { + phasedRegistrationNames: { + bubbled: keyOf({ onSuspend: true }), + captured: keyOf({ onSuspendCapture: true }) + } + }, + timeUpdate: { + phasedRegistrationNames: { + bubbled: keyOf({ onTimeUpdate: true }), + captured: keyOf({ onTimeUpdateCapture: true }) } }, touchCancel: { phasedRegistrationNames: { - bubbled: keyOf({onTouchCancel: true}), - captured: keyOf({onTouchCancelCapture: true}) + bubbled: keyOf({ onTouchCancel: true }), + captured: keyOf({ onTouchCancelCapture: true }) } }, touchEnd: { phasedRegistrationNames: { - bubbled: keyOf({onTouchEnd: true}), - captured: keyOf({onTouchEndCapture: true}) + bubbled: keyOf({ onTouchEnd: true }), + captured: keyOf({ onTouchEndCapture: true }) } }, touchMove: { phasedRegistrationNames: { - bubbled: keyOf({onTouchMove: true}), - captured: keyOf({onTouchMoveCapture: true}) + bubbled: keyOf({ onTouchMove: true }), + captured: keyOf({ onTouchMoveCapture: true }) } }, touchStart: { phasedRegistrationNames: { - bubbled: keyOf({onTouchStart: true}), - captured: keyOf({onTouchStartCapture: true}) + bubbled: keyOf({ onTouchStart: true }), + captured: keyOf({ onTouchStartCapture: true }) + } + }, + volumeChange: { + phasedRegistrationNames: { + bubbled: keyOf({ onVolumeChange: true }), + captured: keyOf({ onVolumeChangeCapture: true }) + } + }, + waiting: { + phasedRegistrationNames: { + bubbled: keyOf({ onWaiting: true }), + captured: keyOf({ onWaitingCapture: true }) } }, wheel: { phasedRegistrationNames: { - bubbled: keyOf({onWheel: true}), - captured: keyOf({onWheelCapture: true}) + bubbled: keyOf({ onWheel: true }), + captured: keyOf({ onWheelCapture: true }) } } }; var topLevelEventsToDispatchConfig = { - topBlur: eventTypes.blur, - topClick: eventTypes.click, + topAbort: eventTypes.abort, + topBlur: eventTypes.blur, + topCanPlay: eventTypes.canPlay, + topCanPlayThrough: eventTypes.canPlayThrough, + topClick: eventTypes.click, topContextMenu: eventTypes.contextMenu, - topCopy: eventTypes.copy, - topCut: eventTypes.cut, + topCopy: eventTypes.copy, + topCut: eventTypes.cut, topDoubleClick: eventTypes.doubleClick, - topDrag: eventTypes.drag, - topDragEnd: eventTypes.dragEnd, - topDragEnter: eventTypes.dragEnter, - topDragExit: eventTypes.dragExit, - topDragLeave: eventTypes.dragLeave, - topDragOver: eventTypes.dragOver, - topDragStart: eventTypes.dragStart, - topDrop: eventTypes.drop, - topError: eventTypes.error, - topFocus: eventTypes.focus, - topInput: eventTypes.input, - topKeyDown: eventTypes.keyDown, - topKeyPress: eventTypes.keyPress, - topKeyUp: eventTypes.keyUp, - topLoad: eventTypes.load, - topMouseDown: eventTypes.mouseDown, - topMouseMove: eventTypes.mouseMove, - topMouseOut: eventTypes.mouseOut, - topMouseOver: eventTypes.mouseOver, - topMouseUp: eventTypes.mouseUp, - topPaste: eventTypes.paste, - topReset: eventTypes.reset, - topScroll: eventTypes.scroll, - topSubmit: eventTypes.submit, + topDrag: eventTypes.drag, + topDragEnd: eventTypes.dragEnd, + topDragEnter: eventTypes.dragEnter, + topDragExit: eventTypes.dragExit, + topDragLeave: eventTypes.dragLeave, + topDragOver: eventTypes.dragOver, + topDragStart: eventTypes.dragStart, + topDrop: eventTypes.drop, + topDurationChange: eventTypes.durationChange, + topEmptied: eventTypes.emptied, + topEncrypted: eventTypes.encrypted, + topEnded: eventTypes.ended, + topError: eventTypes.error, + topFocus: eventTypes.focus, + topInput: eventTypes.input, + topKeyDown: eventTypes.keyDown, + topKeyPress: eventTypes.keyPress, + topKeyUp: eventTypes.keyUp, + topLoad: eventTypes.load, + topLoadedData: eventTypes.loadedData, + topLoadedMetadata: eventTypes.loadedMetadata, + topLoadStart: eventTypes.loadStart, + topMouseDown: eventTypes.mouseDown, + topMouseMove: eventTypes.mouseMove, + topMouseOut: eventTypes.mouseOut, + topMouseOver: eventTypes.mouseOver, + topMouseUp: eventTypes.mouseUp, + topPaste: eventTypes.paste, + topPause: eventTypes.pause, + topPlay: eventTypes.play, + topPlaying: eventTypes.playing, + topProgress: eventTypes.progress, + topRateChange: eventTypes.rateChange, + topReset: eventTypes.reset, + topScroll: eventTypes.scroll, + topSeeked: eventTypes.seeked, + topSeeking: eventTypes.seeking, + topStalled: eventTypes.stalled, + topSubmit: eventTypes.submit, + topSuspend: eventTypes.suspend, + topTimeUpdate: eventTypes.timeUpdate, topTouchCancel: eventTypes.touchCancel, - topTouchEnd: eventTypes.touchEnd, - topTouchMove: eventTypes.touchMove, - topTouchStart: eventTypes.touchStart, - topWheel: eventTypes.wheel + topTouchEnd: eventTypes.touchEnd, + topTouchMove: eventTypes.touchMove, + topTouchStart: eventTypes.touchStart, + topVolumeChange: eventTypes.volumeChange, + topWaiting: eventTypes.waiting, + topWheel: eventTypes.wheel }; for (var type in topLevelEventsToDispatchConfig) { topLevelEventsToDispatchConfig[type].dependencies = [type]; } +var ON_CLICK_KEY = keyOf({ onClick: null }); +var onClickListeners = {}; + var SimpleEventPlugin = { eventTypes: eventTypes, /** - * Same as the default implementation, except cancels the event when return - * value is false. This behavior will be disabled in a future release. - * - * @param {object} Event to be dispatched. - * @param {function} Application-level callback. - * @param {string} domID DOM ID to pass to the callback. - */ - executeDispatch: function(event, listener, domID) { - var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); - - ("production" !== process.env.NODE_ENV ? warning( - typeof returnValue !== 'boolean', - 'Returning `false` from an event handler is deprecated and will be ' + - 'ignored in a future release. Instead, manually call ' + - 'e.stopPropagation() or e.preventDefault(), as appropriate.' - ) : null); - - if (returnValue === false) { - event.stopPropagation(); - event.preventDefault(); - } - }, - - /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. @@ -20887,22 +21547,40 @@ var SimpleEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; if (!dispatchConfig) { return null; } var EventConstructor; switch (topLevelType) { + case topLevelTypes.topAbort: + case topLevelTypes.topCanPlay: + case topLevelTypes.topCanPlayThrough: + case topLevelTypes.topDurationChange: + case topLevelTypes.topEmptied: + case topLevelTypes.topEncrypted: + case topLevelTypes.topEnded: + case topLevelTypes.topError: case topLevelTypes.topInput: case topLevelTypes.topLoad: - case topLevelTypes.topError: + case topLevelTypes.topLoadedData: + case topLevelTypes.topLoadedMetadata: + case topLevelTypes.topLoadStart: + case topLevelTypes.topPause: + case topLevelTypes.topPlay: + case topLevelTypes.topPlaying: + case topLevelTypes.topProgress: + case topLevelTypes.topRateChange: case topLevelTypes.topReset: + case topLevelTypes.topSeeked: + case topLevelTypes.topSeeking: + case topLevelTypes.topStalled: case topLevelTypes.topSubmit: + case topLevelTypes.topSuspend: + case topLevelTypes.topTimeUpdate: + case topLevelTypes.topVolumeChange: + case topLevelTypes.topWaiting: // HTML Events // @see http://www.w3.org/TR/html5/index.html#events-0 EventConstructor = SyntheticEvent; @@ -20914,7 +21592,7 @@ var SimpleEventPlugin = { if (getEventCharCode(nativeEvent) === 0) { return null; } - /* falls through */ + /* falls through */ case topLevelTypes.topKeyDown: case topLevelTypes.topKeyUp: EventConstructor = SyntheticKeyboardEvent; @@ -20929,7 +21607,7 @@ var SimpleEventPlugin = { if (nativeEvent.button === 2) { return null; } - /* falls through */ + /* falls through */ case topLevelTypes.topContextMenu: case topLevelTypes.topDoubleClick: case topLevelTypes.topMouseDown: @@ -20967,27 +21645,38 @@ var SimpleEventPlugin = { EventConstructor = SyntheticClipboardEvent; break; } - ("production" !== process.env.NODE_ENV ? invariant( - EventConstructor, - 'SimpleEventPlugin: Unhandled event type, `%s`.', - topLevelType - ) : invariant(EventConstructor)); - var event = EventConstructor.getPooled( - dispatchConfig, - topLevelTargetID, - nativeEvent - ); + !EventConstructor ? process.env.NODE_ENV !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : invariant(false) : undefined; + var event = EventConstructor.getPooled(dispatchConfig, topLevelTargetID, nativeEvent, nativeEventTarget); EventPropagators.accumulateTwoPhaseDispatches(event); return event; + }, + + didPutListener: function (id, registrationName, listener) { + // Mobile Safari does not fire properly bubble click events on + // non-interactive elements, which means delegated click listeners do not + // fire. The workaround for this bug involves attaching an empty click + // listener on the target node. + if (registrationName === ON_CLICK_KEY) { + var node = ReactMount.getNode(id); + if (!onClickListeners[id]) { + onClickListeners[id] = EventListener.listen(node, 'click', emptyFunction); + } + } + }, + + willDeleteListener: function (id, registrationName) { + if (registrationName === ON_CLICK_KEY) { + onClickListeners[id].remove(); + delete onClickListeners[id]; + } } }; module.exports = SimpleEventPlugin; - }).call(this,require('_process')) -},{"./EventConstants":56,"./EventPluginUtils":60,"./EventPropagators":61,"./SyntheticClipboardEvent":146,"./SyntheticDragEvent":148,"./SyntheticEvent":149,"./SyntheticFocusEvent":150,"./SyntheticKeyboardEvent":152,"./SyntheticMouseEvent":153,"./SyntheticTouchEvent":154,"./SyntheticUIEvent":155,"./SyntheticWheelEvent":156,"./getEventCharCode":178,"./invariant":191,"./keyOf":198,"./warning":212,"_process":1}],146:[function(require,module,exports){ +},{"./EventConstants":73,"./EventPropagators":77,"./ReactMount":130,"./SyntheticClipboardEvent":161,"./SyntheticDragEvent":163,"./SyntheticEvent":164,"./SyntheticFocusEvent":165,"./SyntheticKeyboardEvent":167,"./SyntheticMouseEvent":168,"./SyntheticTouchEvent":169,"./SyntheticUIEvent":170,"./SyntheticWheelEvent":171,"./getEventCharCode":184,"_process":1,"fbjs/lib/EventListener":205,"fbjs/lib/emptyFunction":212,"fbjs/lib/invariant":220,"fbjs/lib/keyOf":225}],161:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21002,19 +21691,15 @@ module.exports = SimpleEventPlugin; 'use strict'; -var SyntheticEvent = require("./SyntheticEvent"); +var SyntheticEvent = require('./SyntheticEvent'); /** * @interface Event * @see http://www.w3.org/TR/clipboard-apis/ */ var ClipboardEventInterface = { - clipboardData: function(event) { - return ( - 'clipboardData' in event ? - event.clipboardData : - window.clipboardData - ); + clipboardData: function (event) { + return 'clipboardData' in event ? event.clipboardData : window.clipboardData; } }; @@ -21024,15 +21709,14 @@ var ClipboardEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); module.exports = SyntheticClipboardEvent; - -},{"./SyntheticEvent":149}],147:[function(require,module,exports){ +},{"./SyntheticEvent":164}],162:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21047,7 +21731,7 @@ module.exports = SyntheticClipboardEvent; 'use strict'; -var SyntheticEvent = require("./SyntheticEvent"); +var SyntheticEvent = require('./SyntheticEvent'); /** * @interface Event @@ -21063,21 +21747,14 @@ var CompositionEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticCompositionEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } -SyntheticEvent.augmentClass( - SyntheticCompositionEvent, - CompositionEventInterface -); +SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); module.exports = SyntheticCompositionEvent; - -},{"./SyntheticEvent":149}],148:[function(require,module,exports){ +},{"./SyntheticEvent":164}],163:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21092,7 +21769,7 @@ module.exports = SyntheticCompositionEvent; 'use strict'; -var SyntheticMouseEvent = require("./SyntheticMouseEvent"); +var SyntheticMouseEvent = require('./SyntheticMouseEvent'); /** * @interface DragEvent @@ -21108,15 +21785,15 @@ var DragEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); module.exports = SyntheticDragEvent; - -},{"./SyntheticMouseEvent":153}],149:[function(require,module,exports){ +},{"./SyntheticMouseEvent":168}],164:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21131,11 +21808,11 @@ module.exports = SyntheticDragEvent; 'use strict'; -var PooledClass = require("./PooledClass"); +var PooledClass = require('./PooledClass'); -var assign = require("./Object.assign"); -var emptyFunction = require("./emptyFunction"); -var getEventTarget = require("./getEventTarget"); +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var warning = require('fbjs/lib/warning'); /** * @interface Event @@ -21143,13 +21820,13 @@ var getEventTarget = require("./getEventTarget"); */ var EventInterface = { type: null, - target: getEventTarget, + target: null, // currentTarget is set when dispatching; no use in copying it here currentTarget: emptyFunction.thatReturnsNull, eventPhase: null, bubbles: null, cancelable: null, - timeStamp: function(event) { + timeStamp: function (event) { return event.timeStamp || Date.now(); }, defaultPrevented: null, @@ -21173,7 +21850,7 @@ var EventInterface = { * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. */ -function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { +function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { this.dispatchConfig = dispatchConfig; this.dispatchMarker = dispatchMarker; this.nativeEvent = nativeEvent; @@ -21187,13 +21864,15 @@ function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { if (normalize) { this[propName] = normalize(nativeEvent); } else { - this[propName] = nativeEvent[propName]; + if (propName === 'target') { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } } } - var defaultPrevented = nativeEvent.defaultPrevented != null ? - nativeEvent.defaultPrevented : - nativeEvent.returnValue === false; + var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; if (defaultPrevented) { this.isDefaultPrevented = emptyFunction.thatReturnsTrue; } else { @@ -21204,9 +21883,16 @@ function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { assign(SyntheticEvent.prototype, { - preventDefault: function() { + preventDefault: function () { this.defaultPrevented = true; var event = this.nativeEvent; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re calling `preventDefault` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined; + } + if (!event) { + return; + } + if (event.preventDefault) { event.preventDefault(); } else { @@ -21215,8 +21901,15 @@ assign(SyntheticEvent.prototype, { this.isDefaultPrevented = emptyFunction.thatReturnsTrue; }, - stopPropagation: function() { + stopPropagation: function () { var event = this.nativeEvent; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re calling `stopPropagation` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined; + } + if (!event) { + return; + } + if (event.stopPropagation) { event.stopPropagation(); } else { @@ -21230,7 +21923,7 @@ assign(SyntheticEvent.prototype, { * 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() { + persist: function () { this.isPersistent = emptyFunction.thatReturnsTrue; }, @@ -21244,7 +21937,7 @@ assign(SyntheticEvent.prototype, { /** * `PooledClass` looks for `destructor` on each instance it releases. */ - destructor: function() { + destructor: function () { var Interface = this.constructor.Interface; for (var propName in Interface) { this[propName] = null; @@ -21264,7 +21957,7 @@ SyntheticEvent.Interface = EventInterface; * @param {function} Class * @param {?object} Interface */ -SyntheticEvent.augmentClass = function(Class, Interface) { +SyntheticEvent.augmentClass = function (Class, Interface) { var Super = this; var prototype = Object.create(Super.prototype); @@ -21275,14 +21968,15 @@ SyntheticEvent.augmentClass = function(Class, Interface) { Class.Interface = assign({}, Super.Interface, Interface); Class.augmentClass = Super.augmentClass; - PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler); + PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler); }; -PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler); +PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler); module.exports = SyntheticEvent; +}).call(this,require('_process')) -},{"./Object.assign":69,"./PooledClass":70,"./emptyFunction":170,"./getEventTarget":181}],150:[function(require,module,exports){ +},{"./Object.assign":82,"./PooledClass":83,"_process":1,"fbjs/lib/emptyFunction":212,"fbjs/lib/warning":232}],165:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21297,7 +21991,7 @@ module.exports = SyntheticEvent; 'use strict'; -var SyntheticUIEvent = require("./SyntheticUIEvent"); +var SyntheticUIEvent = require('./SyntheticUIEvent'); /** * @interface FocusEvent @@ -21313,15 +22007,14 @@ var FocusEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); module.exports = SyntheticFocusEvent; - -},{"./SyntheticUIEvent":155}],151:[function(require,module,exports){ +},{"./SyntheticUIEvent":170}],166:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21336,7 +22029,7 @@ module.exports = SyntheticFocusEvent; 'use strict'; -var SyntheticEvent = require("./SyntheticEvent"); +var SyntheticEvent = require('./SyntheticEvent'); /** * @interface Event @@ -21353,21 +22046,14 @@ var InputEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticInputEvent( - dispatchConfig, - dispatchMarker, - nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } -SyntheticEvent.augmentClass( - SyntheticInputEvent, - InputEventInterface -); +SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface); module.exports = SyntheticInputEvent; - -},{"./SyntheticEvent":149}],152:[function(require,module,exports){ +},{"./SyntheticEvent":164}],167:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21382,11 +22068,11 @@ module.exports = SyntheticInputEvent; 'use strict'; -var SyntheticUIEvent = require("./SyntheticUIEvent"); +var SyntheticUIEvent = require('./SyntheticUIEvent'); -var getEventCharCode = require("./getEventCharCode"); -var getEventKey = require("./getEventKey"); -var getEventModifierState = require("./getEventModifierState"); +var getEventCharCode = require('./getEventCharCode'); +var getEventKey = require('./getEventKey'); +var getEventModifierState = require('./getEventModifierState'); /** * @interface KeyboardEvent @@ -21403,7 +22089,7 @@ var KeyboardEventInterface = { locale: null, getModifierState: getEventModifierState, // Legacy Interface - charCode: function(event) { + charCode: function (event) { // `charCode` is the result of a KeyPress event and represents the value of // the actual printable character. @@ -21414,7 +22100,7 @@ var KeyboardEventInterface = { } return 0; }, - keyCode: function(event) { + keyCode: function (event) { // `keyCode` is the result of a KeyDown/Up event and represents the value of // physical keyboard key. @@ -21427,7 +22113,7 @@ var KeyboardEventInterface = { } return 0; }, - which: function(event) { + which: function (event) { // `which` is an alias for either `keyCode` or `charCode` depending on the // type of the event. if (event.type === 'keypress') { @@ -21446,15 +22132,14 @@ var KeyboardEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); module.exports = SyntheticKeyboardEvent; - -},{"./SyntheticUIEvent":155,"./getEventCharCode":178,"./getEventKey":179,"./getEventModifierState":180}],153:[function(require,module,exports){ +},{"./SyntheticUIEvent":170,"./getEventCharCode":184,"./getEventKey":185,"./getEventModifierState":186}],168:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21469,10 +22154,10 @@ module.exports = SyntheticKeyboardEvent; 'use strict'; -var SyntheticUIEvent = require("./SyntheticUIEvent"); -var ViewportMetrics = require("./ViewportMetrics"); +var SyntheticUIEvent = require('./SyntheticUIEvent'); +var ViewportMetrics = require('./ViewportMetrics'); -var getEventModifierState = require("./getEventModifierState"); +var getEventModifierState = require('./getEventModifierState'); /** * @interface MouseEvent @@ -21488,7 +22173,7 @@ var MouseEventInterface = { altKey: null, metaKey: null, getModifierState: getEventModifierState, - button: function(event) { + button: function (event) { // Webkit, Firefox, IE9+ // which: 1 2 3 // button: 0 1 2 (standard) @@ -21503,21 +22188,15 @@ var MouseEventInterface = { return button === 2 ? 2 : button === 4 ? 1 : 0; }, buttons: null, - relatedTarget: function(event) { - return event.relatedTarget || ( - ((event.fromElement === event.srcElement ? event.toElement : event.fromElement)) - ); + relatedTarget: function (event) { + return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); }, // "Proprietary" Interface. - pageX: function(event) { - return 'pageX' in event ? - event.pageX : - event.clientX + ViewportMetrics.currentScrollLeft; + pageX: function (event) { + return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft; }, - pageY: function(event) { - return 'pageY' in event ? - event.pageY : - event.clientY + ViewportMetrics.currentScrollTop; + pageY: function (event) { + return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop; } }; @@ -21527,15 +22206,14 @@ var MouseEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); module.exports = SyntheticMouseEvent; - -},{"./SyntheticUIEvent":155,"./ViewportMetrics":158,"./getEventModifierState":180}],154:[function(require,module,exports){ +},{"./SyntheticUIEvent":170,"./ViewportMetrics":173,"./getEventModifierState":186}],169:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21550,9 +22228,9 @@ module.exports = SyntheticMouseEvent; 'use strict'; -var SyntheticUIEvent = require("./SyntheticUIEvent"); +var SyntheticUIEvent = require('./SyntheticUIEvent'); -var getEventModifierState = require("./getEventModifierState"); +var getEventModifierState = require('./getEventModifierState'); /** * @interface TouchEvent @@ -21575,15 +22253,14 @@ var TouchEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ -function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); module.exports = SyntheticTouchEvent; - -},{"./SyntheticUIEvent":155,"./getEventModifierState":180}],155:[function(require,module,exports){ +},{"./SyntheticUIEvent":170,"./getEventModifierState":186}],170:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21598,16 +22275,16 @@ module.exports = SyntheticTouchEvent; 'use strict'; -var SyntheticEvent = require("./SyntheticEvent"); +var SyntheticEvent = require('./SyntheticEvent'); -var getEventTarget = require("./getEventTarget"); +var getEventTarget = require('./getEventTarget'); /** * @interface UIEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var UIEventInterface = { - view: function(event) { + view: function (event) { if (event.view) { return event.view; } @@ -21626,7 +22303,7 @@ var UIEventInterface = { return window; } }, - detail: function(event) { + detail: function (event) { return event.detail || 0; } }; @@ -21637,15 +22314,14 @@ var UIEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticEvent} */ -function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); module.exports = SyntheticUIEvent; - -},{"./SyntheticEvent":149,"./getEventTarget":181}],156:[function(require,module,exports){ +},{"./SyntheticEvent":164,"./getEventTarget":187}],171:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21660,28 +22336,24 @@ module.exports = SyntheticUIEvent; 'use strict'; -var SyntheticMouseEvent = require("./SyntheticMouseEvent"); +var SyntheticMouseEvent = require('./SyntheticMouseEvent'); /** * @interface WheelEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var WheelEventInterface = { - deltaX: function(event) { - return ( - 'deltaX' in event ? event.deltaX : - // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). - 'wheelDeltaX' in event ? -event.wheelDeltaX : 0 - ); - }, - deltaY: function(event) { - return ( - 'deltaY' in event ? event.deltaY : - // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). - 'wheelDeltaY' in event ? -event.wheelDeltaY : - // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). - 'wheelDelta' in event ? -event.wheelDelta : 0 - ); + deltaX: function (event) { + return 'deltaX' in event ? event.deltaX : + // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). + 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; + }, + deltaY: function (event) { + return 'deltaY' in event ? event.deltaY : + // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). + 'wheelDeltaY' in event ? -event.wheelDeltaY : + // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). + 'wheelDelta' in event ? -event.wheelDelta : 0; }, deltaZ: null, @@ -21698,15 +22370,14 @@ var WheelEventInterface = { * @param {object} nativeEvent Native browser event. * @extends {SyntheticMouseEvent} */ -function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) { - SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); +function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); module.exports = SyntheticWheelEvent; - -},{"./SyntheticMouseEvent":153}],157:[function(require,module,exports){ +},{"./SyntheticMouseEvent":168}],172:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -21721,7 +22392,7 @@ module.exports = SyntheticWheelEvent; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * `Transaction` creates a black box that is able to wrap any method such that @@ -21792,12 +22463,12 @@ var Mixin = { * That can be useful if you decide to make your subclass of this mixin a * "PooledClass". */ - reinitializeTransaction: function() { + reinitializeTransaction: function () { this.transactionWrappers = this.getTransactionWrappers(); - if (!this.wrapperInitData) { - this.wrapperInitData = []; - } else { + if (this.wrapperInitData) { this.wrapperInitData.length = 0; + } else { + this.wrapperInitData = []; } this._isInTransaction = false; }, @@ -21810,27 +22481,29 @@ var Mixin = { */ getTransactionWrappers: null, - isInTransaction: function() { + 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. + * need to be safety checked. The optional arguments helps prevent the need + * to bind in many cases. * * @param {function} method Member of scope to call. * @param {Object} scope Scope to invoke from. - * @param {Object?=} args... Arguments to pass to the method (optional). - * Helps prevent need to bind in many cases. - * @return Return value from `method`. - */ - perform: function(method, scope, a, b, c, d, e, f) { - ("production" !== process.env.NODE_ENV ? invariant( - !this.isInTransaction(), - 'Transaction.perform(...): Cannot initialize a transaction when there ' + - 'is already an outstanding transaction.' - ) : invariant(!this.isInTransaction())); + * @param {Object?=} a Argument to pass to the method. + * @param {Object?=} b Argument to pass to the method. + * @param {Object?=} c Argument to pass to the method. + * @param {Object?=} d Argument to pass to the method. + * @param {Object?=} e Argument to pass to the method. + * @param {Object?=} f Argument to pass to the method. + * + * @return {*} Return value from `method`. + */ + perform: function (method, scope, a, b, c, d, e, f) { + !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there ' + 'is already an outstanding transaction.') : invariant(false) : undefined; var errorThrown; var ret; try { @@ -21850,8 +22523,7 @@ var Mixin = { // by invoking `closeAll`. try { this.closeAll(0); - } catch (err) { - } + } catch (err) {} } else { // Since `method` didn't throw, we don't want to silence the exception // here. @@ -21864,7 +22536,7 @@ var Mixin = { return ret; }, - initializeAll: function(startIndex) { + initializeAll: function (startIndex) { var transactionWrappers = this.transactionWrappers; for (var i = startIndex; i < transactionWrappers.length; i++) { var wrapper = transactionWrappers[i]; @@ -21874,9 +22546,7 @@ var Mixin = { // 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; + 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 @@ -21884,8 +22554,7 @@ var Mixin = { // that the first error is the one to bubble up. try { this.initializeAll(i + 1); - } catch (err) { - } + } catch (err) {} } } } @@ -21897,11 +22566,8 @@ var Mixin = { * (`close`rs that correspond to initializers that failed will not be * invoked). */ - closeAll: function(startIndex) { - ("production" !== process.env.NODE_ENV ? invariant( - this.isInTransaction(), - 'Transaction.closeAll(): Cannot close transaction when none are open.' - ) : invariant(this.isInTransaction())); + closeAll: function (startIndex) { + !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : invariant(false) : undefined; var transactionWrappers = this.transactionWrappers; for (var i = startIndex; i < transactionWrappers.length; i++) { var wrapper = transactionWrappers[i]; @@ -21924,8 +22590,7 @@ var Mixin = { // first error is the one to bubble up. try { this.closeAll(i + 1); - } catch (e) { - } + } catch (e) {} } } } @@ -21938,17 +22603,16 @@ var Transaction = { Mixin: Mixin, /** - * Token to look for to determine if an error occured. + * Token to look for to determine if an error occurred. */ OBSERVED_ERROR: {} }; module.exports = Transaction; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],158:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],173:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -21968,7 +22632,7 @@ var ViewportMetrics = { currentScrollTop: 0, - refreshScrollValues: function(scrollPosition) { + refreshScrollValues: function (scrollPosition) { ViewportMetrics.currentScrollLeft = scrollPosition.x; ViewportMetrics.currentScrollTop = scrollPosition.y; } @@ -21976,8 +22640,7 @@ var ViewportMetrics = { }; module.exports = ViewportMetrics; - -},{}],159:[function(require,module,exports){ +},{}],174:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -21992,7 +22655,7 @@ module.exports = ViewportMetrics; 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * @@ -22009,10 +22672,7 @@ var invariant = require("./invariant"); */ function accumulateInto(current, next) { - ("production" !== process.env.NODE_ENV ? invariant( - next != null, - 'accumulateInto(...): Accumulated items must not be null or undefined.' - ) : invariant(next != null)); + !(next != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : invariant(false) : undefined; if (current == null) { return next; } @@ -22041,10 +22701,9 @@ function accumulateInto(current, next) { } module.exports = accumulateInto; - }).call(this,require('_process')) -},{"./invariant":191,"_process":1}],160:[function(require,module,exports){ +},{"_process":1,"fbjs/lib/invariant":220}],175:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22056,29 +22715,39 @@ module.exports = accumulateInto; * @providesModule adler32 */ -/* jslint bitwise:true */ - 'use strict'; var MOD = 65521; -// This is a clean-room implementation of adler32 designed for detecting -// if markup is not what we expect it to be. It does not need to be -// cryptographically strong, only reasonably good at detecting if markup -// generated on the server is different than that on the client. +// adler32 is not cryptographically strong, and is only used to sanity check that +// markup generated on the server matches the markup generated on the client. +// This implementation (a modified version of the SheetJS version) has been optimized +// for our use case, at the expense of conforming to the adler32 specification +// for non-ascii inputs. function adler32(data) { var a = 1; var b = 0; - for (var i = 0; i < data.length; i++) { - a = (a + data.charCodeAt(i)) % MOD; - b = (b + a) % MOD; + var i = 0; + var l = data.length; + var m = l & ~0x3; + while (i < m) { + for (; i < Math.min(i + 4096, m); i += 4) { + b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3)); + } + a %= MOD; + b %= MOD; } - return a | (b << 16); + for (; i < l; i++) { + b += a += data.charCodeAt(i); + } + a %= MOD; + b %= MOD; + return a | b << 16; } module.exports = adler32; - -},{}],161:[function(require,module,exports){ +},{}],176:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22087,72 +22756,25 @@ module.exports = adler32; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule camelize - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function(_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; - -},{}],162:[function(require,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule camelizeStyleName - * @typechecks + * @providesModule canDefineProperty */ -"use strict"; - -var camelize = require("./camelize"); - -var msPattern = /^-ms-/; +'use strict'; -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); +var canDefineProperty = false; +if (process.env.NODE_ENV !== 'production') { + try { + Object.defineProperty({}, 'x', { get: function () {} }); + canDefineProperty = true; + } catch (x) { + // IE will fail on defineProperty + } } -module.exports = camelizeStyleName; +module.exports = canDefineProperty; +}).call(this,require('_process')) -},{"./camelize":161}],163:[function(require,module,exports){ +},{"_process":1}],177:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -22168,13 +22790,15 @@ module.exports = camelizeStyleName; 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactPropTransferer = require("./ReactPropTransferer"); +var ReactElement = require('./ReactElement'); +var ReactPropTransferer = require('./ReactPropTransferer'); + +var keyOf = require('fbjs/lib/keyOf'); +var warning = require('fbjs/lib/warning'); -var keyOf = require("./keyOf"); -var warning = require("./warning"); +var CHILDREN_PROP = keyOf({ children: null }); -var CHILDREN_PROP = keyOf({children: null}); +var didDeprecatedWarn = false; /** * Sometimes you want to change the props of a child passed to you. Usually @@ -22184,376 +22808,31 @@ var CHILDREN_PROP = keyOf({children: null}); * @param {object} props props you'd like to modify. className and style will be * merged automatically. * @return {ReactElement} a clone of child with props merged in. + * @deprecated */ function cloneWithProps(child, props) { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - !child.ref, - 'You are calling cloneWithProps() on a child with a ref. This is ' + - 'dangerous because you\'re creating a new child which will not be ' + - 'added as a ref to its parent.' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(didDeprecatedWarn, 'cloneWithProps(...) is deprecated. ' + 'Please use React.cloneElement instead.') : undefined; + didDeprecatedWarn = true; + process.env.NODE_ENV !== 'production' ? warning(!child.ref, 'You are calling cloneWithProps() on a child with a ref. This is ' + 'dangerous because you\'re creating a new child which will not be ' + 'added as a ref to its parent.') : undefined; } var newProps = ReactPropTransferer.mergeProps(props, child.props); // Use `child.props.children` if it is provided. - if (!newProps.hasOwnProperty(CHILDREN_PROP) && - child.props.hasOwnProperty(CHILDREN_PROP)) { + if (!newProps.hasOwnProperty(CHILDREN_PROP) && child.props.hasOwnProperty(CHILDREN_PROP)) { newProps.children = child.props.children; } - // The current API doesn't retain _owner and _context, which is why this + // The current API doesn't retain _owner, which is why this // doesn't use ReactElement.cloneAndReplaceProps. return ReactElement.createElement(child.type, newProps); } module.exports = cloneWithProps; - -}).call(this,require('_process')) - -},{"./ReactElement":103,"./ReactPropTransferer":123,"./keyOf":198,"./warning":212,"_process":1}],164:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule containsNode - * @typechecks - */ - -var isTextNode = require("./isTextNode"); - -/*jslint bitwise:true */ - -/** - * Checks if a given DOM node contains or is another DOM node. - * - * @param {?DOMNode} outerNode Outer DOM node. - * @param {?DOMNode} innerNode Inner DOM node. - * @return {boolean} True if `outerNode` contains or is `innerNode`. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if (outerNode.contains) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; - -},{"./isTextNode":195}],165:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createArrayFromMixed - * @typechecks - */ - -var toArray = require("./toArray"); - -/** - * Perform a heuristic test to determine if an object is "array-like". - * - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" - * Joshu replied: "Mu." - * - * This function determines if its argument has "array nature": it returns - * true if the argument is an actual array, an `arguments' object, or an - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). - * - * It will return false for other array-like objects like Filelist. - * - * @param {*} obj - * @return {boolean} - */ -function hasArrayNature(obj) { - return ( - // not null/false - !!obj && - // arrays are objects, NodeLists are functions in Safari - (typeof obj == 'object' || typeof obj == 'function') && - // quacks like an array - ('length' in obj) && - // not window - !('setInterval' in obj) && - // no DOM node should be considered an array-like - // a 'select' element has 'length' and 'item' properties on IE8 - (typeof obj.nodeType != 'number') && - ( - // a real array - (// HTMLCollection/NodeList - (Array.isArray(obj) || - // arguments - ('callee' in obj) || 'item' in obj)) - ) - ); -} - -/** - * Ensure that the argument is an array by wrapping it in an array if it is not. - * Creates a copy of the argument if it is already an array. - * - * This is mostly useful idiomatically: - * - * var createArrayFromMixed = require('createArrayFromMixed'); - * - * function takesOneOrMoreThings(things) { - * things = createArrayFromMixed(things); - * ... - * } - * - * This allows you to treat `things' as an array, but accept scalars in the API. - * - * If you need to convert an array-like object, like `arguments`, into an array - * use toArray instead. - * - * @param {*} obj - * @return {array} - */ -function createArrayFromMixed(obj) { - if (!hasArrayNature(obj)) { - return [obj]; - } else if (Array.isArray(obj)) { - return obj.slice(); - } else { - return toArray(obj); - } -} - -module.exports = createArrayFromMixed; - -},{"./toArray":209}],166:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createFullPageComponent - * @typechecks - */ - -'use strict'; - -// Defeat circular references by requiring this directly. -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); - -var invariant = require("./invariant"); - -/** - * Create a component that will throw an exception when unmounted. - * - * Components like <html> <head> and <body> can't be removed or added - * easily in a cross-browser way, however it's valuable to be able to - * take advantage of React's reconciliation for styling and <title> - * management. So we just document it and throw in dangerous cases. - * - * @param {string} tag The tag to wrap - * @return {function} convenience constructor of new component - */ -function createFullPageComponent(tag) { - var elementFactory = ReactElement.createFactory(tag); - - var FullPageComponent = ReactClass.createClass({ - tagName: tag.toUpperCase(), - displayName: 'ReactFullPageComponent' + tag, - - componentWillUnmount: function() { - ("production" !== process.env.NODE_ENV ? invariant( - false, - '%s tried to unmount. Because of cross-browser quirks it is ' + - 'impossible to unmount some top-level components (eg <html>, <head>, ' + - 'and <body>) reliably and efficiently. To fix this, have a single ' + - 'top-level component that never unmounts render these elements.', - this.constructor.displayName - ) : invariant(false)); - }, - - render: function() { - return elementFactory(this.props); - } - }); - - return FullPageComponent; -} - -module.exports = createFullPageComponent; - -}).call(this,require('_process')) - -},{"./ReactClass":78,"./ReactElement":103,"./invariant":191,"_process":1}],167:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule createNodesFromMarkup - * @typechecks - */ - -/*jslint evil: true, sub: true */ - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var createArrayFromMixed = require("./createArrayFromMixed"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); - -/** - * Dummy container used to render all markup. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Pattern used by `getNodeName`. - */ -var nodeNamePattern = /^\s*<(\w+)/; - -/** - * Extracts the `nodeName` of the first element in a string of markup. - * - * @param {string} markup String of markup. - * @return {?string} Node name of the supplied markup. - */ -function getNodeName(markup) { - var nodeNameMatch = markup.match(nodeNamePattern); - return nodeNameMatch && nodeNameMatch[1].toLowerCase(); -} - -/** - * Creates an array containing the nodes rendered from the supplied markup. The - * optionally supplied `handleScript` function will be invoked once for each - * <script> element that is rendered. If no `handleScript` function is supplied, - * an exception is thrown if any <script> elements are rendered. - * - * @param {string} markup A string of valid HTML markup. - * @param {?function} handleScript Invoked once for each rendered <script>. - * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. - */ -function createNodesFromMarkup(markup, handleScript) { - var node = dummyNode; - ("production" !== process.env.NODE_ENV ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode)); - var nodeName = getNodeName(markup); - - var wrap = nodeName && getMarkupWrap(nodeName); - if (wrap) { - node.innerHTML = wrap[1] + markup + wrap[2]; - - var wrapDepth = wrap[0]; - while (wrapDepth--) { - node = node.lastChild; - } - } else { - node.innerHTML = markup; - } - - var scripts = node.getElementsByTagName('script'); - if (scripts.length) { - ("production" !== process.env.NODE_ENV ? invariant( - handleScript, - 'createNodesFromMarkup(...): Unexpected <script> element rendered.' - ) : invariant(handleScript)); - createArrayFromMixed(scripts).forEach(handleScript); - } - - var nodes = createArrayFromMixed(node.childNodes); - while (node.lastChild) { - node.removeChild(node.lastChild); - } - return nodes; -} - -module.exports = createNodesFromMarkup; - -}).call(this,require('_process')) - -},{"./ExecutionEnvironment":62,"./createArrayFromMixed":165,"./getMarkupWrap":183,"./invariant":191,"_process":1}],168:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule cx - */ - -/** - * This function is used to mark string literals representing CSS class names - * so that they can be transformed statically. This allows for modularization - * and minification of CSS class names. - * - * In static_upstream, this function is actually implemented, but it should - * eventually be replaced with something more descriptive, and the transform - * that is used in the main stack should be ported for use elsewhere. - * - * @param string|object className to modularize, or an object of key/values. - * In the object case, the values are conditions that - * determine if the className keys should be included. - * @param [string ...] Variable list of classNames in the string case. - * @return string Renderable space-separated CSS className. - */ - -'use strict'; -var warning = require("./warning"); - -var warned = false; - -function cx(classNames) { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - warned, - 'React.addons.classSet will be deprecated in a future version. See ' + - 'http://fb.me/react-addons-classset' - ) : null); - warned = true; - } - - if (typeof classNames == 'object') { - return Object.keys(classNames).filter(function(className) { - return classNames[className]; - }).join(' '); - } else { - return Array.prototype.join.call(arguments, ' '); - } -} - -module.exports = cx; - }).call(this,require('_process')) -},{"./warning":212,"_process":1}],169:[function(require,module,exports){ +},{"./ReactElement":115,"./ReactPropTransferer":137,"_process":1,"fbjs/lib/keyOf":225,"fbjs/lib/warning":232}],178:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22568,7 +22847,7 @@ module.exports = cx; 'use strict'; -var CSSProperty = require("./CSSProperty"); +var CSSProperty = require('./CSSProperty'); var isUnitlessNumber = CSSProperty.isUnitlessNumber; @@ -22598,8 +22877,7 @@ function dangerousStyleValue(name, value) { } var isNonNumeric = isNaN(value); - if (isNonNumeric || value === 0 || - isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { + if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { return '' + value; // cast to string } @@ -22610,8 +22888,8 @@ function dangerousStyleValue(name, value) { } module.exports = dangerousStyleValue; - -},{"./CSSProperty":45}],170:[function(require,module,exports){ +},{"./CSSProperty":62}],179:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22620,57 +22898,49 @@ module.exports = dangerousStyleValue; * LICENSE file in the 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. + * @providesModule deprecated */ -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; }; +'use strict'; -module.exports = emptyFunction; +var assign = require('./Object.assign'); +var warning = require('fbjs/lib/warning'); -},{}],171:[function(require,module,exports){ -(function (process){ /** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. + * This will log a single deprecation notice per function and forward the call + * on to the new API. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the 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 + * @param {string} fnName The name of the function + * @param {string} newModule The module that fn will exist in + * @param {string} newPackage The module that fn will exist in + * @param {*} ctx The context this forwarded call should run in + * @param {function} fn The function to forward on to + * @return {function} The function that will warn once and then call fn */ +function deprecated(fnName, newModule, newPackage, ctx, fn) { + var warned = false; + if (process.env.NODE_ENV !== 'production') { + var newFn = function () { + process.env.NODE_ENV !== 'production' ? warning(warned, + // Require examples in this string must be split to prevent React's + // build tools from mistaking them for real requires. + // Otherwise the build tools will attempt to build a '%s' module. + 'React.%s is deprecated. Please use %s.%s from require' + '(\'%s\') ' + 'instead.', fnName, newModule, fnName, newPackage) : undefined; + warned = true; + return fn.apply(ctx, arguments); + }; + // 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); + } -"use strict"; - -var emptyObject = {}; - -if ("production" !== process.env.NODE_ENV) { - Object.freeze(emptyObject); + return fn; } -module.exports = emptyObject; - +module.exports = deprecated; }).call(this,require('_process')) -},{"_process":1}],172:[function(require,module,exports){ +},{"./Object.assign":82,"_process":1,"fbjs/lib/warning":232}],180:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22709,8 +22979,7 @@ function escapeTextContentForBrowser(text) { } module.exports = escapeTextContentForBrowser; - -},{}],173:[function(require,module,exports){ +},{}],181:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -22726,65 +22995,44 @@ module.exports = escapeTextContentForBrowser; 'use strict'; -var ReactCurrentOwner = require("./ReactCurrentOwner"); -var ReactInstanceMap = require("./ReactInstanceMap"); -var ReactMount = require("./ReactMount"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactInstanceMap = require('./ReactInstanceMap'); +var ReactMount = require('./ReactMount'); -var invariant = require("./invariant"); -var isNode = require("./isNode"); -var warning = require("./warning"); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); /** * Returns the DOM node rendered by this element. * * @param {ReactComponent|DOMElement} componentOrElement - * @return {DOMElement} The root node of this element. + * @return {?DOMElement} The root node of this element. */ function findDOMNode(componentOrElement) { - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { var owner = ReactCurrentOwner.current; if (owner !== null) { - ("production" !== process.env.NODE_ENV ? warning( - owner._warnedAboutRefsInRender, - '%s is accessing getDOMNode or findDOMNode inside its render(). ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ) : null); + process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing getDOMNode or findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : undefined; owner._warnedAboutRefsInRender = true; } } if (componentOrElement == null) { return null; } - if (isNode(componentOrElement)) { + if (componentOrElement.nodeType === 1) { return componentOrElement; } if (ReactInstanceMap.has(componentOrElement)) { return ReactMount.getNodeFromInstance(componentOrElement); } - ("production" !== process.env.NODE_ENV ? invariant( - componentOrElement.render == null || - typeof componentOrElement.render !== 'function', - 'Component (with keys: %s) contains `render` method ' + - 'but is not mounted in the DOM', - Object.keys(componentOrElement) - ) : invariant(componentOrElement.render == null || - typeof componentOrElement.render !== 'function')); - ("production" !== process.env.NODE_ENV ? invariant( - false, - 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', - Object.keys(componentOrElement) - ) : invariant(false)); + !(componentOrElement.render == null || typeof componentOrElement.render !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : invariant(false) : undefined; + !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : invariant(false) : undefined; } module.exports = findDOMNode; - }).call(this,require('_process')) -},{"./ReactCurrentOwner":85,"./ReactInstanceMap":113,"./ReactMount":117,"./invariant":191,"./isNode":193,"./warning":212,"_process":1}],174:[function(require,module,exports){ +},{"./ReactCurrentOwner":97,"./ReactInstanceMap":126,"./ReactMount":130,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],182:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -22799,8 +23047,8 @@ module.exports = findDOMNode; 'use strict'; -var traverseAllChildren = require("./traverseAllChildren"); -var warning = require("./warning"); +var traverseAllChildren = require('./traverseAllChildren'); +var warning = require('fbjs/lib/warning'); /** * @param {function} traverseContext Context passed through traversal. @@ -22810,15 +23058,9 @@ var warning = require("./warning"); function flattenSingleChildIntoContext(traverseContext, child, name) { // We found a component instance. var result = traverseContext; - var keyUnique = !result.hasOwnProperty(name); - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - keyUnique, - 'flattenChildren(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ) : null); + var keyUnique = result[name] === undefined; + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? 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) : undefined; } if (keyUnique && child != null) { result[name] = child; @@ -22840,39 +23082,9 @@ function flattenChildren(children) { } module.exports = flattenChildren; - }).call(this,require('_process')) -},{"./traverseAllChildren":210,"./warning":212,"_process":1}],175:[function(require,module,exports){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule focusNode - */ - -"use strict"; - -/** - * @param {DOMElement} node input/textarea to focus - */ -function focusNode(node) { - // IE8 can throw "Can't move focus to the control because it is invisible, - // not enabled, or of a type that does not accept the focus." for all kinds of - // reasons that are too expensive and fragile to test. - try { - node.focus(); - } catch(e) { - } -} - -module.exports = focusNode; - -},{}],176:[function(require,module,exports){ +},{"./traverseAllChildren":201,"_process":1,"fbjs/lib/warning":232}],183:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22887,13 +23099,13 @@ module.exports = focusNode; 'use strict'; /** - * @param {array} an "accumulation" of items which is either an Array or + * @param {array} arr 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) { +var forEachAccumulated = function (arr, cb, scope) { if (Array.isArray(arr)) { arr.forEach(cb, scope); } else if (arr) { @@ -22902,37 +23114,7 @@ var forEachAccumulated = function(arr, cb, scope) { }; module.exports = forEachAccumulated; - -},{}],177:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getActiveElement - * @typechecks - */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document body is not yet defined. - */ -function getActiveElement() /*?DOMElement*/ { - try { - return document.activeElement || document.body; - } catch (e) { - return document.body; - } -} - -module.exports = getActiveElement; - -},{}],178:[function(require,module,exports){ +},{}],184:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22955,7 +23137,7 @@ module.exports = getActiveElement; * presumably because it does not produce a tab-character in browsers. * * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `charCode` property. + * @return {number} Normalized `charCode` property. */ function getEventCharCode(nativeEvent) { var charCode; @@ -22983,8 +23165,7 @@ function getEventCharCode(nativeEvent) { } module.exports = getEventCharCode; - -},{}],179:[function(require,module,exports){ +},{}],185:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -22999,7 +23180,7 @@ module.exports = getEventCharCode; 'use strict'; -var getEventCharCode = require("./getEventCharCode"); +var getEventCharCode = require('./getEventCharCode'); /** * Normalization of deprecated HTML5 `key` values @@ -23088,8 +23269,7 @@ function getEventKey(nativeEvent) { } module.exports = getEventKey; - -},{"./getEventCharCode":178}],180:[function(require,module,exports){ +},{"./getEventCharCode":184}],186:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23120,7 +23300,6 @@ var modifierKeyToProp = { // modifier keys exposed by the event itself, does not support Lock-keys. // Currently, all major browsers except Chrome seems to support Lock-keys. function modifierStateGetter(keyArg) { - /*jshint validthis:true */ var syntheticEvent = this; var nativeEvent = syntheticEvent.nativeEvent; if (nativeEvent.getModifierState) { @@ -23135,8 +23314,7 @@ function getEventModifierState(nativeEvent) { } module.exports = getEventModifierState; - -},{}],181:[function(require,module,exports){ +},{}],187:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23166,8 +23344,7 @@ function getEventTarget(nativeEvent) { } module.exports = getEventTarget; - -},{}],182:[function(require,module,exports){ +},{}],188:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23201,137 +23378,14 @@ var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. * @return {?function} */ function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && ( - (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]) - ); + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); if (typeof iteratorFn === 'function') { return iteratorFn; } } module.exports = getIteratorFn; - -},{}],183:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getMarkupWrap - */ - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var invariant = require("./invariant"); - -/** - * Dummy container used to detect which wraps are necessary. - */ -var dummyNode = - ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Some browsers cannot use `innerHTML` to render certain elements standalone, - * so we wrap them, render the wrapped nodes, then extract the desired node. - * - * In IE8, certain elements cannot render alone, so wrap all elements ('*'). - */ -var shouldWrap = { - // Force wrapping for SVG elements because if they get created inside a <div>, - // they will be initialized in the wrong namespace (and will not display). - 'circle': true, - 'clipPath': true, - 'defs': true, - 'ellipse': true, - 'g': true, - 'line': true, - 'linearGradient': true, - 'path': true, - 'polygon': true, - 'polyline': true, - 'radialGradient': true, - 'rect': true, - 'stop': true, - 'text': true -}; - -var selectWrap = [1, '<select multiple="true">', '</select>']; -var tableWrap = [1, '<table>', '</table>']; -var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; - -var svgWrap = [1, '<svg>', '</svg>']; - -var markupWrap = { - '*': [1, '?<div>', '</div>'], - - 'area': [1, '<map>', '</map>'], - 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], - 'legend': [1, '<fieldset>', '</fieldset>'], - 'param': [1, '<object>', '</object>'], - 'tr': [2, '<table><tbody>', '</tbody></table>'], - - 'optgroup': selectWrap, - 'option': selectWrap, - - 'caption': tableWrap, - 'colgroup': tableWrap, - 'tbody': tableWrap, - 'tfoot': tableWrap, - 'thead': tableWrap, - - 'td': trWrap, - 'th': trWrap, - - 'circle': svgWrap, - 'clipPath': svgWrap, - 'defs': svgWrap, - 'ellipse': svgWrap, - 'g': svgWrap, - 'line': svgWrap, - 'linearGradient': svgWrap, - 'path': svgWrap, - 'polygon': svgWrap, - 'polyline': svgWrap, - 'radialGradient': svgWrap, - 'rect': svgWrap, - 'stop': svgWrap, - 'text': svgWrap -}; - -/** - * Gets the markup wrap configuration for the supplied `nodeName`. - * - * NOTE: This lazily detects which wraps are necessary for the current browser. - * - * @param {string} nodeName Lowercase `nodeName`. - * @return {?array} Markup wrap configuration, if applicable. - */ -function getMarkupWrap(nodeName) { - ("production" !== process.env.NODE_ENV ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); - if (!markupWrap.hasOwnProperty(nodeName)) { - nodeName = '*'; - } - if (!shouldWrap.hasOwnProperty(nodeName)) { - if (nodeName === '*') { - dummyNode.innerHTML = '<link />'; - } else { - dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; - } - shouldWrap[nodeName] = !dummyNode.firstChild; - } - return shouldWrap[nodeName] ? markupWrap[nodeName] : null; -} - - -module.exports = getMarkupWrap; - -}).call(this,require('_process')) - -},{"./ExecutionEnvironment":62,"./invariant":191,"_process":1}],184:[function(require,module,exports){ +},{}],189:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23405,43 +23459,7 @@ function getNodeForCharacterOffset(root, offset) { } module.exports = getNodeForCharacterOffset; - -},{}],185:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getReactRootElementInContainer - */ - -'use strict'; - -var DOC_NODE_TYPE = 9; - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -module.exports = getReactRootElementInContainer; - -},{}],186:[function(require,module,exports){ +},{}],190:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23455,7 +23473,7 @@ module.exports = getReactRootElementInContainer; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var contentKey = null; @@ -23469,130 +23487,13 @@ function getTextContentAccessor() { if (!contentKey && ExecutionEnvironment.canUseDOM) { // Prefer textContent to innerText because many browsers support both but // SVG <text> elements don't support innerText even when <div> does. - contentKey = 'textContent' in document.documentElement ? - 'textContent' : - 'innerText'; + contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; } return contentKey; } module.exports = getTextContentAccessor; - -},{"./ExecutionEnvironment":62}],187:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule getUnboundedScrollPosition - * @typechecks - */ - -"use strict"; - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -},{}],188:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenate - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; - -},{}],189:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule hyphenateStyleName - * @typechecks - */ - -"use strict"; - -var hyphenate = require("./hyphenate"); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; - -},{"./hyphenate":188}],190:[function(require,module,exports){ +},{"fbjs/lib/ExecutionEnvironment":206}],191:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -23608,23 +23509,29 @@ module.exports = hyphenateStyleName; 'use strict'; -var ReactCompositeComponent = require("./ReactCompositeComponent"); -var ReactEmptyComponent = require("./ReactEmptyComponent"); -var ReactNativeComponent = require("./ReactNativeComponent"); +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"); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); // To avoid a cyclic dependency, we create the final class in this module -var ReactCompositeComponentWrapper = function() { }; -assign( - ReactCompositeComponentWrapper.prototype, - ReactCompositeComponent.Mixin, - { - _instantiateReactComponent: instantiateReactComponent +var ReactCompositeComponentWrapper = function () {}; +assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent.Mixin, { + _instantiateReactComponent: instantiateReactComponent +}); + +function getDeclarationErrorAddendum(owner) { + if (owner) { + var name = owner.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } } -); + return ''; +} /** * Check if the type reference is a known internal type. I.e. not a user @@ -23634,49 +23541,31 @@ assign( * @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' - ); + 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) { +function instantiateReactComponent(node) { var instance; if (node === null || node === false) { - node = ReactEmptyComponent.emptyElement; - } - - if (typeof node === 'object') { + instance = new ReactEmptyComponent(instantiateReactComponent); + } else if (typeof node === 'object') { var element = node; - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - element && (typeof element.type === 'function' || - typeof element.type === 'string'), - 'Only functions or strings can be mounted as React components.' - ) : null); - } + !(element && (typeof element.type === 'function' || typeof element.type === 'string')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) ' + 'or a class/function (for composite components) but got: %s.%s', element.type == null ? element.type : typeof element.type, getDeclarationErrorAddendum(element._owner)) : invariant(false) : undefined; // Special case string values - if (parentCompositeType === element.type && - typeof element.type === 'string') { - // Avoid recursion if the wrapper renders itself. + if (typeof element.type === 'string') { 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 + // representations. I.e. ART. Once those are updated to use the string // representation, we can drop this code path. instance = new element.type(element); } else { @@ -23685,21 +23574,11 @@ function instantiateReactComponent(node, parentCompositeType) { } else if (typeof node === 'string' || typeof node === 'number') { instance = ReactNativeComponent.createInstanceForText(node); } else { - ("production" !== process.env.NODE_ENV ? invariant( - false, - 'Encountered invalid React node of type %s', - typeof node - ) : invariant(false)); + !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : invariant(false) : undefined; } - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - typeof instance.construct === 'function' && - typeof instance.mountComponent === 'function' && - typeof instance.receiveComponent === 'function' && - typeof instance.unmountComponent === 'function', - 'Only React Components can be mounted.' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning(typeof instance.construct === 'function' && typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : undefined; } // Sets up the instance. This can probably just move into the constructor now. @@ -23711,14 +23590,14 @@ function instantiateReactComponent(node, parentCompositeType) { instance._mountIndex = 0; instance._mountImage = null; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { instance._isOwnerNecessary = false; instance._warnedAboutRefsInRender = false; } // Internal instances should fully constructed at this point, so they should // not get any new fields added to them at this point. - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { if (Object.preventExtensions) { Object.preventExtensions(instance); } @@ -23728,68 +23607,9 @@ function instantiateReactComponent(node, parentCompositeType) { } module.exports = instantiateReactComponent; - -}).call(this,require('_process')) - -},{"./Object.assign":69,"./ReactCompositeComponent":83,"./ReactEmptyComponent":105,"./ReactNativeComponent":120,"./invariant":191,"./warning":212,"_process":1}],191:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule invariant - */ - -"use strict"; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if ("production" !== process.env.NODE_ENV) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - }).call(this,require('_process')) -},{"_process":1}],192:[function(require,module,exports){ +},{"./Object.assign":82,"./ReactCompositeComponent":96,"./ReactEmptyComponent":117,"./ReactNativeComponent":133,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],192:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23803,16 +23623,14 @@ module.exports = invariant; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var useHasFeature; if (ExecutionEnvironment.canUseDOM) { - useHasFeature = - document.implementation && - document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; + useHasFeature = document.implementation && document.implementation.hasFeature && + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + document.implementation.hasFeature('', '') !== true; } /** @@ -23830,13 +23648,12 @@ if (ExecutionEnvironment.canUseDOM) { * @license Modernizr 3.0.0pre (Custom Build) | MIT */ function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || - capture && !('addEventListener' in document)) { + if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { return false; } var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; + var isSupported = (eventName in document); if (!isSupported) { var element = document.createElement('div'); @@ -23853,35 +23670,7 @@ function isEventSupported(eventNameSuffix, capture) { } module.exports = isEventSupported; - -},{"./ExecutionEnvironment":62}],193:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule 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; - -},{}],194:[function(require,module,exports){ +},{"fbjs/lib/ExecutionEnvironment":206}],193:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -23917,258 +23706,12 @@ var supportedInputTypes = { }; function isTextInputElement(elem) { - return elem && ( - (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type] || elem.nodeName === 'TEXTAREA') - ); + var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); + return nodeName && (nodeName === 'input' && supportedInputTypes[elem.type] || nodeName === 'textarea'); } module.exports = isTextInputElement; - -},{}],195:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule isTextNode - * @typechecks - */ - -var isNode = require("./isNode"); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; - -},{"./isNode":193}],196:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule joinClasses - * @typechecks static-only - */ - -'use strict'; - -/** - * Combines multiple className strings into one. - * http://jsperf.com/joinclasses-args-vs-array - * - * @param {...?string} classes - * @return {string} - */ -function joinClasses(className/*, ... */) { - if (!className) { - className = ''; - } - var nextClass; - var argLength = arguments.length; - if (argLength > 1) { - for (var ii = 1; ii < argLength; ii++) { - nextClass = arguments[ii]; - if (nextClass) { - className = (className ? className + ' ' : '') + nextClass; - } - } - } - return className; -} - -module.exports = joinClasses; - -},{}],197:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule keyMirror - * @typechecks static-only - */ - -'use strict'; - -var invariant = require("./invariant"); - -/** - * Constructs an enumeration with keys equal to their value. - * - * For example: - * - * var COLORS = keyMirror({blue: null, red: null}); - * var myColor = COLORS.blue; - * var isColorValid = !!COLORS[myColor]; - * - * The last line could not be performed if the values of the generated enum were - * not equal to their keys. - * - * Input: {key1: val1, key2: val2} - * Output: {key1: key1, key2: key2} - * - * @param {object} obj - * @return {object} - */ -var keyMirror = function(obj) { - var ret = {}; - var key; - ("production" !== process.env.NODE_ENV ? invariant( - obj instanceof Object && !Array.isArray(obj), - 'keyMirror(...): Argument must be an object.' - ) : invariant(obj instanceof Object && !Array.isArray(obj))); - for (key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - ret[key] = key; - } - return ret; -}; - -module.exports = keyMirror; - -}).call(this,require('_process')) - -},{"./invariant":191,"_process":1}],198:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule 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; - -},{}],199:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule 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; - -},{}],200:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule memoizeStringOnly - * @typechecks static-only - */ - -'use strict'; - -/** - * Memoizes the return value of a function that accepts one string argument. - * - * @param {function} callback - * @return {function} - */ -function memoizeStringOnly(callback) { - var cache = {}; - return function(string) { - if (!cache.hasOwnProperty(string)) { - cache[string] = callback.call(this, string); - } - return cache[string]; - }; -} - -module.exports = memoizeStringOnly; - -},{}],201:[function(require,module,exports){ +},{}],194:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -24182,9 +23725,9 @@ module.exports = memoizeStringOnly; */ 'use strict'; -var ReactElement = require("./ReactElement"); +var ReactElement = require('./ReactElement'); -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); /** * Returns the first child in a collection of children and verifies that there @@ -24198,18 +23741,14 @@ var invariant = require("./invariant"); * structure. */ function onlyChild(children) { - ("production" !== process.env.NODE_ENV ? invariant( - ReactElement.isValidElement(children), - 'onlyChild must be passed a children with exactly one child.' - ) : invariant(ReactElement.isValidElement(children))); + !ReactElement.isValidElement(children) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'onlyChild must be passed a children with exactly one child.') : invariant(false) : undefined; return children; } module.exports = onlyChild; - }).call(this,require('_process')) -},{"./ReactElement":103,"./invariant":191,"_process":1}],202:[function(require,module,exports){ +},{"./ReactElement":115,"_process":1,"fbjs/lib/invariant":220}],195:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24218,54 +23757,25 @@ module.exports = onlyChild; * LICENSE file in the 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 + * @providesModule quoteAttributeValueForBrowser */ -"use strict"; - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = - window.performance || - window.msPerformance || - window.webkitPerformance; -} +'use strict'; -module.exports = performance || {}; +var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); -},{"./ExecutionEnvironment":62}],203:[function(require,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * Escapes attribute value to prevent scripting attacks. * - * @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. + * @param {*} value Value to escape. + * @return {string} An escaped string. */ -if (!performance || !performance.now) { - performance = Date; +function quoteAttributeValueForBrowser(value) { + return '"' + escapeTextContentForBrowser(value) + '"'; } -var performanceNow = performance.now.bind(performance); - -module.exports = performanceNow; - -},{"./performance":202}],204:[function(require,module,exports){ +module.exports = quoteAttributeValueForBrowser; +},{"./escapeTextContentForBrowser":180}],196:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24274,26 +23784,15 @@ module.exports = performanceNow; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule quoteAttributeValueForBrowser - */ +* @providesModule renderSubtreeIntoContainer +*/ 'use strict'; -var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); - -/** - * Escapes attribute value to prevent scripting attacks. - * - * @param {*} value Value to escape. - * @return {string} An escaped string. - */ -function quoteAttributeValueForBrowser(value) { - return '"' + escapeTextContentForBrowser(value) + '"'; -} - -module.exports = quoteAttributeValueForBrowser; +var ReactMount = require('./ReactMount'); -},{"./escapeTextContentForBrowser":172}],205:[function(require,module,exports){ +module.exports = ReactMount.renderSubtreeIntoContainer; +},{"./ReactMount":130}],197:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24309,7 +23808,7 @@ module.exports = quoteAttributeValueForBrowser; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var WHITESPACE_TEST = /^[ \r\n\t\f]/; var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; @@ -24322,14 +23821,14 @@ var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; * @param {string} html * @internal */ -var setInnerHTML = function(node, html) { +var setInnerHTML = function (node, html) { node.innerHTML = html; }; // Win8 apps: Allow all html to be inserted if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - setInnerHTML = function(node, html) { - MSApp.execUnsafeLocalFunction(function() { + setInnerHTML = function (node, html) { + MSApp.execUnsafeLocalFunction(function () { node.innerHTML = html; }); }; @@ -24345,7 +23844,7 @@ if (ExecutionEnvironment.canUseDOM) { var testElement = document.createElement('div'); testElement.innerHTML = ' '; if (testElement.innerHTML === '') { - setInnerHTML = function(node, html) { + setInnerHTML = function (node, html) { // Magic theory: IE8 supposedly differentiates between added and updated // nodes when processing innerHTML, innerHTML on updated nodes suffers // from worse whitespace behavior. Re-adding a node like this triggers @@ -24359,11 +23858,14 @@ if (ExecutionEnvironment.canUseDOM) { // thin air on IE8, this only happens if there is no visible text // in-front of the non-visible tags. Piggyback on the whitespace fix // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || - html[0] === '<' && NONVISIBLE_TEST.test(html)) { + if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) { // Recover leading whitespace by temporarily prepending any character. // \uFEFF has the potential advantage of being zero-width/invisible. - node.innerHTML = '\uFEFF' + html; + // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode + // in hopes that this is preserved even if "\uFEFF" is transformed to + // the actual Unicode character (by Babel, for example). + // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216 + node.innerHTML = String.fromCharCode(0xFEFF) + html; // deleteData leaves an empty `TextNode` which offsets the index of all // children. Definitely want to avoid this. @@ -24381,8 +23883,7 @@ if (ExecutionEnvironment.canUseDOM) { } module.exports = setInnerHTML; - -},{"./ExecutionEnvironment":62}],206:[function(require,module,exports){ +},{"fbjs/lib/ExecutionEnvironment":206}],198:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24396,9 +23897,9 @@ module.exports = setInnerHTML; 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); -var setInnerHTML = require("./setInnerHTML"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); +var setInnerHTML = require('./setInnerHTML'); /** * Set the textContent property of a node, ensuring that whitespace is preserved @@ -24410,21 +23911,20 @@ var setInnerHTML = require("./setInnerHTML"); * @param {string} text * @internal */ -var setTextContent = function(node, text) { +var setTextContent = function (node, text) { node.textContent = text; }; if (ExecutionEnvironment.canUseDOM) { if (!('textContent' in document.documentElement)) { - setTextContent = function(node, text) { + setTextContent = function (node, text) { setInnerHTML(node, escapeTextContentForBrowser(text)); }; } } module.exports = setTextContent; - -},{"./ExecutionEnvironment":62,"./escapeTextContentForBrowser":172,"./setInnerHTML":205}],207:[function(require,module,exports){ +},{"./escapeTextContentForBrowser":180,"./setInnerHTML":197,"fbjs/lib/ExecutionEnvironment":206}],199:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24433,43 +23933,23 @@ module.exports = setTextContent; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule shallowEqual - */ +* @providesModule shallowCompare +*/ 'use strict'; +var shallowEqual = require('fbjs/lib/shallowEqual'); + /** - * Performs equality by iterating through keys on an object and returning - * false when any key has values which are not strictly equal between - * objA and objB. Returns true when the values of all keys are strictly equal. - * - * @return {boolean} + * Does a shallow comparison for props and state. + * See ReactComponentWithPureRenderMixin */ -function shallowEqual(objA, objB) { - if (objA === objB) { - return true; - } - var key; - // Test for A's keys different from B. - for (key in objA) { - if (objA.hasOwnProperty(key) && - (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { - return false; - } - } - // Test for B's keys missing from A. - for (key in objB) { - if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { - return false; - } - } - return true; +function shallowCompare(instance, nextProps, nextState) { + return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState); } -module.exports = shallowEqual; - -},{}],208:[function(require,module,exports){ -(function (process){ +module.exports = shallowCompare; +},{"fbjs/lib/shallowEqual":230}],200:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -24484,8 +23964,6 @@ module.exports = shallowEqual; '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 @@ -24498,155 +23976,24 @@ var warning = require("./warning"); * @protected */ function shouldUpdateReactComponent(prevElement, nextElement) { - if (prevElement != null && nextElement != null) { - var prevType = typeof prevElement; - var nextType = typeof nextElement; - if (prevType === 'string' || prevType === 'number') { - return (nextType === 'string' || nextType === 'number'); - } else { - if (nextType === 'object' && - prevElement.type === nextElement.type && - prevElement.key === nextElement.key) { - var ownersMatch = prevElement._owner === nextElement._owner; - var prevName = null; - var nextName = null; - var nextDisplayName = null; - if ("production" !== process.env.NODE_ENV) { - if (!ownersMatch) { - if (prevElement._owner != null && - prevElement._owner.getPublicInstance() != null && - prevElement._owner.getPublicInstance().constructor != null) { - prevName = - prevElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement._owner != null && - nextElement._owner.getPublicInstance() != null && - nextElement._owner.getPublicInstance().constructor != null) { - nextName = - nextElement._owner.getPublicInstance().constructor.displayName; - } - if (nextElement.type != null && - nextElement.type.displayName != null) { - nextDisplayName = nextElement.type.displayName; - } - if (nextElement.type != null && typeof nextElement.type === 'string') { - nextDisplayName = nextElement.type; - } - if (typeof nextElement.type !== 'string' || - nextElement.type === 'input' || - nextElement.type === 'textarea') { - if ((prevElement._owner != null && - prevElement._owner._isOwnerNecessary === false) || - (nextElement._owner != null && - nextElement._owner._isOwnerNecessary === false)) { - if (prevElement._owner != null) { - prevElement._owner._isOwnerNecessary = true; - } - if (nextElement._owner != null) { - nextElement._owner._isOwnerNecessary = true; - } - ("production" !== process.env.NODE_ENV ? warning( - false, - '<%s /> is being rendered by both %s and %s using the same ' + - 'key (%s) in the same place. Currently, this means that ' + - 'they don\'t preserve state. This behavior should be very ' + - 'rare so we\'re considering deprecating it. Please contact ' + - 'the React team and explain your use case so that we can ' + - 'take that into consideration.', - nextDisplayName || 'Unknown Component', - prevName || '[Unknown]', - nextName || '[Unknown]', - prevElement.key - ) : null); - } - } - } - } - return ownersMatch; - } - } - } - return false; -} - -module.exports = shouldUpdateReactComponent; - -}).call(this,require('_process')) - -},{"./warning":212,"_process":1}],209:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule toArray - * @typechecks - */ - -var invariant = require("./invariant"); - -/** - * Convert array-like objects to arrays. - * - * This API assumes the caller knows the contents of the data type. For less - * well defined inputs use createArrayFromMixed. - * - * @param {object|function|filelist} obj - * @return {array} - */ -function toArray(obj) { - var length = obj.length; - - // Some browse builtin objects can report typeof 'function' (e.g. NodeList in - // old versions of Safari). - ("production" !== process.env.NODE_ENV ? invariant( - !Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'), - 'toArray: Array-like object expected' - ) : invariant(!Array.isArray(obj) && - (typeof obj === 'object' || typeof obj === 'function'))); - - ("production" !== process.env.NODE_ENV ? invariant( - typeof length === 'number', - 'toArray: Object needs a length property' - ) : invariant(typeof length === 'number')); - - ("production" !== process.env.NODE_ENV ? invariant( - length === 0 || - (length - 1) in obj, - 'toArray: Object should have keys for indices' - ) : invariant(length === 0 || - (length - 1) in obj)); - - // Old IE doesn't give collections access to hasOwnProperty. Assume inputs - // without method will throw during the slice call and skip straight to the - // fallback. - if (obj.hasOwnProperty) { - try { - return Array.prototype.slice.call(obj); - } catch (e) { - // IE < 9 does not support Array#slice on collections objects - } + var prevEmpty = prevElement === null || prevElement === false; + var nextEmpty = nextElement === null || nextElement === false; + if (prevEmpty || nextEmpty) { + return prevEmpty === nextEmpty; } - // Fall back to copying key by key. This assumes all keys have a value, - // so will not preserve sparsely populated inputs. - var ret = Array(length); - for (var ii = 0; ii < length; ii++) { - ret[ii] = obj[ii]; + var prevType = typeof prevElement; + var nextType = typeof nextElement; + if (prevType === 'string' || prevType === 'number') { + return nextType === 'string' || nextType === 'number'; + } else { + return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key; } - return ret; + return false; } -module.exports = toArray; - -}).call(this,require('_process')) - -},{"./invariant":191,"_process":1}],210:[function(require,module,exports){ +module.exports = shouldUpdateReactComponent; +},{}],201:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -24661,13 +24008,13 @@ module.exports = toArray; 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactFragment = require("./ReactFragment"); -var ReactInstanceHandles = require("./ReactInstanceHandles"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactElement = require('./ReactElement'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); -var getIteratorFn = require("./getIteratorFn"); -var invariant = require("./invariant"); -var warning = require("./warning"); +var getIteratorFn = require('./getIteratorFn'); +var invariant = require('fbjs/lib/invariant'); +var warning = require('fbjs/lib/warning'); var SEPARATOR = ReactInstanceHandles.SEPARATOR; var SUBSEPARATOR = ':'; @@ -24710,14 +24057,11 @@ function getComponentKey(component, index) { /** * Escape a component key so that it is safe to use in a reactid. * - * @param {*} key Component key to be escaped. + * @param {*} text Component key to be escaped. * @return {string} An escaped string. */ function escapeUserProvidedKey(text) { - return ('' + text).replace( - userProvidedKeyEscapeRegex, - userProvidedKeyEscaper - ); + return ('' + text).replace(userProvidedKeyEscapeRegex, userProvidedKeyEscaper); } /** @@ -24734,19 +24078,12 @@ function wrapUserProvidedKey(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 -) { +function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { var type = typeof children; if (type === 'undefined' || type === 'boolean') { @@ -24754,39 +24091,24 @@ function traverseAllChildrenImpl( 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 - ); + 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); return 1; } - var child, nextName, nextIndex; + var child; + var nextName; var subtreeCount = 0; // Count of children found in the current subtree. + var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; 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 - ); + nextName = nextNamePrefix + getComponentKey(child, i); + subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); } } else { var iteratorFn = getIteratorFn(children); @@ -24797,27 +24119,12 @@ function traverseAllChildrenImpl( 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 - ); + nextName = nextNamePrefix + getComponentKey(child, ii++); + subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); } } else { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - didWarnAboutMaps, - 'Using Maps as children is not yet fully supported. It is an ' + - 'experimental feature that might be removed. Convert it to a ' + - 'sequence / iterable of keyed ReactElements instead.' - ) : null); + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? 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.') : undefined; didWarnAboutMaps = true; } // Iterator will provide entry [k,v] tuples rather than values. @@ -24825,47 +24132,27 @@ function traverseAllChildrenImpl( 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 - ); + nextName = nextNamePrefix + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); + subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); } } } } else if (type === 'object') { - ("production" !== process.env.NODE_ENV ? invariant( - children.nodeType !== 1, - 'traverseAllChildren(...): Encountered an invalid child; DOM ' + - 'elements are not valid children of React components.' - ) : invariant(children.nodeType !== 1)); - var fragment = ReactFragment.extract(children); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - child = fragment[key]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(key) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); + var addendum = ''; + if (process.env.NODE_ENV !== 'production') { + addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; + if (children._isReactElement) { + addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; + } + if (ReactCurrentOwner.current) { + var name = ReactCurrentOwner.current.getName(); + if (name) { + addendum += ' Check the render method of `' + name + '`.'; + } } } + var childrenString = String(children); + !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : invariant(false) : undefined; } } @@ -24893,14 +24180,13 @@ function traverseAllChildren(children, callback, traverseContext) { return 0; } - return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); + return traverseAllChildrenImpl(children, '', callback, traverseContext); } module.exports = traverseAllChildren; - }).call(this,require('_process')) -},{"./ReactElement":103,"./ReactFragment":109,"./ReactInstanceHandles":112,"./getIteratorFn":182,"./invariant":191,"./warning":212,"_process":1}],211:[function(require,module,exports){ +},{"./ReactCurrentOwner":97,"./ReactElement":115,"./ReactInstanceHandles":125,"./getIteratorFn":188,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/warning":232}],202:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -24913,14 +24199,14 @@ module.exports = traverseAllChildren; * @providesModule update */ - /* global hasOwnProperty:true */ +/* global hasOwnProperty:true */ 'use strict'; -var assign = require("./Object.assign"); -var keyOf = require("./keyOf"); -var invariant = require("./invariant"); -var hasOwnProperty = {}.hasOwnProperty; +var assign = require('./Object.assign'); +var keyOf = require('fbjs/lib/keyOf'); +var invariant = require('fbjs/lib/invariant'); +var hasOwnProperty = ({}).hasOwnProperty; function shallowCopy(x) { if (Array.isArray(x)) { @@ -24932,60 +24218,32 @@ function shallowCopy(x) { } } -var COMMAND_PUSH = keyOf({$push: null}); -var COMMAND_UNSHIFT = keyOf({$unshift: null}); -var COMMAND_SPLICE = keyOf({$splice: null}); -var COMMAND_SET = keyOf({$set: null}); -var COMMAND_MERGE = keyOf({$merge: null}); -var COMMAND_APPLY = keyOf({$apply: null}); +var COMMAND_PUSH = keyOf({ $push: null }); +var COMMAND_UNSHIFT = keyOf({ $unshift: null }); +var COMMAND_SPLICE = keyOf({ $splice: null }); +var COMMAND_SET = keyOf({ $set: null }); +var COMMAND_MERGE = keyOf({ $merge: null }); +var COMMAND_APPLY = keyOf({ $apply: null }); -var ALL_COMMANDS_LIST = [ - COMMAND_PUSH, - COMMAND_UNSHIFT, - COMMAND_SPLICE, - COMMAND_SET, - COMMAND_MERGE, - COMMAND_APPLY -]; +var ALL_COMMANDS_LIST = [COMMAND_PUSH, COMMAND_UNSHIFT, COMMAND_SPLICE, COMMAND_SET, COMMAND_MERGE, COMMAND_APPLY]; var ALL_COMMANDS_SET = {}; -ALL_COMMANDS_LIST.forEach(function(command) { +ALL_COMMANDS_LIST.forEach(function (command) { ALL_COMMANDS_SET[command] = true; }); function invariantArrayCase(value, spec, command) { - ("production" !== process.env.NODE_ENV ? invariant( - Array.isArray(value), - 'update(): expected target of %s to be an array; got %s.', - command, - value - ) : invariant(Array.isArray(value))); + !Array.isArray(value) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): expected target of %s to be an array; got %s.', command, value) : invariant(false) : undefined; var specValue = spec[command]; - ("production" !== process.env.NODE_ENV ? invariant( - Array.isArray(specValue), - 'update(): expected spec of %s to be an array; got %s. ' + - 'Did you forget to wrap your parameter in an array?', - command, - specValue - ) : invariant(Array.isArray(specValue))); + !Array.isArray(specValue) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): expected spec of %s to be an array; got %s. ' + 'Did you forget to wrap your parameter in an array?', command, specValue) : invariant(false) : undefined; } function update(value, spec) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof spec === 'object', - 'update(): You provided a key path to update() that did not contain one ' + - 'of %s. Did you forget to include {%s: ...}?', - ALL_COMMANDS_LIST.join(', '), - COMMAND_SET - ) : invariant(typeof spec === 'object')); + !(typeof spec === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): You provided a key path to update() that did not contain one ' + 'of %s. Did you forget to include {%s: ...}?', ALL_COMMANDS_LIST.join(', '), COMMAND_SET) : invariant(false) : undefined; if (hasOwnProperty.call(spec, COMMAND_SET)) { - ("production" !== process.env.NODE_ENV ? invariant( - Object.keys(spec).length === 1, - 'Cannot have more than one key in an object with %s', - COMMAND_SET - ) : invariant(Object.keys(spec).length === 1)); + !(Object.keys(spec).length === 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot have more than one key in an object with %s', COMMAND_SET) : invariant(false) : undefined; return spec[COMMAND_SET]; } @@ -24994,68 +24252,36 @@ function update(value, spec) { if (hasOwnProperty.call(spec, COMMAND_MERGE)) { var mergeObj = spec[COMMAND_MERGE]; - ("production" !== process.env.NODE_ENV ? invariant( - mergeObj && typeof mergeObj === 'object', - 'update(): %s expects a spec of type \'object\'; got %s', - COMMAND_MERGE, - mergeObj - ) : invariant(mergeObj && typeof mergeObj === 'object')); - ("production" !== process.env.NODE_ENV ? invariant( - nextValue && typeof nextValue === 'object', - 'update(): %s expects a target of type \'object\'; got %s', - COMMAND_MERGE, - nextValue - ) : invariant(nextValue && typeof nextValue === 'object')); + !(mergeObj && typeof mergeObj === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): %s expects a spec of type \'object\'; got %s', COMMAND_MERGE, mergeObj) : invariant(false) : undefined; + !(nextValue && typeof nextValue === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): %s expects a target of type \'object\'; got %s', COMMAND_MERGE, nextValue) : invariant(false) : undefined; assign(nextValue, spec[COMMAND_MERGE]); } if (hasOwnProperty.call(spec, COMMAND_PUSH)) { invariantArrayCase(value, spec, COMMAND_PUSH); - spec[COMMAND_PUSH].forEach(function(item) { + spec[COMMAND_PUSH].forEach(function (item) { nextValue.push(item); }); } if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) { invariantArrayCase(value, spec, COMMAND_UNSHIFT); - spec[COMMAND_UNSHIFT].forEach(function(item) { + spec[COMMAND_UNSHIFT].forEach(function (item) { nextValue.unshift(item); }); } if (hasOwnProperty.call(spec, COMMAND_SPLICE)) { - ("production" !== process.env.NODE_ENV ? invariant( - Array.isArray(value), - 'Expected %s target to be an array; got %s', - COMMAND_SPLICE, - value - ) : invariant(Array.isArray(value))); - ("production" !== process.env.NODE_ENV ? invariant( - Array.isArray(spec[COMMAND_SPLICE]), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ) : invariant(Array.isArray(spec[COMMAND_SPLICE]))); - spec[COMMAND_SPLICE].forEach(function(args) { - ("production" !== process.env.NODE_ENV ? invariant( - Array.isArray(args), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ) : invariant(Array.isArray(args))); + !Array.isArray(value) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s target to be an array; got %s', COMMAND_SPLICE, value) : invariant(false) : undefined; + !Array.isArray(spec[COMMAND_SPLICE]) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(false) : undefined; + spec[COMMAND_SPLICE].forEach(function (args) { + !Array.isArray(args) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(false) : undefined; nextValue.splice.apply(nextValue, args); }); } if (hasOwnProperty.call(spec, COMMAND_APPLY)) { - ("production" !== process.env.NODE_ENV ? invariant( - typeof spec[COMMAND_APPLY] === 'function', - 'update(): expected spec of %s to be a function; got %s.', - COMMAND_APPLY, - spec[COMMAND_APPLY] - ) : invariant(typeof spec[COMMAND_APPLY] === 'function')); + !(typeof spec[COMMAND_APPLY] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'update(): expected spec of %s to be a function; got %s.', COMMAND_APPLY, spec[COMMAND_APPLY]) : invariant(false) : undefined; nextValue = spec[COMMAND_APPLY](nextValue); } @@ -25069,10 +24295,1731 @@ function update(value, spec) { } module.exports = update; +}).call(this,require('_process')) + +},{"./Object.assign":82,"_process":1,"fbjs/lib/invariant":220,"fbjs/lib/keyOf":225}],203:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule validateDOMNesting + */ + +'use strict'; + +var assign = require('./Object.assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var warning = require('fbjs/lib/warning'); + +var validateDOMNesting = emptyFunction; + +if (process.env.NODE_ENV !== 'production') { + // This validation code was written based on the HTML5 parsing spec: + // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope + // + // Note: this does not catch all invalid nesting, nor does it try to (as it's + // not clear what practical benefit doing so provides); instead, we warn only + // for cases where the parser will give a parse tree differing from what React + // intended. For example, <b><div></div></b> is invalid but we don't warn + // because it still parses correctly; we do warn for other cases like nested + // <p> tags where the beginning of the second element implicitly closes the + // first, causing a confusing mess. + + // https://html.spec.whatwg.org/multipage/syntax.html#special + var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; + + // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope + var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', + + // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point + // TODO: Distinguish by namespace here -- for <title>, including it here + // errs on the side of fewer warnings + 'foreignObject', 'desc', 'title']; + + // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope + var buttonScopeTags = inScopeTags.concat(['button']); + + // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags + var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; + + var emptyAncestorInfo = { + parentTag: null, + + formTag: null, + aTagInScope: null, + buttonTagInScope: null, + nobrTagInScope: null, + pTagInButtonScope: null, + + listItemTagAutoclosing: null, + dlItemTagAutoclosing: null + }; + + var updatedAncestorInfo = function (oldInfo, tag, instance) { + var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo); + var info = { tag: tag, instance: instance }; + + if (inScopeTags.indexOf(tag) !== -1) { + ancestorInfo.aTagInScope = null; + ancestorInfo.buttonTagInScope = null; + ancestorInfo.nobrTagInScope = null; + } + if (buttonScopeTags.indexOf(tag) !== -1) { + ancestorInfo.pTagInButtonScope = null; + } + + // See rules for 'li', 'dd', 'dt' start tags in + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody + if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { + ancestorInfo.listItemTagAutoclosing = null; + ancestorInfo.dlItemTagAutoclosing = null; + } + + ancestorInfo.parentTag = info; + + if (tag === 'form') { + ancestorInfo.formTag = info; + } + if (tag === 'a') { + ancestorInfo.aTagInScope = info; + } + if (tag === 'button') { + ancestorInfo.buttonTagInScope = info; + } + if (tag === 'nobr') { + ancestorInfo.nobrTagInScope = info; + } + if (tag === 'p') { + ancestorInfo.pTagInButtonScope = info; + } + if (tag === 'li') { + ancestorInfo.listItemTagAutoclosing = info; + } + if (tag === 'dd' || tag === 'dt') { + ancestorInfo.dlItemTagAutoclosing = info; + } + + return ancestorInfo; + }; + + /** + * Returns whether + */ + var isTagValidWithParent = function (tag, parentTag) { + // First, let's check if we're in an unusual parsing mode... + switch (parentTag) { + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect + case 'select': + return tag === 'option' || tag === 'optgroup' || tag === '#text'; + case 'optgroup': + return tag === 'option' || tag === '#text'; + // Strictly speaking, seeing an <option> doesn't mean we're in a <select> + // but + case 'option': + return tag === '#text'; + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption + // No special behavior since these rules fall back to "in body" mode for + // all except special table nodes which cause bad parsing behavior anyway. + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr + case 'tr': + return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody + case 'tbody': + case 'thead': + case 'tfoot': + return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup + case 'colgroup': + return tag === 'col' || tag === 'template'; + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable + case 'table': + return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; + + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead + case 'head': + return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; + + // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element + case 'html': + return tag === 'head' || tag === 'body'; + } + + // Probably in the "in body" parsing mode, so we outlaw only tag combos + // where the parsing rules cause implicit opens or closes to be added. + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody + switch (tag) { + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; + + case 'rp': + case 'rt': + return impliedEndTags.indexOf(parentTag) === -1; + + case 'caption': + case 'col': + case 'colgroup': + case 'frame': + case 'head': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // These tags are only valid with a few parents that have special child + // parsing rules -- if we're down here, then none of those matched and + // so we allow it only if we don't know what the parent is, as all other + // cases are invalid. + return parentTag == null; + } + + return true; + }; + + /** + * Returns whether + */ + var findInvalidAncestorForTag = function (tag, ancestorInfo) { + switch (tag) { + case 'address': + case 'article': + case 'aside': + case 'blockquote': + case 'center': + case 'details': + case 'dialog': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'figcaption': + case 'figure': + case 'footer': + case 'header': + case 'hgroup': + case 'main': + case 'menu': + case 'nav': + case 'ol': + case 'p': + case 'section': + case 'summary': + case 'ul': + + case 'pre': + case 'listing': + + case 'table': + + case 'hr': + + case 'xmp': + + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + return ancestorInfo.pTagInButtonScope; + + case 'form': + return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; + + case 'li': + return ancestorInfo.listItemTagAutoclosing; + + case 'dd': + case 'dt': + return ancestorInfo.dlItemTagAutoclosing; + + case 'button': + return ancestorInfo.buttonTagInScope; + + case 'a': + // Spec says something about storing a list of markers, but it sounds + // equivalent to this check. + return ancestorInfo.aTagInScope; + + case 'nobr': + return ancestorInfo.nobrTagInScope; + } + + return null; + }; + + /** + * Given a ReactCompositeComponent instance, return a list of its recursive + * owners, starting at the root and ending with the instance itself. + */ + var findOwnerStack = function (instance) { + if (!instance) { + return []; + } + + var stack = []; + /*eslint-disable space-after-keywords */ + do { + /*eslint-enable space-after-keywords */ + stack.push(instance); + } while (instance = instance._currentElement._owner); + stack.reverse(); + return stack; + }; + + var didWarn = {}; + + validateDOMNesting = function (childTag, childInstance, ancestorInfo) { + ancestorInfo = ancestorInfo || emptyAncestorInfo; + var parentInfo = ancestorInfo.parentTag; + var parentTag = parentInfo && parentInfo.tag; + + var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; + var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); + var problematic = invalidParent || invalidAncestor; + + if (problematic) { + var ancestorTag = problematic.tag; + var ancestorInstance = problematic.instance; + + var childOwner = childInstance && childInstance._currentElement._owner; + var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner; + + var childOwners = findOwnerStack(childOwner); + var ancestorOwners = findOwnerStack(ancestorOwner); + + var minStackLen = Math.min(childOwners.length, ancestorOwners.length); + var i; + + var deepestCommon = -1; + for (i = 0; i < minStackLen; i++) { + if (childOwners[i] === ancestorOwners[i]) { + deepestCommon = i; + } else { + break; + } + } + + var UNKNOWN = '(unknown)'; + var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) { + return inst.getName() || UNKNOWN; + }); + var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) { + return inst.getName() || UNKNOWN; + }); + var ownerInfo = [].concat( + // If the parent and child instances have a common owner ancestor, start + // with that -- otherwise we just start with the parent's owners. + deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag, + // If we're warning about an invalid (non-parent) ancestry, add '...' + invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > '); + + var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo; + if (didWarn[warnKey]) { + return; + } + didWarn[warnKey] = true; + + if (invalidParent) { + var info = ''; + if (ancestorTag === 'table' && childTag === 'tr') { + info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; + } + process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a child of <%s>. ' + 'See %s.%s', childTag, ancestorTag, ownerInfo, info) : undefined; + } else { + process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a descendant of ' + '<%s>. See %s.', childTag, ancestorTag, ownerInfo) : undefined; + } + } + }; + + validateDOMNesting.ancestorInfoContextKey = '__validateDOMNesting_ancestorInfo$' + Math.random().toString(36).slice(2); + + validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo; + + // For testing + validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) { + ancestorInfo = ancestorInfo || emptyAncestorInfo; + var parentInfo = ancestorInfo.parentTag; + var parentTag = parentInfo && parentInfo.tag; + return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo); + }; +} + +module.exports = validateDOMNesting; +}).call(this,require('_process')) + +},{"./Object.assign":82,"_process":1,"fbjs/lib/emptyFunction":212,"fbjs/lib/warning":232}],204:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSCore + * @typechecks + */ + +'use strict'; + +var invariant = require('./invariant'); + +/** + * The CSSCore module specifies the API (and implements most of the methods) + * that should be used when dealing with the display of elements (via their + * CSS classes and visibility on screen. It is an API focused on mutating the + * display and not reading it as no logical state should be encoded in the + * display of elements. + */ + +var CSSCore = { + + /** + * Adds the class passed in to the element if it doesn't already have it. + * + * @param {DOMElement} element the element to set the class on + * @param {string} className the CSS className + * @return {DOMElement} the element passed in + */ + addClass: function (element, className) { + !!/\s/.test(className) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'CSSCore.addClass takes only a single class name. "%s" contains ' + 'multiple classes.', className) : invariant(false) : undefined; + + if (className) { + if (element.classList) { + element.classList.add(className); + } else if (!CSSCore.hasClass(element, className)) { + element.className = element.className + ' ' + className; + } + } + return element; + }, + + /** + * Removes the class passed in from the element + * + * @param {DOMElement} element the element to set the class on + * @param {string} className the CSS className + * @return {DOMElement} the element passed in + */ + removeClass: function (element, className) { + !!/\s/.test(className) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 'multiple classes.', className) : invariant(false) : undefined; + + if (className) { + if (element.classList) { + element.classList.remove(className); + } else if (CSSCore.hasClass(element, className)) { + element.className = element.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1').replace(/\s+/g, ' ') // multiple spaces to one + .replace(/^\s*|\s*$/g, ''); // trim the ends + } + } + return element; + }, + + /** + * Helper to add or remove a class from an element based on a condition. + * + * @param {DOMElement} element the element to set the class on + * @param {string} className the CSS className + * @param {*} bool condition to whether to add or remove the class + * @return {DOMElement} the element passed in + */ + conditionClass: function (element, className, bool) { + return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); + }, + + /** + * Tests whether the element has the class specified. + * + * @param {DOMNode|DOMWindow} element the element to set the class on + * @param {string} className the CSS className + * @return {boolean} true if the element has the class, false if not + */ + hasClass: function (element, className) { + !!/\s/.test(className) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'CSS.hasClass takes only a single class name.') : invariant(false) : undefined; + if (element.classList) { + return !!className && element.classList.contains(className); + } + return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; + } +}; + +module.exports = CSSCore; }).call(this,require('_process')) -},{"./Object.assign":69,"./invariant":191,"./keyOf":198,"_process":1}],212:[function(require,module,exports){ +},{"./invariant":220,"_process":1}],205:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule EventListener + * @typechecks + */ + +'use strict'; + +var emptyFunction = require('./emptyFunction'); + +/** + * Upstream version of event listener. Does not take into account specific + * nature of platform. + */ +var EventListener = { + /** + * Listen to DOM events during the bubble phase. + * + * @param {DOMEventTarget} target DOM element to register listener on. + * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. + * @param {function} callback Callback function. + * @return {object} Object with a `remove` method. + */ + listen: function (target, eventType, callback) { + if (target.addEventListener) { + target.addEventListener(eventType, callback, false); + return { + remove: function () { + target.removeEventListener(eventType, callback, false); + } + }; + } else if (target.attachEvent) { + target.attachEvent('on' + eventType, callback); + return { + remove: function () { + target.detachEvent('on' + eventType, callback); + } + }; + } + }, + + /** + * Listen to DOM events during the capture phase. + * + * @param {DOMEventTarget} target DOM element to register listener on. + * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. + * @param {function} callback Callback function. + * @return {object} Object with a `remove` method. + */ + capture: function (target, eventType, callback) { + if (target.addEventListener) { + target.addEventListener(eventType, callback, true); + return { + remove: function () { + target.removeEventListener(eventType, callback, true); + } + }; + } else { + if (process.env.NODE_ENV !== 'production') { + console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); + } + return { + remove: emptyFunction + }; + } + }, + + registerDefault: function () {} +}; + +module.exports = EventListener; +}).call(this,require('_process')) + +},{"./emptyFunction":212,"_process":1}],206:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ExecutionEnvironment + */ + +'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; +},{}],207:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule camelize + * @typechecks + */ + +"use strict"; + +var _hyphenPattern = /-(.)/g; + +/** + * Camelcases a hyphenated string, for example: + * + * > camelize('background-color') + * < "backgroundColor" + * + * @param {string} string + * @return {string} + */ +function camelize(string) { + return string.replace(_hyphenPattern, function (_, character) { + return character.toUpperCase(); + }); +} + +module.exports = camelize; +},{}],208:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule camelizeStyleName + * @typechecks + */ + +'use strict'; + +var camelize = require('./camelize'); + +var msPattern = /^-ms-/; + +/** + * Camelcases a hyphenated CSS property name, for example: + * + * > camelizeStyleName('background-color') + * < "backgroundColor" + * > camelizeStyleName('-moz-transition') + * < "MozTransition" + * > camelizeStyleName('-ms-transition') + * < "msTransition" + * + * As Andi Smith suggests + * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix + * is converted to lowercase `ms`. + * + * @param {string} string + * @return {string} + */ +function camelizeStyleName(string) { + return camelize(string.replace(msPattern, 'ms-')); +} + +module.exports = camelizeStyleName; +},{"./camelize":207}],209:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule containsNode + * @typechecks + */ + +'use strict'; + +var isTextNode = require('./isTextNode'); + +/*eslint-disable no-bitwise */ + +/** + * Checks if a given DOM node contains or is another DOM node. + * + * @param {?DOMNode} outerNode Outer DOM node. + * @param {?DOMNode} innerNode Inner DOM node. + * @return {boolean} True if `outerNode` contains or is `innerNode`. + */ +function containsNode(_x, _x2) { + var _again = true; + + _function: while (_again) { + var outerNode = _x, + innerNode = _x2; + _again = false; + + if (!outerNode || !innerNode) { + return false; + } else if (outerNode === innerNode) { + return true; + } else if (isTextNode(outerNode)) { + return false; + } else if (isTextNode(innerNode)) { + _x = outerNode; + _x2 = innerNode.parentNode; + _again = true; + continue _function; + } else if (outerNode.contains) { + return outerNode.contains(innerNode); + } else if (outerNode.compareDocumentPosition) { + return !!(outerNode.compareDocumentPosition(innerNode) & 16); + } else { + return false; + } + } +} + +module.exports = containsNode; +},{"./isTextNode":222}],210:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule createArrayFromMixed + * @typechecks + */ + +'use strict'; + +var toArray = require('./toArray'); + +/** + * Perform a heuristic test to determine if an object is "array-like". + * + * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" + * Joshu replied: "Mu." + * + * This function determines if its argument has "array nature": it returns + * true if the argument is an actual array, an `arguments' object, or an + * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). + * + * It will return false for other array-like objects like Filelist. + * + * @param {*} obj + * @return {boolean} + */ +function hasArrayNature(obj) { + return( + // not null/false + !!obj && ( + // arrays are objects, NodeLists are functions in Safari + typeof obj == 'object' || typeof obj == 'function') && + // quacks like an array + 'length' in obj && + // not window + !('setInterval' in obj) && + // no DOM node should be considered an array-like + // a 'select' element has 'length' and 'item' properties on IE8 + typeof obj.nodeType != 'number' && ( + // a real array + Array.isArray(obj) || + // arguments + 'callee' in obj || + // HTMLCollection/NodeList + 'item' in obj) + ); +} + +/** + * Ensure that the argument is an array by wrapping it in an array if it is not. + * Creates a copy of the argument if it is already an array. + * + * This is mostly useful idiomatically: + * + * var createArrayFromMixed = require('createArrayFromMixed'); + * + * function takesOneOrMoreThings(things) { + * things = createArrayFromMixed(things); + * ... + * } + * + * This allows you to treat `things' as an array, but accept scalars in the API. + * + * If you need to convert an array-like object, like `arguments`, into an array + * use toArray instead. + * + * @param {*} obj + * @return {array} + */ +function createArrayFromMixed(obj) { + if (!hasArrayNature(obj)) { + return [obj]; + } else if (Array.isArray(obj)) { + return obj.slice(); + } else { + return toArray(obj); + } +} + +module.exports = createArrayFromMixed; +},{"./toArray":231}],211:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule createNodesFromMarkup + * @typechecks + */ + +/*eslint-disable fb-www/unsafe-html*/ + +'use strict'; + +var ExecutionEnvironment = require('./ExecutionEnvironment'); + +var createArrayFromMixed = require('./createArrayFromMixed'); +var getMarkupWrap = require('./getMarkupWrap'); +var invariant = require('./invariant'); + +/** + * Dummy container used to render all markup. + */ +var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; + +/** + * Pattern used by `getNodeName`. + */ +var nodeNamePattern = /^\s*<(\w+)/; + +/** + * Extracts the `nodeName` of the first element in a string of markup. + * + * @param {string} markup String of markup. + * @return {?string} Node name of the supplied markup. + */ +function getNodeName(markup) { + var nodeNameMatch = markup.match(nodeNamePattern); + return nodeNameMatch && nodeNameMatch[1].toLowerCase(); +} + +/** + * Creates an array containing the nodes rendered from the supplied markup. The + * optionally supplied `handleScript` function will be invoked once for each + * <script> element that is rendered. If no `handleScript` function is supplied, + * an exception is thrown if any <script> elements are rendered. + * + * @param {string} markup A string of valid HTML markup. + * @param {?function} handleScript Invoked once for each rendered <script>. + * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. + */ +function createNodesFromMarkup(markup, handleScript) { + var node = dummyNode; + !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : undefined; + var nodeName = getNodeName(markup); + + var wrap = nodeName && getMarkupWrap(nodeName); + if (wrap) { + node.innerHTML = wrap[1] + markup + wrap[2]; + + var wrapDepth = wrap[0]; + while (wrapDepth--) { + node = node.lastChild; + } + } else { + node.innerHTML = markup; + } + + var scripts = node.getElementsByTagName('script'); + if (scripts.length) { + !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : undefined; + createArrayFromMixed(scripts).forEach(handleScript); + } + + var nodes = createArrayFromMixed(node.childNodes); + while (node.lastChild) { + node.removeChild(node.lastChild); + } + return nodes; +} + +module.exports = createNodesFromMarkup; +}).call(this,require('_process')) + +},{"./ExecutionEnvironment":206,"./createArrayFromMixed":210,"./getMarkupWrap":216,"./invariant":220,"_process":1}],212:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule emptyFunction + */ + +"use strict"; + +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; +},{}],213:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule emptyObject + */ + +'use strict'; + +var emptyObject = {}; + +if (process.env.NODE_ENV !== 'production') { + Object.freeze(emptyObject); +} + +module.exports = emptyObject; +}).call(this,require('_process')) + +},{"_process":1}],214:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule focusNode + */ + +'use strict'; + +/** + * @param {DOMElement} node input/textarea to focus + */ +function focusNode(node) { + // IE8 can throw "Can't move focus to the control because it is invisible, + // not enabled, or of a type that does not accept the focus." for all kinds of + // reasons that are too expensive and fragile to test. + try { + node.focus(); + } catch (e) {} +} + +module.exports = focusNode; +},{}],215:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule getActiveElement + * @typechecks + */ + +/* eslint-disable fb-www/typeof-undefined */ + +/** + * Same as document.activeElement but wraps in a try-catch block. In IE it is + * not safe to call document.activeElement if there is nothing focused. + * + * The activeElement will be null only if the document or document body is not + * yet defined. + */ +'use strict'; + +function getActiveElement() /*?DOMElement*/{ + if (typeof document === 'undefined') { + return null; + } + try { + return document.activeElement || document.body; + } catch (e) { + return document.body; + } +} + +module.exports = getActiveElement; +},{}],216:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule getMarkupWrap + */ + +/*eslint-disable fb-www/unsafe-html */ + +'use strict'; + +var ExecutionEnvironment = require('./ExecutionEnvironment'); + +var invariant = require('./invariant'); + +/** + * Dummy container used to detect which wraps are necessary. + */ +var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; + +/** + * Some browsers cannot use `innerHTML` to render certain elements standalone, + * so we wrap them, render the wrapped nodes, then extract the desired node. + * + * In IE8, certain elements cannot render alone, so wrap all elements ('*'). + */ + +var shouldWrap = {}; + +var selectWrap = [1, '<select multiple="true">', '</select>']; +var tableWrap = [1, '<table>', '</table>']; +var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; + +var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; + +var markupWrap = { + '*': [1, '?<div>', '</div>'], + + 'area': [1, '<map>', '</map>'], + 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], + 'legend': [1, '<fieldset>', '</fieldset>'], + 'param': [1, '<object>', '</object>'], + 'tr': [2, '<table><tbody>', '</tbody></table>'], + + 'optgroup': selectWrap, + 'option': selectWrap, + + 'caption': tableWrap, + 'colgroup': tableWrap, + 'tbody': tableWrap, + 'tfoot': tableWrap, + 'thead': tableWrap, + + 'td': trWrap, + 'th': trWrap +}; + +// Initialize the SVG elements since we know they'll always need to be wrapped +// consistently. If they are created inside a <div> they will be initialized in +// the wrong namespace (and will not display). +var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; +svgElements.forEach(function (nodeName) { + markupWrap[nodeName] = svgWrap; + shouldWrap[nodeName] = true; +}); + +/** + * Gets the markup wrap configuration for the supplied `nodeName`. + * + * NOTE: This lazily detects which wraps are necessary for the current browser. + * + * @param {string} nodeName Lowercase `nodeName`. + * @return {?array} Markup wrap configuration, if applicable. + */ +function getMarkupWrap(nodeName) { + !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : undefined; + if (!markupWrap.hasOwnProperty(nodeName)) { + nodeName = '*'; + } + if (!shouldWrap.hasOwnProperty(nodeName)) { + if (nodeName === '*') { + dummyNode.innerHTML = '<link />'; + } else { + dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; + } + shouldWrap[nodeName] = !dummyNode.firstChild; + } + return shouldWrap[nodeName] ? markupWrap[nodeName] : null; +} + +module.exports = getMarkupWrap; +}).call(this,require('_process')) + +},{"./ExecutionEnvironment":206,"./invariant":220,"_process":1}],217:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule getUnboundedScrollPosition + * @typechecks + */ + +'use strict'; + +/** + * Gets the scroll position of the supplied element or window. + * + * The return values are unbounded, unlike `getScrollPosition`. This means they + * may be negative or exceed the element boundaries (which is possible using + * inertial scrolling). + * + * @param {DOMWindow|DOMElement} scrollable + * @return {object} Map with `x` and `y` keys. + */ +function getUnboundedScrollPosition(scrollable) { + if (scrollable === window) { + return { + x: window.pageXOffset || document.documentElement.scrollLeft, + y: window.pageYOffset || document.documentElement.scrollTop + }; + } + return { + x: scrollable.scrollLeft, + y: scrollable.scrollTop + }; +} + +module.exports = getUnboundedScrollPosition; +},{}],218:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule hyphenate + * @typechecks + */ + +'use strict'; + +var _uppercasePattern = /([A-Z])/g; + +/** + * Hyphenates a camelcased string, for example: + * + * > hyphenate('backgroundColor') + * < "background-color" + * + * For CSS style names, use `hyphenateStyleName` instead which works properly + * with all vendor prefixes, including `ms`. + * + * @param {string} string + * @return {string} + */ +function hyphenate(string) { + return string.replace(_uppercasePattern, '-$1').toLowerCase(); +} + +module.exports = hyphenate; +},{}],219:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule hyphenateStyleName + * @typechecks + */ + +'use strict'; + +var hyphenate = require('./hyphenate'); + +var msPattern = /^ms-/; + +/** + * Hyphenates a camelcased CSS property name, for example: + * + * > hyphenateStyleName('backgroundColor') + * < "background-color" + * > hyphenateStyleName('MozTransition') + * < "-moz-transition" + * > hyphenateStyleName('msTransition') + * < "-ms-transition" + * + * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix + * is converted to `-ms-`. + * + * @param {string} string + * @return {string} + */ +function hyphenateStyleName(string) { + return hyphenate(string).replace(msPattern, '-ms-'); +} + +module.exports = hyphenateStyleName; +},{"./hyphenate":218}],220:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule invariant + */ + +'use strict'; + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +function invariant(condition, format, a, b, c, d, e, f) { + if (process.env.NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error(format.replace(/%s/g, function () { + return args[argIndex++]; + })); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +} + +module.exports = invariant; +}).call(this,require('_process')) + +},{"_process":1}],221:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule isNode + * @typechecks + */ + +/** + * @param {*} object The object to check. + * @return {boolean} Whether or not the object is a DOM node. + */ +'use strict'; + +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; +},{}],222:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule isTextNode + * @typechecks + */ + +'use strict'; + +var isNode = require('./isNode'); + +/** + * @param {*} object The object to check. + * @return {boolean} Whether or not the object is a DOM text node. + */ +function isTextNode(object) { + return isNode(object) && object.nodeType == 3; +} + +module.exports = isTextNode; +},{"./isNode":221}],223:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule joinClasses + * @typechecks static-only + */ + +'use strict'; + +/** + * Combines multiple className strings into one. + * http://jsperf.com/joinclasses-args-vs-array + * + * @param {...?string} className + * @return {string} + */ +function joinClasses(className /*, ... */) { + if (!className) { + className = ''; + } + var nextClass; + var argLength = arguments.length; + if (argLength > 1) { + for (var ii = 1; ii < argLength; ii++) { + nextClass = arguments[ii]; + if (nextClass) { + className = (className ? className + ' ' : '') + nextClass; + } + } + } + return className; +} + +module.exports = joinClasses; +},{}],224:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule keyMirror + * @typechecks static-only + */ + +'use strict'; + +var invariant = require('./invariant'); + +/** + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; + * + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. + * + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} + * + * @param {object} obj + * @return {object} + */ +var keyMirror = function (obj) { + var ret = {}; + var key; + !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : undefined; + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; + } + return ret; +}; + +module.exports = keyMirror; +}).call(this,require('_process')) + +},{"./invariant":220,"_process":1}],225:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule keyOf + */ + +/** + * Allows extraction of a minified key. Let's the build system minify keys + * without losing 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. + */ +"use strict"; + +var keyOf = function (oneKeyObj) { + var key; + for (key in oneKeyObj) { + if (!oneKeyObj.hasOwnProperty(key)) { + continue; + } + return key; + } + return null; +}; + +module.exports = keyOf; +},{}],226:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule mapObject + */ + +'use strict'; + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Executes the provided `callback` once for each enumerable own property in the + * object and constructs a new object from the results. The `callback` is + * invoked with three arguments: + * + * - the property value + * - the property name + * - the object being traversed + * + * Properties that are added after the call to `mapObject` will not be visited + * by `callback`. If the values of existing properties are changed, the value + * passed to `callback` will be the value at the time `mapObject` visits them. + * Properties that are deleted before being visited are not visited. + * + * @grep function objectMap() + * @grep function objMap() + * + * @param {?object} object + * @param {function} callback + * @param {*} context + * @return {?object} + */ +function mapObject(object, callback, context) { + if (!object) { + return null; + } + var result = {}; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result[name] = callback.call(context, object[name], name, object); + } + } + return result; +} + +module.exports = mapObject; +},{}],227:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule memoizeStringOnly + * @typechecks static-only + */ + +'use strict'; + +/** + * Memoizes the return value of a function that accepts one string argument. + * + * @param {function} callback + * @return {function} + */ +function memoizeStringOnly(callback) { + var cache = {}; + return function (string) { + if (!cache.hasOwnProperty(string)) { + cache[string] = callback.call(this, string); + } + return cache[string]; + }; +} + +module.exports = memoizeStringOnly; +},{}],228:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule performance + * @typechecks + */ + +'use strict'; + +var ExecutionEnvironment = require('./ExecutionEnvironment'); + +var performance; + +if (ExecutionEnvironment.canUseDOM) { + performance = window.performance || window.msPerformance || window.webkitPerformance; +} + +module.exports = performance || {}; +},{"./ExecutionEnvironment":206}],229:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule performanceNow + * @typechecks + */ + +'use strict'; + +var performance = require('./performance'); + +var performanceNow; + +/** + * 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.now) { + performanceNow = function () { + return performance.now(); + }; +} else { + performanceNow = function () { + return Date.now(); + }; +} + +module.exports = performanceNow; +},{"./performance":228}],230:[function(require,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule shallowEqual + * @typechecks + * + */ + +'use strict'; + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Performs equality by iterating through keys on an object and returning false + * when any key has values which are not strictly equal between the arguments. + * Returns true when the values of all keys are strictly equal. + */ +function shallowEqual(objA, objB) { + if (objA === objB) { + return true; + } + + if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } + + // Test for A's keys different from B. + var bHasOwnProperty = hasOwnProperty.bind(objB); + for (var i = 0; i < keysA.length; i++) { + if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { + return false; + } + } + + return true; +} + +module.exports = shallowEqual; +},{}],231:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule toArray + * @typechecks + */ + +'use strict'; + +var invariant = require('./invariant'); + +/** + * Convert array-like objects to arrays. + * + * This API assumes the caller knows the contents of the data type. For less + * well defined inputs use createArrayFromMixed. + * + * @param {object|function|filelist} obj + * @return {array} + */ +function toArray(obj) { + var length = obj.length; + + // Some browse builtin objects can report typeof 'function' (e.g. NodeList in + // old versions of Safari). + !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : undefined; + + !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : undefined; + + !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : undefined; + + // Old IE doesn't give collections access to hasOwnProperty. Assume inputs + // without method will throw during the slice call and skip straight to the + // fallback. + if (obj.hasOwnProperty) { + try { + return Array.prototype.slice.call(obj); + } catch (e) { + // IE < 9 does not support Array#slice on collections objects + } + } + + // Fall back to copying key by key. This assumes all keys have a value, + // so will not preserve sparsely populated inputs. + var ret = Array(length); + for (var ii = 0; ii < length; ii++) { + ret[ii] = obj[ii]; + } + return ret; +} + +module.exports = toArray; +}).call(this,require('_process')) + +},{"./invariant":220,"_process":1}],232:[function(require,module,exports){ (function (process){ /** * Copyright 2014-2015, Facebook, Inc. @@ -25085,9 +26032,9 @@ module.exports = update; * @providesModule warning */ -"use strict"; +'use strict'; -var emptyFunction = require("./emptyFunction"); +var emptyFunction = require('./emptyFunction'); /** * Similar to invariant but only logs a warning if the condition is not met. @@ -25098,20 +26045,14 @@ var emptyFunction = require("./emptyFunction"); var warning = emptyFunction; -if ("production" !== process.env.NODE_ENV) { - warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); +if (process.env.NODE_ENV !== 'production') { + warning = function (condition, format) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; } - 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 === undefined) { + throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); } if (format.indexOf('Failed Composite propType: ') === 0) { @@ -25120,23 +26061,26 @@ if ("production" !== process.env.NODE_ENV) { if (!condition) { var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); - console.warn(message); + var message = 'Warning: ' + format.replace(/%s/g, function () { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.error(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) {} + } catch (x) {} } }; } module.exports = warning; - }).call(this,require('_process')) -},{"./emptyFunction":170,"_process":1}],"flux":[function(require,module,exports){ +},{"./emptyFunction":212,"_process":1}],"flux":[function(require,module,exports){ /** * Copyright (c) 2014-2015, Facebook, Inc. * All rights reserved. @@ -25150,17 +26094,17 @@ module.exports.Dispatcher = require('./lib/Dispatcher'); },{"./lib/Dispatcher":2}],"jquery":[function(require,module,exports){ /*! - * jQuery JavaScript Library v2.1.4 + * jQuery JavaScript Library v2.2.1 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2015-04-28T16:01Z + * Date: 2016-02-22T19:11Z */ (function( global, factory ) { @@ -25192,10 +26136,11 @@ module.exports.Dispatcher = require('./lib/Dispatcher'); // Can't be in strict mode, several libs including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) -// - +//"use strict"; var arr = []; +var document = window.document; + var slice = arr.slice; var concat = arr.concat; @@ -25215,13 +26160,11 @@ var support = {}; var - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - version = "2.1.4", + version = "2.2.1", // Define a local copy of jQuery jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); @@ -25241,6 +26184,7 @@ var }; jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used jquery: version, @@ -25284,16 +26228,14 @@ jQuery.fn = jQuery.prototype = { }, // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); + each: function( callback ) { + return jQuery.each( this, callback ); }, map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); - })); + } ) ); }, slice: function() { @@ -25311,11 +26253,11 @@ jQuery.fn = jQuery.prototype = { eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { - return this.prevObject || this.constructor(null); + return this.prevObject || this.constructor(); }, // For internal use only. @@ -25327,7 +26269,7 @@ jQuery.fn = jQuery.prototype = { jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, + target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; @@ -25342,7 +26284,7 @@ jQuery.extend = jQuery.fn.extend = function() { } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } @@ -25353,8 +26295,10 @@ jQuery.extend = jQuery.fn.extend = function() { } for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { + if ( ( options = arguments[ i ] ) != null ) { + // Extend the base object for ( name in options ) { src = target[ name ]; @@ -25366,13 +26310,15 @@ jQuery.extend = jQuery.fn.extend = function() { } // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + if ( copyIsArray ) { copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; + clone = src && jQuery.isArray( src ) ? src : []; } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; + clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them @@ -25390,7 +26336,8 @@ jQuery.extend = jQuery.fn.extend = function() { return target; }; -jQuery.extend({ +jQuery.extend( { + // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), @@ -25404,7 +26351,7 @@ jQuery.extend({ noop: function() {}, isFunction: function( obj ) { - return jQuery.type(obj) === "function"; + return jQuery.type( obj ) === "function"; }, isArray: Array.isArray, @@ -25414,14 +26361,17 @@ jQuery.extend({ }, isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN // adding 1 corrects loss of precision from parseFloat (#15100) - return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; }, isPlainObject: function( obj ) { + // Not plain objects: // - Any object or value whose internal [[Class]] property is not "[object Object]" // - DOM nodes @@ -25452,9 +26402,10 @@ jQuery.extend({ if ( obj == null ) { return obj + ""; } + // Support: Android<4.0, iOS<6 (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : + class2type[ toString.call( obj ) ] || "object" : typeof obj; }, @@ -25466,16 +26417,19 @@ jQuery.extend({ code = jQuery.trim( code ); if ( code ) { + // If the code includes a valid, prologue position // strict mode pragma, execute code by injecting a // script tag into the document. - if ( code.indexOf("use strict") === 1 ) { - script = document.createElement("script"); + if ( code.indexOf( "use strict" ) === 1 ) { + script = document.createElement( "script" ); script.text = code; document.head.appendChild( script ).parentNode.removeChild( script ); } else { - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval + + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); } } @@ -25492,49 +26446,20 @@ jQuery.extend({ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); + each: function( obj, callback ) { + var length, i = 0; - if ( value === false ) { - break; - } + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } - - // A special, fast, case for the most common use of each } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } } @@ -25554,7 +26479,7 @@ jQuery.extend({ var ret = results || []; if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { + if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr @@ -25606,14 +26531,13 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var value, + var length, value, i = 0, - length = elems.length, - isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their new values - if ( isArray ) { + if ( isArrayLike( elems ) ) { + length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); @@ -25674,43 +26598,50 @@ jQuery.extend({ // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support -}); +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} +/* jshint ignore: end */ // Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); +} ); -function isArraylike( obj ) { +function isArrayLike( obj ) { // Support: iOS 8.2 (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE - var length = "length" in obj && obj.length, + var length = !!obj && "length" in obj && obj.length, type = jQuery.type( obj ); if ( type === "function" || jQuery.isWindow( obj ) ) { return false; } - if ( obj.nodeType === 1 && length ) { - return true; - } - return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.2.0-pre + * Sizzle CSS Selector Engine v2.2.1 * http://sizzlejs.com/ * - * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-12-16 + * Date: 2015-10-17 */ (function( window ) { @@ -25778,25 +26709,21 @@ var i, // Regular expressions - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", - pseudos = ":(" + characterEncoding + ")(?:\\((" + + pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + @@ -25819,9 +26746,9 @@ var i, ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + @@ -25899,103 +26826,129 @@ try { } function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; - context = context || document; results = results || []; - nodeType = context.nodeType; + // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } - if ( !seed && documentIsHTML ) { + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { - // Try to shortcut find operations when possible (e.g., not under DocumentFragment) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { return results; } + + // Element context } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } } - } - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } } - } - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType !== 1 && selector; + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } } } } @@ -26008,7 +26961,7 @@ function Sizzle( selector, context, results, seed ) { /** * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ @@ -26063,7 +27016,7 @@ function assert( fn ) { */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), - i = attrs.length; + i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; @@ -26176,33 +27129,29 @@ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, parent, doc = node ? node.ownerDocument || node : preferredDoc; - // If no document and documentElement is available, return + // Return early if doc is invalid or already selected if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } - // Set our document + // Update global variables document = doc; - docElem = doc.documentElement; - parent = doc.defaultView; - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 if ( parent.addEventListener ) { parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only } else if ( parent.attachEvent ) { parent.attachEvent( "onunload", unloadHandler ); } } - /* Support tests - ---------------------------------------------------------------------- */ - documentIsHTML = !isXML( doc ); - /* Attributes ---------------------------------------------------------------------- */ @@ -26219,12 +27168,12 @@ setDocument = Sizzle.setDocument = function( node ) { // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); + div.appendChild( document.createComment("") ); return !div.getElementsByTagName("*").length; }); // Support: IE<9 - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name @@ -26232,7 +27181,7 @@ setDocument = Sizzle.setDocument = function( node ) { // so use a roundabout getElementsByName test support.getById = assert(function( div ) { docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + return !document.getElementsByName || !document.getElementsByName( expando ).length; }); // ID find and filter @@ -26240,9 +27189,7 @@ setDocument = Sizzle.setDocument = function( node ) { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; + return m ? [ m ] : []; } }; Expr.filter["ID"] = function( id ) { @@ -26259,7 +27206,8 @@ setDocument = Sizzle.setDocument = function( node ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); return node && node.value === attrId; }; }; @@ -26299,7 +27247,7 @@ setDocument = Sizzle.setDocument = function( node ) { // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( documentIsHTML ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; @@ -26319,7 +27267,7 @@ setDocument = Sizzle.setDocument = function( node ) { // See http://bugs.jquery.com/ticket/13378 rbuggyQSA = []; - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { @@ -26329,7 +27277,7 @@ setDocument = Sizzle.setDocument = function( node ) { // since its presence should be enough // http://bugs.jquery.com/ticket/12359 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + - "<select id='" + expando + "-\f]' msallowcapture=''>" + + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; // Support: IE8, Opera 11-12.16 @@ -26346,7 +27294,7 @@ setDocument = Sizzle.setDocument = function( node ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } - // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push("~="); } @@ -26369,7 +27317,7 @@ setDocument = Sizzle.setDocument = function( node ) { assert(function( div ) { // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); + var input = document.createElement("input"); input.setAttribute( "type", "hidden" ); div.appendChild( input ).setAttribute( "name", "D" ); @@ -26417,7 +27365,7 @@ setDocument = Sizzle.setDocument = function( node ) { hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another - // Purposefully does not implement inclusive descendent + // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { @@ -26471,10 +27419,10 @@ setDocument = Sizzle.setDocument = function( node ) { (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } @@ -26502,8 +27450,8 @@ setDocument = Sizzle.setDocument = function( node ) { // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : + return a === document ? -1 : + b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? @@ -26540,7 +27488,7 @@ setDocument = Sizzle.setDocument = function( node ) { 0; }; - return doc; + return document; }; Sizzle.matches = function( expr, elements ) { @@ -26557,6 +27505,7 @@ Sizzle.matchesSelector = function( elem, expr ) { expr = expr.replace( rattributeQuotes, "='$1']" ); if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { @@ -26830,11 +27779,12 @@ Expr = Sizzle.selectors = { } : function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, + var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; + useCache = !xml && !ofType, + diff = false; if ( parent ) { @@ -26843,7 +27793,10 @@ Expr = Sizzle.selectors = { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + return false; } } @@ -26857,11 +27810,21 @@ Expr = Sizzle.selectors = { // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { + // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || @@ -26871,29 +27834,55 @@ Expr = Sizzle.selectors = { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); - if ( node === elem ) { - break; + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } } } } @@ -27255,10 +28244,10 @@ function addCombinator( matcher, combinator, base ) { // Check against all ancestor/preceding elements function( elem, context, xml ) { - var oldCache, outerCache, + var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { @@ -27271,14 +28260,19 @@ function addCombinator( matcher, combinator, base ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; + uniqueCache[ dir ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { @@ -27503,18 +28497,21 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { len = elems.length; if ( outermost ) { - outermostContext = context !== document && context; + outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { + if ( matcher( elem, context || document, xml) ) { results.push( elem ); break; } @@ -27538,8 +28535,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { } } - // Apply set filters to unmatched elements + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { @@ -27631,10 +28637,11 @@ select = Sizzle.select = function( selector, context, results, seed ) { results = results || []; - // Try to minimize operations if there is no seed and only one group + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) if ( match.length === 1 ) { - // Take a shortcut and set the context if the root selector is an ID + // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && @@ -27689,7 +28696,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { context, !documentIsHTML, results, - rsibling.test( selector ) && testContext( context.parentNode ) || context + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; @@ -27765,17 +28772,46 @@ return Sizzle; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + var rneedsContext = jQuery.expr.match.needsContext; -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); @@ -27787,14 +28823,14 @@ function winnow( elements, qualifier, not ) { return jQuery.grep( elements, function( elem, i ) { /* jshint -W018 */ return !!qualifier.call( elem, i, elem ) !== not; - }); + } ); } if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; - }); + } ); } @@ -27807,8 +28843,8 @@ function winnow( elements, qualifier, not ) { } return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; - }); + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); } jQuery.filter = function( expr, elems, not ) { @@ -27822,10 +28858,10 @@ jQuery.filter = function( expr, elems, not ) { jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; - })); + } ) ); }; -jQuery.fn.extend({ +jQuery.fn.extend( { find: function( selector ) { var i, len = this.length, @@ -27833,13 +28869,13 @@ jQuery.fn.extend({ self = this; if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { + return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } - }) ); + } ) ); } for ( i = 0; i < len; i++ ) { @@ -27852,10 +28888,10 @@ jQuery.fn.extend({ return ret; }, filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); + return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); + return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( @@ -27869,7 +28905,7 @@ jQuery.fn.extend({ false ).length; } -}); +} ); // Initialize a jQuery object @@ -27883,7 +28919,7 @@ var rootjQuery, // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - init = jQuery.fn.init = function( selector, context ) { + init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) @@ -27891,9 +28927,16 @@ var rootjQuery, return this; } + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + // Handle HTML strings if ( typeof selector === "string" ) { - if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; @@ -27902,23 +28945,24 @@ var rootjQuery, } // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { + if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( - match[1], + match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { + // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); @@ -27934,14 +28978,15 @@ var rootjQuery, // HANDLE: $(#id) } else { - elem = document.getElementById( match[2] ); + elem = document.getElementById( match[ 2 ] ); // Support: Blackberry 4.6 // gEBID returns nodes no longer in the document (#6963) if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object this.length = 1; - this[0] = elem; + this[ 0 ] = elem; } this.context = document; @@ -27951,7 +28996,7 @@ var rootjQuery, // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); + return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) @@ -27961,15 +29006,16 @@ var rootjQuery, // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { - this.context = this[0] = selector; + this.context = this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : + return root.ready !== undefined ? + root.ready( selector ) : + // Execute immediately if ready is not present selector( jQuery ); } @@ -27990,6 +29036,7 @@ rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, @@ -27998,48 +29045,19 @@ var rparentsprev = /^(?:parents|prev(?:Until|All))/, prev: true }; -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; - }, - - sibling: function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; - } -}); - -jQuery.fn.extend({ +jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; - return this.filter(function() { + return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { + if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } - }); + } ); }, closest: function( selectors, context ) { @@ -28052,14 +29070,15 @@ jQuery.fn.extend({ 0; for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { + jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; @@ -28067,7 +29086,7 @@ jQuery.fn.extend({ } } - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set @@ -28093,7 +29112,7 @@ jQuery.fn.extend({ add: function( selector, context ) { return this.pushStack( - jQuery.unique( + jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); @@ -28101,26 +29120,26 @@ jQuery.fn.extend({ addBack: function( selector ) { return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) + this.prevObject : this.prevObject.filter( selector ) ); } -}); +} ); function sibling( cur, dir ) { - while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } -jQuery.each({ +jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); + return dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); + return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); @@ -28129,22 +29148,22 @@ jQuery.each({ return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); + return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); + return dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); + return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); + return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { - return jQuery.sibling( elem.firstChild ); + return siblings( elem.firstChild ); }, contents: function( elem ) { return elem.contentDocument || jQuery.merge( [], elem.childNodes ); @@ -28162,9 +29181,10 @@ jQuery.each({ } if ( this.length > 1 ) { + // Remove duplicates if ( !guaranteedUnique[ name ] ) { - jQuery.unique( matched ); + jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives @@ -28175,20 +29195,17 @@ jQuery.each({ return this.pushStack( matched ); }; -}); -var rnotwhite = (/\S+/g); - +} ); +var rnotwhite = ( /\S+/g ); -// String to Object options format cache -var optionsCache = {}; -// Convert String-formatted options into Object-formatted ones and store in cache +// Convert String-formatted options into Object-formatted ones function createOptions( options ) { - var object = optionsCache[ options ] = {}; + var object = {}; jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { object[ flag ] = true; - }); + } ); return object; } @@ -28219,156 +29236,186 @@ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : + createOptions( options ) : jQuery.extend( {}, options ); - var // Last fire value (for non-forgettable lists) + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists memory, + // Flag to know if list was already fired fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, + + // Flag to prevent firing + locked, + // Actual callback list list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } } } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { list = []; + + // Otherwise, this object is spent } else { - self.disable(); + list = ""; } } }, + // Actual Callbacks object self = { + // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { + if ( jQuery.isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } - } else if ( arg && arg.length && type !== "string" ) { + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + // Inspect recursively add( arg ); } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); } } return this; }, + // Remove a callback from the list remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; } - }); - } + } + } ); return this; }, + // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; }, + // Remove all callbacks from the list empty: function() { - list = []; - firingLength = 0; + if ( list ) { + list = []; + } return this; }, - // Have the list do nothing anymore + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values disable: function() { - list = stack = memory = undefined; + locked = queue = []; + list = memory = ""; return this; }, - // Is it disabled? disabled: function() { return !list; }, - // Lock the list in its current state + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions lock: function() { - stack = undefined; + locked = queue = []; if ( !memory ) { - self.disable(); + list = memory = ""; } return this; }, - // Is it locked? locked: function() { - return !stack; + return !!locked; }, + // Call all callbacks with the given context and arguments fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { + if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); + queue.push( args ); + if ( !firing ) { + fire(); } } return this; }, + // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, + // To know if the callbacks have already been called at least once fired: function() { return !!fired; @@ -28379,14 +29426,15 @@ jQuery.Callbacks = function( options ) { }; -jQuery.extend({ +jQuery.extend( { Deferred: function( func ) { var tuples = [ + // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] ], state = "pending", promise = { @@ -28399,25 +29447,30 @@ jQuery.extend({ }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; - return jQuery.Deferred(function( newDefer ) { + return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { + deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() + .progress( newDefer.notify ) .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); + .fail( newDefer.reject ); } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); } - }); - }); + } ); + } ); fns = null; - }).promise(); + } ).promise(); }, + // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { @@ -28435,11 +29488,12 @@ jQuery.extend({ stateString = tuple[ 3 ]; // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; + promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { - list.add(function() { + list.add( function() { + // state = [ resolved | rejected ] state = stateString; @@ -28448,12 +29502,12 @@ jQuery.extend({ } // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); // Make the deferred a promise promise.promise( deferred ); @@ -28474,9 +29528,11 @@ jQuery.extend({ length = resolveValues.length, // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values @@ -28502,9 +29558,9 @@ jQuery.extend({ for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); + .fail( deferred.reject ); } else { --remaining; } @@ -28518,20 +29574,22 @@ jQuery.extend({ return deferred.promise(); } -}); +} ); // The deferred used on DOM ready var readyList; jQuery.fn.ready = function( fn ) { + // Add the callback jQuery.ready.promise().done( fn ); return this; }; -jQuery.extend({ +jQuery.extend( { + // Is the DOM ready to be used? Set to true once it occurs. isReady: false, @@ -28573,14 +29631,14 @@ jQuery.extend({ jQuery( document ).off( "ready" ); } } -}); +} ); /** * The ready event handler and self cleanup method */ function completed() { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); jQuery.ready(); } @@ -28589,20 +29647,23 @@ jQuery.ready.promise = function( obj ) { readyList = jQuery.Deferred(); - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // We once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE9-10 only + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); + window.setTimeout( jQuery.ready ); } else { // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); + document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); + window.addEventListener( "load", completed ); } } return readyList.promise( obj ); @@ -28616,7 +29677,7 @@ jQuery.ready.promise(); // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; @@ -28625,7 +29686,7 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value @@ -28637,6 +29698,7 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe } if ( bulk ) { + // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); @@ -28653,7 +29715,11 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe if ( fn ) { for ( ; i < len; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); } } } @@ -28664,14 +29730,10 @@ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGe // Gets bulk ? fn.call( elems ) : - len ? fn( elems[0], key ) : emptyGet; + len ? fn( elems[ 0 ], key ) : emptyGet; }; +var acceptData = function( owner ) { - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE @@ -28683,66 +29745,79 @@ jQuery.acceptData = function( owner ) { }; -function Data() { - // Support: Android<4, - // Old WebKit does not have Object.preventExtensions/freeze method, - // return new empty object instead with no [[set]] accessor - Object.defineProperty( this.cache = {}, 0, { - get: function() { - return {}; - } - }); + +function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; -Data.accepts = jQuery.acceptData; Data.prototype = { - key: function( owner ) { + + register: function( owner, initial ) { + var value = initial || {}; + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable, non-writable property + // configurability must be true to allow the property to be + // deleted with the delete operator + } else { + Object.defineProperty( owner, this.expando, { + value: value, + writable: true, + configurable: true + } ); + } + return owner[ this.expando ]; + }, + cache: function( owner ) { + // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. - // Always return the key for a frozen object. - if ( !Data.accepts( owner ) ) { - return 0; + // Always return an empty object. + if ( !acceptData( owner ) ) { + return {}; } - var descriptor = {}, - // Check if the owner object already has a cache key - unlock = owner[ this.expando ]; + // Check if the owner object already has a cache + var value = owner[ this.expando ]; // If not, create one - if ( !unlock ) { - unlock = Data.uid++; - - // Secure it in a non-enumerable, non-writable property - try { - descriptor[ this.expando ] = { value: unlock }; - Object.defineProperties( owner, descriptor ); - - // Support: Android<4 - // Fallback to a less secure definition - } catch ( e ) { - descriptor[ this.expando ] = unlock; - jQuery.extend( owner, descriptor ); + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } } } - // Ensure the cache object - if ( !this.cache[ unlock ] ) { - this.cache[ unlock ] = {}; - } - - return unlock; + return value; }, set: function( owner, data, value ) { var prop, - // There may be an unlock assigned to this node, - // if there is no entry for this "owner", create one inline - // and set the unlock as though an owner entry had always existed - unlock = this.key( owner ), - cache = this.cache[ unlock ]; + cache = this.cache( owner ); // Handle: [ owner, key, value ] args if ( typeof data === "string" ) { @@ -28750,30 +29825,22 @@ Data.prototype = { // Handle: [ owner, { properties } ] args } else { - // Fresh assignments by object are shallow copied - if ( jQuery.isEmptyObject( cache ) ) { - jQuery.extend( this.cache[ unlock ], data ); - // Otherwise, copy the properties one-by-one to the cache object - } else { - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ prop ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { - // Either a valid cache is found, or will be created. - // New caches will be created and the unlock returned, - // allowing direct access to the newly created - // empty data object. A valid owner object must be provided. - var cache = this.cache[ this.key( owner ) ]; - return key === undefined ? - cache : cache[ key ]; + this.cache( owner ) : + owner[ this.expando ] && owner[ this.expando ][ key ]; }, access: function( owner, key, value ) { var stored; + // In cases where either: // // 1. No key was specified @@ -28786,15 +29853,15 @@ Data.prototype = { // 2. The data stored at the key // if ( key === undefined || - ((key && typeof key === "string") && value === undefined) ) { + ( ( key && typeof key === "string" ) && value === undefined ) ) { stored = this.get( owner, key ); return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase(key) ); + stored : this.get( owner, jQuery.camelCase( key ) ); } - // [*]When the key is not a string, or both a key and value + // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties @@ -28808,15 +29875,20 @@ Data.prototype = { }, remove: function( owner, key ) { var i, name, camel, - unlock = this.key( owner ), - cache = this.cache[ unlock ]; + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } if ( key === undefined ) { - this.cache[ unlock ] = {}; + this.register( owner ); } else { + // Support array or space separated string of keys if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... // When data is initially created, via ("key", "val") signature, // keys will be converted to camelCase. @@ -28826,10 +29898,12 @@ Data.prototype = { name = key.concat( key.map( jQuery.camelCase ) ); } else { camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation if ( key in cache ) { name = [ key, camel ]; } else { + // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace name = camel; @@ -28839,25 +29913,34 @@ Data.prototype = { } i = name.length; + while ( i-- ) { delete cache[ name[ i ] ]; } } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <= 35-45+ + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } }, hasData: function( owner ) { - return !jQuery.isEmptyObject( - this.cache[ owner[ this.expando ] ] || {} - ); - }, - discard: function( owner ) { - if ( owner[ this.expando ] ) { - delete this.cache[ owner[ this.expando ] ]; - } + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; -var data_priv = new Data(); +var dataPriv = new Data(); -var data_user = new Data(); +var dataUser = new Data(); @@ -28872,7 +29955,7 @@ var data_user = new Data(); // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; + rmultiDash = /[A-Z]/g; function dataAttr( elem, key, data ) { var name; @@ -28880,7 +29963,7 @@ function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { @@ -28888,14 +29971,15 @@ function dataAttr( elem, key, data ) { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : + // Only convert to a number if it doesn't change the string +data + "" === data ? +data : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; - } catch( e ) {} + } catch ( e ) {} // Make sure we set the data so it isn't changed later - data_user.set( elem, key, data ); + dataUser.set( elem, key, data ); } else { data = undefined; } @@ -28903,31 +29987,31 @@ function dataAttr( elem, key, data ) { return data; } -jQuery.extend({ +jQuery.extend( { hasData: function( elem ) { - return data_user.hasData( elem ) || data_priv.hasData( elem ); + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { - return data_user.access( elem, name, data ); + return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { - data_user.remove( elem, name ); + dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to data_priv methods, these can be deprecated. + // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { - return data_priv.access( elem, name, data ); + return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { - data_priv.remove( elem, name ); + dataPriv.remove( elem, name ); } -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], @@ -28936,9 +30020,9 @@ jQuery.fn.extend({ // Gets all values if ( key === undefined ) { if ( this.length ) { - data = data_user.get( elem ); + data = dataUser.get( elem ); - if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { @@ -28947,12 +30031,12 @@ jQuery.fn.extend({ if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); + name = jQuery.camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } - data_priv.set( elem, "hasDataAttrs", true ); + dataPriv.set( elem, "hasDataAttrs", true ); } } @@ -28961,14 +30045,13 @@ jQuery.fn.extend({ // Sets multiple values if ( typeof key === "object" ) { - return this.each(function() { - data_user.set( this, key ); - }); + return this.each( function() { + dataUser.set( this, key ); + } ); } return access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); + var data, camelKey; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the @@ -28976,16 +30059,24 @@ jQuery.fn.extend({ // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { + // Attempt to get data from the cache // with the key as-is - data = data_user.get( elem, key ); + data = dataUser.get( elem, key ) || + + // Try to find dashed key if it exists (gh-2779) + // This is for 2.2.x only + dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); + if ( data !== undefined ) { return data; } + camelKey = jQuery.camelCase( key ); + // Attempt to get data from the cache // with the key camelized - data = data_user.get( elem, camelKey ); + data = dataUser.get( elem, camelKey ); if ( data !== undefined ) { return data; } @@ -29002,46 +30093,48 @@ jQuery.fn.extend({ } // Set the data... - this.each(function() { + camelKey = jQuery.camelCase( key ); + this.each( function() { + // First, attempt to store a copy or reference of any // data that might've been store with a camelCased key. - var data = data_user.get( this, camelKey ); + var data = dataUser.get( this, camelKey ); // For HTML5 data-* attribute interop, we have to // store property names with dashes in a camelCase form. // This might not apply to all properties...* - data_user.set( this, camelKey, value ); + dataUser.set( this, camelKey, value ); // *... In the case of properties that might _actually_ // have dashes, we need to also store a copy of that // unchanged property. - if ( key.indexOf("-") !== -1 && data !== undefined ) { - data_user.set( this, key, value ); + if ( key.indexOf( "-" ) > -1 && data !== undefined ) { + dataUser.set( this, key, value ); } - }); + } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { - return this.each(function() { - data_user.remove( this, key ); - }); + return this.each( function() { + dataUser.remove( this, key ); + } ); } -}); +} ); -jQuery.extend({ +jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; - queue = data_priv.get( elem, type ); + queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray( data ) ) { - queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } @@ -29088,15 +30181,15 @@ jQuery.extend({ // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; - return data_priv.get( elem, key ) || data_priv.access( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - data_priv.remove( elem, [ type + "queue", key ] ); - }) - }); + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); } -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; @@ -29107,30 +30200,31 @@ jQuery.fn.extend({ } if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); + return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : - this.each(function() { + this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); - if ( type === "fx" && queue[0] !== "inprogress" ) { + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } - }); + } ); }, dequeue: function( type ) { - return this.each(function() { + return this.each( function() { jQuery.dequeue( this, type ); - }); + } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, + // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { @@ -29152,7 +30246,7 @@ jQuery.fn.extend({ type = type || "fx"; while ( i-- ) { - tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); @@ -29161,28 +30255,243 @@ jQuery.fn.extend({ resolve(); return defer.promise( obj ); } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); }; -var rcheckableType = (/^(?:checkbox|radio)$/i); +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE9 + option: [ 1, "<select multiple='multiple'>", "</select>" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting <tbody> or other required elements. + thead: [ 1, "<table>", "</table>" ], + col: [ 2, "<table><colgroup>", "</colgroup></table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + -(function() { +( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); - // Support: Safari<=5.1 + // Support: Android 4.0-4.3, Safari<=5.1 // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) @@ -29200,19 +30509,13 @@ var rcheckableType = (/^(?:checkbox|radio)$/i); // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = "<textarea>x</textarea>"; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -})(); -var strundefined = typeof undefined; - - - -support.focusinBubbles = "onfocusin" in window; +} )(); var rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; @@ -29222,12 +30525,75 @@ function returnFalse() { return false; } +// Support: IE9 +// See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. @@ -29241,7 +30607,7 @@ jQuery.event = { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, - elemData = data_priv.get( elem ); + elemData = dataPriv.get( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { @@ -29261,14 +30627,15 @@ jQuery.event = { } // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { + if ( !( events = elemData.events ) ) { events = elemData.events = {}; } - if ( !(eventHandle = elemData.handle) ) { + if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } @@ -29277,9 +30644,9 @@ jQuery.event = { types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { @@ -29296,7 +30663,7 @@ jQuery.event = { special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers - handleObj = jQuery.extend({ + handleObj = jQuery.extend( { type: type, origType: origType, data: data, @@ -29304,18 +30671,20 @@ jQuery.event = { guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") + namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { + if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); + elem.addEventListener( type, eventHandle ); } } } @@ -29347,9 +30716,9 @@ jQuery.event = { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - if ( !elemData || !(events = elemData.events) ) { + if ( !elemData || !( events = elemData.events ) ) { return; } @@ -29357,9 +30726,9 @@ jQuery.event = { types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { @@ -29372,7 +30741,8 @@ jQuery.event = { special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; @@ -29382,7 +30752,8 @@ jQuery.event = { if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { @@ -29397,7 +30768,9 @@ jQuery.event = { // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); } @@ -29405,143 +30778,10 @@ jQuery.event = { } } - // Remove the expando if it's no longer used + // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - data_priv.remove( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } + dataPriv.remove( elem, "handle events" ); } - - return event.result; }, dispatch: function( event ) { @@ -29552,11 +30792,11 @@ jQuery.event = { var i, j, ret, matched, handleObj, handlerQueue = [], args = slice.call( arguments ), - handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; + args[ 0 ] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired @@ -29569,24 +30809,25 @@ jQuery.event = { // Run delegates first; they may want to stop propagation beneath us i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { + if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } @@ -29609,15 +30850,20 @@ jQuery.event = { delegateCount = handlers.delegateCount, cur = event.target; + // Support (at least): Chrome, IE9 // Find delegate handlers // Black-hole SVG <use> instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { + // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; @@ -29627,7 +30873,7 @@ jQuery.event = { if ( matches[ sel ] === undefined ) { matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : + jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matches[ sel ] ) { @@ -29635,7 +30881,7 @@ jQuery.event = { } } if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); + handlerQueue.push( { elem: cur, handlers: matches } ); } } } @@ -29643,19 +30889,20 @@ jQuery.event = { // Add the remaining (directly-bound) handlers if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), fixHooks: {}, keyHooks: { - props: "char charCode key keyCode".split(" "), + props: "char charCode key keyCode".split( " " ), filter: function( event, original ) { // Add which for key events @@ -29668,7 +30915,8 @@ jQuery.event = { }, mouseHooks: { - props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + + "screenX screenY toElement" ).split( " " ), filter: function( event, original ) { var eventDoc, doc, body, button = original.button; @@ -29679,8 +30927,12 @@ jQuery.event = { doc = eventDoc.documentElement; body = eventDoc.body; - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); } // Add which for click: 1 === left; 2 === middle; 3 === right @@ -29737,10 +30989,12 @@ jQuery.event = { special: { load: { + // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { + // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== safeActiveElement() && this.focus ) { @@ -29760,6 +31014,7 @@ jQuery.event = { delegateType: "focusout" }, click: { + // For checkbox, fire native event so checked state will be right trigger: function() { if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { @@ -29784,41 +31039,21 @@ jQuery.event = { } } } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } } }; jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); + elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { + if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } @@ -29831,6 +31066,7 @@ jQuery.Event = function( src, props ) { // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && + // Support: Android<4.0 src.returnValue === false ? returnTrue : @@ -29856,6 +31092,7 @@ jQuery.Event = function( src, props ) { // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { + constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, @@ -29865,7 +31102,7 @@ jQuery.Event.prototype = { this.isDefaultPrevented = returnTrue; - if ( e && e.preventDefault ) { + if ( e ) { e.preventDefault(); } }, @@ -29874,7 +31111,7 @@ jQuery.Event.prototype = { this.isPropagationStopped = returnTrue; - if ( e && e.stopPropagation ) { + if ( e ) { e.stopPropagation(); } }, @@ -29883,7 +31120,7 @@ jQuery.Event.prototype = { this.isImmediatePropagationStopped = returnTrue; - if ( e && e.stopImmediatePropagation ) { + if ( e ) { e.stopImmediatePropagation(); } @@ -29892,8 +31129,14 @@ jQuery.Event.prototype = { }; // Create mouseenter/leave events using mouseover/out and event-time checks -// Support: Chrome 15+ -jQuery.each({ +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", @@ -29909,9 +31152,9 @@ jQuery.each({ related = event.relatedTarget, handleObj = event.handleObj; - // For mousenter/leave call the handler if related is outside the target. + // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; @@ -29919,115 +31162,32 @@ jQuery.each({ return ret; } }; -}); - -// Support: Firefox, Chrome, Safari -// Create "bubbling" focus and blur events -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - data_priv.remove( doc, fix ); - - } else { - data_priv.access( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } +} ); - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); +jQuery.fn.extend( { + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); + return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { + // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); @@ -30035,6 +31195,7 @@ jQuery.fn.extend({ return this; } if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) fn = selector; selector = undefined; @@ -30042,70 +31203,39 @@ jQuery.fn.extend({ if ( fn === false ) { fn = returnFalse; } - return this.each(function() { + return this.each( function() { jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } + } ); } -}); +} ); var - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /<script|<style|<link/i, + // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /^$|\/(?:java|ecma)script/i, rscriptTypeMasked = /^true\/(.*)/, - rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - - // Support: IE9 - option: [ 1, "<select multiple='multiple'>", "</select>" ], - - thead: [ 1, "<table>", "</table>" ], - col: [ 2, "<table><colgroup>", "</colgroup></table>" ], - tr: [ 2, "<table><tbody>", "</tbody></table>" ], - td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], - - _default: [ 0, "", "" ] - }; - -// Support: IE9 -wrapMap.optgroup = wrapMap.option; + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: 1.x compatibility // Manipulating tables requires a tbody function manipulationTarget( elem, content ) { return jQuery.nodeName( elem, "table" ) && jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem.getElementsByTagName( "tbody" )[ 0 ] || + elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { @@ -30114,24 +31244,12 @@ function restoreScript( elem ) { if ( match ) { elem.type = match[ 1 ]; } else { - elem.removeAttribute("type"); + elem.removeAttribute( "type" ); } return elem; } -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - data_priv.set( - elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) - ); - } -} - function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; @@ -30140,9 +31258,9 @@ function cloneCopyEvent( src, dest ) { } // 1. Copy private data: events, handlers, etc. - if ( data_priv.hasData( src ) ) { - pdataOld = data_priv.access( src ); - pdataCur = data_priv.set( dest, pdataOld ); + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; if ( events ) { @@ -30158,24 +31276,14 @@ function cloneCopyEvent( src, dest ) { } // 2. Copy user data - if ( data_user.hasData( src ) ) { - udataOld = data_user.access( src ); + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); - data_user.set( dest, udataCur ); + dataUser.set( dest, udataCur ); } } -function getAll( context, tag ) { - var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : - context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : - []; - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], ret ) : - ret; -} - // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); @@ -30190,7 +31298,122 @@ function fixInput( src, dest ) { } } -jQuery.extend({ +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1></$2>" ); + }, + clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), @@ -30233,102 +31456,14 @@ jQuery.extend({ return clone; }, - buildFragment: function( elems, context, scripts, selection ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; - }, - cleanData: function( elems ) { - var data, elem, type, key, + var data, elem, type, special = jQuery.event.special, i = 0; - for ( ; (elem = elems[ i ]) !== undefined; i++ ) { - if ( jQuery.acceptData( elem ) ) { - key = elem[ data_priv.expando ]; - - if ( key && (data = data_priv.cache[ key ]) ) { + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { @@ -30340,91 +31475,86 @@ jQuery.extend({ } } } - if ( data_priv.cache[ key ] ) { - // Discard any remaining `private` data - delete data_priv.cache[ key ]; - } + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; } } - // Discard any remaining `user` data - delete data_user.cache[ elem[ data_user.expando ] ]; } } -}); +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, -jQuery.fn.extend({ text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : - this.empty().each(function() { + this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } - }); + } ); }, null, value, arguments.length ); }, append: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } - }); + } ); }, prepend: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } - }); + } ); }, before: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } - }); + } ); }, after: function() { - return this.domManip( arguments, function( elem ) { + return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; + } ); }, empty: function() { var elem, i = 0; - for ( ; (elem = this[i]) != null; i++ ) { + for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks @@ -30442,9 +31572,9 @@ jQuery.fn.extend({ dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - return this.map(function() { + return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); + } ); }, html: function( value ) { @@ -30461,7 +31591,7 @@ jQuery.fn.extend({ if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - value = value.replace( rxhtmlTag, "<$1></$2>" ); + value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { @@ -30477,7 +31607,7 @@ jQuery.fn.extend({ elem = 0; // If using innerHTML throws an exception, use the fallback method - } catch( e ) {} + } catch ( e ) {} } if ( elem ) { @@ -30487,115 +31617,25 @@ jQuery.fn.extend({ }, replaceWith: function() { - var arg = arguments[ 0 ]; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; - - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } + var ignored = []; - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); - } - } - } + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); } } - } - return this; + // Force callback invocation + }, ignored ); } -}); +} ); -jQuery.each({ +jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", @@ -30620,28 +31660,29 @@ jQuery.each({ return this.pushStack( ret ); }; -}); +} ); var iframe, - elemdisplay = {}; + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; /** * Retrieve the actual display of a element * @param {String} name nodeName of the element * @param {Object} doc Document object */ + // Called only from within defaultDisplay function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - // Use of this method is a temporary fix (more like optimization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); + display = jQuery.css( elem[ 0 ], "display" ); // We don't have any data stored on the element, // so use "detach" method as fast way to get rid of the element @@ -30665,7 +31706,8 @@ function defaultDisplay( nodeName ) { if ( display === "none" || !display ) { // Use the already-created iframe if possible - iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); + iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) ) + .appendTo( doc.documentElement ); // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse doc = iframe[ 0 ].contentDocument; @@ -30684,21 +31726,159 @@ function defaultDisplay( nodeName ) { return display; } -var rmargin = (/^margin/); +var rmargin = ( /^margin/ ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { + // Support: IE<=11+, Firefox<=30+ (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - if ( elem.ownerDocument.defaultView.opener ) { - return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; } - return window.getComputedStyle( elem, null ); + return view.getComputedStyle( elem ); }; +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var documentElement = document.documentElement; + + + +( function() { + var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE9-11+ + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + + "padding:0;margin-top:1px;position:absolute"; + container.appendChild( div ); + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + div.style.cssText = + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" + + "position:relative;display:block;" + + "margin:auto;border:1px;padding:1px;" + + "top:1%;width:50%"; + div.innerHTML = ""; + documentElement.appendChild( container ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + reliableMarginLeftVal = divStyle.marginLeft === "2px"; + boxSizingReliableVal = divStyle.width === "4px"; + + // Support: Android 4.0 - 4.3 only + // Some styles come back with percentage values, even though they shouldn't + div.style.marginRight = "50%"; + pixelMarginRightVal = divStyle.marginRight === "4px"; + + documentElement.removeChild( container ); + } + + jQuery.extend( support, { + pixelPosition: function() { + + // This test is executed only once but we still do memoizing + // since we can use the boxSizingReliable pre-computing. + // No need to check if the test was already performed, though. + computeStyleTests(); + return pixelPositionVal; + }, + boxSizingReliable: function() { + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return boxSizingReliableVal; + }, + pixelMarginRight: function() { + + // Support: Android 4.0-4.3 + // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal + // since that compresses better and they're computed together anyway. + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return pixelMarginRightVal; + }, + reliableMarginLeft: function() { + + // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37 + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return reliableMarginLeftVal; + }, + reliableMarginRight: function() { + + // Support: Android 2.3 + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // This support function is only executed once so no memoizing is needed. + var ret, + marginDiv = div.appendChild( document.createElement( "div" ) ); + + // Reset CSS: box-sizing; display; margin; border; padding + marginDiv.style.cssText = div.style.cssText = + + // Support: Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;box-sizing:content-box;" + + "display:block;margin:0;border:0;padding:0"; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + documentElement.appendChild( container ); + + ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight ); + + documentElement.removeChild( container ); + div.removeChild( marginDiv ); + + return ret; + } + } ); +} )(); function curCSS( elem, name, computed ) { @@ -30706,24 +31886,25 @@ function curCSS( elem, name, computed ) { style = elem.style; computed = computed || getStyles( elem ); + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; - // Support: IE9 - // getPropertyValue is only needed for .css('filter') (#12537) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; + // Support: Opera 12.1x only + // Fall back to style even without computed + // computed is undefined for elems on document fragments + if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); } + // Support: IE9 + // getPropertyValue is only needed for .css('filter') (#12537) if ( computed ) { - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { - ret = jQuery.style( elem, name ); - } - - // Support: iOS < 6 // A tribute to the "awesome hack by Dean Edwards" - // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels - // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values - if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // http://dev.w3.org/csswg/cssom/#resolved-values + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { // Remember the original values width = style.width; @@ -30742,7 +31923,8 @@ function curCSS( elem, name, computed ) { } return ret !== undefined ? - // Support: IE + + // Support: IE9-11+ // IE returns zIndex value as an integer. ret + "" : ret; @@ -30750,10 +31932,12 @@ function curCSS( elem, name, computed ) { function addGetHookIf( conditionFn, hookFn ) { + // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { + // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; @@ -30761,129 +31945,18 @@ function addGetHookIf( conditionFn, hookFn ) { } // Hook needed; redefine it so that the support test is not executed again. - return (this.get = hookFn).apply( this, arguments ); + return ( this.get = hookFn ).apply( this, arguments ); } }; } -(function() { - var pixelPositionVal, boxSizingReliableVal, - docElem = document.documentElement, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - if ( !div.style ) { - return; - } - - // Support: IE9-11+ - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + - "position:absolute"; - container.appendChild( div ); - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computePixelPositionAndBoxSizingReliable() { - div.style.cssText = - // Support: Firefox<29, Android 2.3 - // Vendor-prefix box-sizing - "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + - "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + - "border:1px;padding:1px;width:4px;position:absolute"; - div.innerHTML = ""; - docElem.appendChild( container ); - - var divStyle = window.getComputedStyle( div, null ); - pixelPositionVal = divStyle.top !== "1%"; - boxSizingReliableVal = divStyle.width === "4px"; - - docElem.removeChild( container ); - } - - // Support: node.js jsdom - // Don't assume that getComputedStyle is a property of the global object - if ( window.getComputedStyle ) { - jQuery.extend( support, { - pixelPosition: function() { - - // This test is executed only once but we still do memoizing - // since we can use the boxSizingReliable pre-computing. - // No need to check if the test was already performed, though. - computePixelPositionAndBoxSizingReliable(); - return pixelPositionVal; - }, - boxSizingReliable: function() { - if ( boxSizingReliableVal == null ) { - computePixelPositionAndBoxSizingReliable(); - } - return boxSizingReliableVal; - }, - reliableMarginRight: function() { - - // Support: Android 2.3 - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. (#3333) - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - // This support function is only executed once so no memoizing is needed. - var ret, - marginDiv = div.appendChild( document.createElement( "div" ) ); - - // Reset CSS: box-sizing; display; margin; border; padding - marginDiv.style.cssText = div.style.cssText = - // Support: Firefox<29, Android 2.3 - // Vendor-prefix box-sizing - "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + - "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; - marginDiv.style.marginRight = marginDiv.style.width = "0"; - div.style.width = "1px"; - docElem.appendChild( container ); - - ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); - - docElem.removeChild( container ); - div.removeChild( marginDiv ); - - return ret; - } - }); - } -})(); - - -// A method for quickly swapping in/out CSS properties to get correct calculations. -jQuery.swap = function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - var - // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), - rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { @@ -30891,55 +31964,61 @@ var fontWeight: "400" }, - cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; // Return a css property mapped to a potentially vendor prefixed property -function vendorPropName( style, name ) { +function vendorPropName( name ) { // Shortcut for names that are not vendor prefixed - if ( name in style ) { + if ( name in emptyStyle ) { return name; } // Check for vendor prefixed names - var capName = name[0].toUpperCase() + name.slice(1), - origName = name, + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; - if ( name in style ) { + if ( name in emptyStyle ) { return name; } } - - return origName; } function setPositiveNumber( elem, value, subtract ) { - var matches = rnumsplit.exec( value ); + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation 4 : + // Otherwise initialize for horizontal or vertical properties name === "width" ? 1 : 0, val = 0; for ( ; i < 4; i += 2 ) { + // Both box models exclude margin, so add it if we want it if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content if ( extra === "content" ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); @@ -30950,6 +32029,7 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { + // At this point, extra isn't content, so add padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); @@ -30971,10 +32051,24 @@ function getWidthOrHeight( elem, name, extra ) { styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + // Support: IE11 only + // In IE 11 fullscreen elements inside of an iframe have + // 100x too small dimensions (gh-1764). + if ( document.msFullscreenElement && window.top !== window ) { + + // Support: IE11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + if ( elem.getClientRects().length ) { + val = Math.round( elem.getBoundingClientRect()[ name ] * 100 ); + } + } + // Some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name, styles ); if ( val < 0 || val == null ) { @@ -30982,7 +32076,7 @@ function getWidthOrHeight( elem, name, extra ) { } // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test(val) ) { + if ( rnumnonpx.test( val ) ) { return val; } @@ -31019,9 +32113,10 @@ function showHide( elements, show ) { continue; } - values[ index ] = data_priv.get( elem, "olddisplay" ); + values[ index ] = dataPriv.get( elem, "olddisplay" ); display = elem.style.display; if ( show ) { + // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not if ( !values[ index ] && display === "none" ) { @@ -31032,13 +32127,21 @@ function showHide( elements, show ) { // in a stylesheet to whatever the default browser style is // for such an element if ( elem.style.display === "" && isHidden( elem ) ) { - values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + values[ index ] = dataPriv.access( + elem, + "olddisplay", + defaultDisplay( elem.nodeName ) + ); } } else { hidden = isHidden( elem ); if ( display !== "none" || !hidden ) { - data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + dataPriv.set( + elem, + "olddisplay", + hidden ? display : jQuery.css( elem, "display" ) + ); } } } @@ -31058,7 +32161,7 @@ function showHide( elements, show ) { return elements; } -jQuery.extend({ +jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property @@ -31077,6 +32180,7 @@ jQuery.extend({ // Don't automatically add "px" to these possibly-unitless properties cssNumber: { + "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, @@ -31110,7 +32214,8 @@ jQuery.extend({ origName = jQuery.camelCase( name ), style = elem.style; - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + name = jQuery.cssProps[ origName ] || + ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; @@ -31120,8 +32225,9 @@ jQuery.extend({ type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && (ret = rrelNum.exec( value )) ) { - value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + // Fixes bug #9237 type = "number"; } @@ -31131,9 +32237,9 @@ jQuery.extend({ return; } - // If a number, add 'px' to the (except for certain CSS properties) - if ( type === "number" && !jQuery.cssNumber[ origName ] ) { - value += "px"; + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // Support: IE9-11+ @@ -31143,13 +32249,18 @@ jQuery.extend({ } // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + style[ name ] = value; } } else { + // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + return ret; } @@ -31163,7 +32274,8 @@ jQuery.extend({ origName = jQuery.camelCase( name ); // Make sure that we're working with the right name - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + name = jQuery.cssProps[ origName ] || + ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; @@ -31186,54 +32298,77 @@ jQuery.extend({ // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); - return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + return extra === true || isFinite( num ) ? num || 0 : val; } return val; } -}); +} ); -jQuery.each([ "height", "width" ], function( i, name ) { +jQuery.each( [ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? - jQuery.swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); - }) : - getWidthOrHeight( elem, name, extra ); + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + elem.offsetWidth === 0 ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + } ) : + getWidthOrHeight( elem, name, extra ); } }, set: function( elem, value, extra ) { - var styles = extra && getStyles( elem ); - return setPositiveNumber( elem, value, extra ? - augmentWidthOrHeight( + var matches, + styles = extra && getStyles( elem ), + subtract = extra && augmentWidthOrHeight( elem, name, extra, jQuery.css( elem, "boxSizing", false, styles ) === "border-box", styles - ) : 0 - ); + ); + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ name ] = value; + value = jQuery.css( elem, name ); + } + + return setPositiveNumber( elem, value, subtract ); } }; -}); +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); // Support: Android 2.3 jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, function( elem, computed ) { if ( computed ) { - return jQuery.swap( elem, { "display": "inline-block" }, + return swap( elem, { "display": "inline-block" }, curCSS, [ elem, "marginRight" ] ); } } ); // These hooks are used by animate to expand properties -jQuery.each({ +jQuery.each( { margin: "", padding: "", border: "Width" @@ -31244,7 +32379,7 @@ jQuery.each({ expanded = {}, // Assumes a single number if not a string - parts = typeof value === "string" ? value.split(" ") : [ value ]; + parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = @@ -31258,9 +32393,9 @@ jQuery.each({ if ( !rmargin.test( prefix ) ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, @@ -31294,15 +32429,15 @@ jQuery.fn.extend({ return state ? this.show() : this.hide(); } - return this.each(function() { + return this.each( function() { if ( isHidden( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } - }); + } ); } -}); +} ); function Tween( elem, options, prop, end, easing ) { @@ -31315,7 +32450,7 @@ Tween.prototype = { init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; - this.easing = easing || "swing"; + this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; @@ -31361,8 +32496,10 @@ Tween.propHooks = { get: function( tween ) { var result; - if ( tween.elem[ tween.prop ] != null && - (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } @@ -31371,16 +32508,20 @@ Tween.propHooks = { // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { + // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; @@ -31405,7 +32546,8 @@ jQuery.easing = { }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; - } + }, + _default: "swing" }; jQuery.fx = Tween.prototype.init; @@ -31419,65 +32561,13 @@ jQuery.fx.step = {}; var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, - rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), - rrun = /queueHooks$/, - animationPrefilters = [ defaultPrefilter ], - tweeners = { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ), - target = tween.cur(), - parts = rfxnum.exec( value ), - unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && - rfxnum.exec( jQuery.css( tween.elem, prop ) ), - scale = 1, - maxIterations = 20; - - if ( start && start[ 3 ] !== unit ) { - // Trust units reported by jQuery.css - unit = unit || start[ 3 ]; - - // Make sure we update the tween properties later on - parts = parts || []; - - // Iteratively approximate from a nonzero starting point - start = +target || 1; - - do { - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - start = start / scale; - jQuery.style( tween.elem, prop, start + unit ); - - // Update scale, tolerating zero or NaN from tween.cur(), - // break the loop if scale is unchanged or perfect, or if we've just had enough - } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); - } - - // Update tween properties - if ( parts ) { - start = tween.start = +start || +target || 0; - tween.unit = unit; - // If a +=/-= token was provided, we're doing a relative animation - tween.end = parts[ 1 ] ? - start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : - +parts[ 2 ]; - } - - return tween; - } ] - }; + rrun = /queueHooks$/; // Animations created synchronously will run synchronously function createFxNow() { - setTimeout(function() { + window.setTimeout( function() { fxNow = undefined; - }); + } ); return ( fxNow = jQuery.now() ); } @@ -31504,11 +32594,11 @@ function genFx( type, includeWidth ) { function createTween( value, prop, animation ) { var tween, - collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { - if ( (tween = collection[ index ].call( animation, prop, value )) ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; @@ -31523,7 +32613,7 @@ function defaultPrefilter( elem, props, opts ) { orig = {}, style = elem.style, hidden = elem.nodeType && isHidden( elem ), - dataShow = data_priv.get( elem, "fxshow" ); + dataShow = dataPriv.get( elem, "fxshow" ); // Handle queue: false promises if ( !opts.queue ) { @@ -31539,19 +32629,21 @@ function defaultPrefilter( elem, props, opts ) { } hooks.unqueued++; - anim.always(function() { + anim.always( function() { + // Ensure the complete handler is called before this completes - anim.always(function() { + anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } - }); - }); + } ); + } ); } // Height/width overflow pass if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE9-10 do not // change the overflow attribute when overflowX and @@ -31564,7 +32656,7 @@ function defaultPrefilter( elem, props, opts ) { // Test default display if display is currently "none" checkDisplay = display === "none" ? - data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; + dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { style.display = "inline-block"; @@ -31573,11 +32665,11 @@ function defaultPrefilter( elem, props, opts ) { if ( opts.overflow ) { style.overflow = "hidden"; - anim.always(function() { + anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; - }); + } ); } // show/hide pass @@ -31588,7 +32680,8 @@ function defaultPrefilter( elem, props, opts ) { toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { - // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden + // If there is dataShow left over from a stopped hide or show + // and we are going to proceed with show, we should pretend to be hidden if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; } else { @@ -31609,7 +32702,7 @@ function defaultPrefilter( elem, props, opts ) { hidden = dataShow.hidden; } } else { - dataShow = data_priv.access( elem, "fxshow", {} ); + dataShow = dataPriv.access( elem, "fxshow", {} ); } // Store state if its toggle - enables .stop().toggle() to "reverse" @@ -31619,18 +32712,18 @@ function defaultPrefilter( elem, props, opts ) { if ( hidden ) { jQuery( elem ).show(); } else { - anim.done(function() { + anim.done( function() { jQuery( elem ).hide(); - }); + } ); } - anim.done(function() { + anim.done( function() { var prop; - data_priv.remove( elem, "fxshow" ); + dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } - }); + } ); for ( prop in orig ) { tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); @@ -31644,7 +32737,7 @@ function defaultPrefilter( elem, props, opts ) { } // If this is a noop like .hide().hide(), restore an overwritten display value - } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { + } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) { style.display = display; } } @@ -31690,17 +32783,19 @@ function Animation( elem, properties, options ) { var result, stopped, index = 0, - length = animationPrefilters.length, + length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { + // Don't match elem in the :animated selector delete tick.elem; - }), + } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // Support: Android 2.3 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, @@ -31712,7 +32807,7 @@ function Animation( elem, properties, options ) { animation.tweens[ index ].run( percent ); } - deferred.notifyWith( elem, [ animation, percent, remaining ]); + deferred.notifyWith( elem, [ animation, percent, remaining ] ); if ( percent < 1 && length ) { return remaining; @@ -31721,10 +32816,13 @@ function Animation( elem, properties, options ) { return false; } }, - animation = deferred.promise({ + animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { specialEasing: {} }, options ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), @@ -31738,6 +32836,7 @@ function Animation( elem, properties, options ) { }, stop: function( gotoEnd ) { var index = 0, + // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; @@ -31751,20 +32850,25 @@ function Animation( elem, properties, options ) { // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } - }), + } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length ; index++ ) { - result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { + if ( jQuery.isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + jQuery.proxy( result.stop, result ); + } return result; } } @@ -31780,7 +32884,7 @@ function Animation( elem, properties, options ) { elem: elem, anim: animation, queue: animation.opts.queue - }) + } ) ); // attach callbacks from options @@ -31791,13 +32895,20 @@ function Animation( elem, properties, options ) { } jQuery.Animation = jQuery.extend( Animation, { + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, tweener: function( props, callback ) { if ( jQuery.isFunction( props ) ) { callback = props; props = [ "*" ]; } else { - props = props.split(" "); + props = props.match( rnotwhite ); } var prop, @@ -31806,19 +32917,21 @@ jQuery.Animation = jQuery.extend( Animation, { for ( ; index < length ; index++ ) { prop = props[ index ]; - tweeners[ prop ] = tweeners[ prop ] || []; - tweeners[ prop ].unshift( callback ); + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); } }, + prefilters: [ defaultPrefilter ], + prefilter: function( callback, prepend ) { if ( prepend ) { - animationPrefilters.unshift( callback ); + Animation.prefilters.unshift( callback ); } else { - animationPrefilters.push( callback ); + Animation.prefilters.push( callback ); } } -}); +} ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { @@ -31828,8 +32941,9 @@ jQuery.speed = function( speed, easing, fn ) { easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing }; - opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : - opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? + opt.duration : opt.duration in jQuery.fx.speeds ? + jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { @@ -31852,24 +32966,25 @@ jQuery.speed = function( speed, easing, fn ) { return opt; }; -jQuery.fn.extend({ +jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHidden ).css( "opacity", 0 ).show() // Animate to the value specified - .end().animate({ opacity: to }, speed, easing, callback ); + .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately - if ( empty || data_priv.get( this, "finish" ) ) { + if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; @@ -31895,11 +33010,11 @@ jQuery.fn.extend({ this.queue( type || "fx", [] ); } - return this.each(function() { + return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, - data = data_priv.get( this ); + data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { @@ -31914,7 +33029,9 @@ jQuery.fn.extend({ } for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); @@ -31927,15 +33044,15 @@ jQuery.fn.extend({ if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } - }); + } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } - return this.each(function() { + return this.each( function() { var index, - data = data_priv.get( this ), + data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, @@ -31968,24 +33085,24 @@ jQuery.fn.extend({ // Turn off finishing flag delete data.finish; - }); + } ); } -}); +} ); -jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; -}); +} ); // Generate shortcuts for custom animations -jQuery.each({ - slideDown: genFx("show"), - slideUp: genFx("hide"), - slideToggle: genFx("toggle"), +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } @@ -31993,7 +33110,7 @@ jQuery.each({ jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; -}); +} ); jQuery.timers = []; jQuery.fx.tick = function() { @@ -32005,6 +33122,7 @@ jQuery.fx.tick = function() { for ( ; i < timers.length; i++ ) { timer = timers[ i ]; + // Checks the timer has not already been removed if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); @@ -32027,42 +33145,43 @@ jQuery.fx.timer = function( timer ) { }; jQuery.fx.interval = 13; - jQuery.fx.start = function() { if ( !timerId ) { - timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); } }; jQuery.fx.stop = function() { - clearInterval( timerId ); + window.clearInterval( timerId ); + timerId = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, + // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. -// http://blindsignals.com/index.php/2009/07/jquery-delay/ +// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); + var timeout = window.setTimeout( next, time ); hooks.stop = function() { - clearTimeout( timeout ); + window.clearTimeout( timeout ); }; - }); + } ); }; -(function() { +( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); @@ -32088,36 +33207,36 @@ jQuery.fn.delay = function( time, type ) { input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; -})(); +} )(); -var nodeHook, boolHook, +var boolHook, attrHandle = jQuery.expr.attrHandle; -jQuery.fn.extend({ +jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { - return this.each(function() { + return this.each( function() { jQuery.removeAttr( this, name ); - }); + } ); } -}); +} ); -jQuery.extend({ +jQuery.extend( { attr: function( elem, name, value ) { - var hooks, ret, + var ret, hooks, nType = elem.nodeType; - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === strundefined ) { + if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } @@ -32126,32 +33245,47 @@ jQuery.extend({ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { - if ( value === null ) { jQuery.removeAttr( elem, name ); + return; + } - } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; - - } else { - elem.setAttribute( name, value + "" ); - return value; } - } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; + } - } else { - ret = jQuery.find.attr( elem, name ); + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, - // Non-existent attributes return null, we normalize to undefined - return ret == null ? - undefined : - ret; + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + jQuery.nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } } }, @@ -32161,11 +33295,12 @@ jQuery.extend({ attrNames = value && value.match( rnotwhite ); if ( attrNames && elem.nodeType === 1 ) { - while ( (name = attrNames[i++]) ) { + while ( ( name = attrNames[ i++ ] ) ) { propName = jQuery.propFix[ name ] || name; // Boolean attributes get special treatment (#10870) if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false elem[ propName ] = false; } @@ -32173,29 +33308,14 @@ jQuery.extend({ elem.removeAttribute( name ); } } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - jQuery.nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } } -}); +} ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { + // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { @@ -32210,6 +33330,7 @@ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle; if ( !isXML ) { + // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ name ]; attrHandle[ name ] = ret; @@ -32220,70 +33341,84 @@ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) } return ret; }; -}); +} ); -var rfocusable = /^(?:input|select|textarea|button)$/i; +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; -jQuery.fn.extend({ +jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { - return this.each(function() { + return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; - }); + } ); } -}); - -jQuery.extend({ - propFix: { - "for": "htmlFor", - "class": "className" - }, +} ); +jQuery.extend( { prop: function( elem, name, value ) { - var ret, hooks, notxml, + var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + if ( nType === 3 || nType === 8 || nType === 2 ) { return; } - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - if ( notxml ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { - return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? - ret : - ( elem[ name ] = value ); + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } - } else { - return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? - ret : - elem[ name ]; + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; } + + return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { - return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? - elem.tabIndex : - -1; + + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; } } + }, + + propFix: { + "for": "htmlFor", + "class": "className" } -}); +} ); if ( !support.optSelected ) { jQuery.propHooks.selected = { @@ -32297,7 +33432,7 @@ if ( !support.optSelected ) { }; } -jQuery.each([ +jQuery.each( [ "tabIndex", "readOnly", "maxLength", @@ -32310,49 +33445,48 @@ jQuery.each([ "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; -}); +} ); var rclass = /[\t\r\n\f]/g; -jQuery.fn.extend({ +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +jQuery.fn.extend( { addClass: function( value ) { - var classes, elem, cur, clazz, j, finalValue, - proceed = typeof value === "string" && value, - i = 0, - len = this.length; + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call( this, j, this.className ) ); - }); + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); } - if ( proceed ) { - // The disjunction here is for better compressibility (see removeClass) - classes = ( value || "" ).match( rnotwhite ) || []; + if ( typeof value === "string" && value ) { + classes = value.match( rnotwhite ) || []; - for ( ; i < len; i++ ) { - elem = this[ i ]; - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - " " - ); + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && + ( " " + curValue + " " ).replace( rclass, " " ); if ( cur ) { j = 0; - while ( (clazz = classes[j++]) ) { + while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } - // only assign if different to avoid unneeded rendering. + // Only assign if different to avoid unneeded rendering. finalValue = jQuery.trim( cur ); - if ( elem.className !== finalValue ) { - elem.className = finalValue; + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); } } } @@ -32362,40 +33496,43 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - var classes, elem, cur, clazz, j, finalValue, - proceed = arguments.length === 0 || typeof value === "string" && value, - i = 0, - len = this.length; + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call( this, j, this.className ) ); - }); + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); } - if ( proceed ) { - classes = ( value || "" ).match( rnotwhite ) || []; - for ( ; i < len; i++ ) { - elem = this[ i ]; + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnotwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - "" - ); + cur = elem.nodeType === 1 && + ( " " + curValue + " " ).replace( rclass, " " ); if ( cur ) { j = 0; - while ( (clazz = classes[j++]) ) { + while ( ( clazz = classes[ j++ ] ) ) { + // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. - finalValue = value ? jQuery.trim( cur ) : ""; - if ( elem.className !== finalValue ) { - elem.className = finalValue; + finalValue = jQuery.trim( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); } } } @@ -32412,20 +33549,26 @@ jQuery.fn.extend({ } if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); } - return this.each(function() { + return this.each( function() { + var className, i, self, classNames; + if ( type === "string" ) { + // Toggle individual class names - var className, - i = 0, - self = jQuery( this ), - classNames = value.match( rnotwhite ) || []; + i = 0; + self = jQuery( this ); + classNames = value.match( rnotwhite ) || []; + + while ( ( className = classNames[ i++ ] ) ) { - while ( (className = classNames[ i++ ]) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); @@ -32435,58 +33578,76 @@ jQuery.fn.extend({ } // Toggle whole class name - } else if ( type === strundefined || type === "boolean" ) { - if ( this.className ) { - // store className if set - data_priv.set( this, "__className__", this.className ); + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. - this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } } - }); + } ); }, hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + getClass( elem ) + " " ).replace( rclass, " " ) + .indexOf( className ) > -1 + ) { return true; } } return false; } -}); +} ); var rreturn = /\r/g; -jQuery.fn.extend({ +jQuery.fn.extend( { val: function( value ) { var hooks, ret, isFunction, - elem = this[0]; + elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { return ret; } ret = elem.value; return typeof ret === "string" ? + // Handle most common string cases - ret.replace(rreturn, "") : + ret.replace( rreturn, "" ) : + // Handle cases where value is null/undef or number ret == null ? "" : ret; } @@ -32496,7 +33657,7 @@ jQuery.fn.extend({ isFunction = jQuery.isFunction( value ); - return this.each(function( i ) { + return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { @@ -32519,29 +33680,27 @@ jQuery.fn.extend({ } else if ( jQuery.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; - }); + } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } - }); + } ); } -}); +} ); -jQuery.extend({ +jQuery.extend( { valHooks: { option: { get: function( elem ) { - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - // Support: IE10-11+ - // option.text throws exceptions (#14686, #14858) - jQuery.trim( jQuery.text( elem ) ); + + // Support: IE<11 + // option.value not trimmed (#14858) + return jQuery.trim( elem.value ); } }, select: { @@ -32560,11 +33719,14 @@ jQuery.extend({ for ( ; i < max; i++ ) { option = options[ i ]; - // IE6-9 doesn't update selected after form reset (#2551) + // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup - ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) && - ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + ( support.optDisabled ? + !option.disabled : option.getAttribute( "disabled" ) === null ) && + ( !option.parentNode.disabled || + !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); @@ -32590,7 +33752,9 @@ jQuery.extend({ while ( i-- ) { option = options[ i ]; - if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) { + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { optionSet = true; } } @@ -32603,23 +33767,23 @@ jQuery.extend({ } } } -}); +} ); // Radios and checkboxes getter/setter -jQuery.each([ "radio", "checkbox" ], function() { +jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute("value") === null ? "on" : elem.value; + return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } -}); +} ); @@ -32627,9 +33791,198 @@ jQuery.each([ "radio", "checkbox" ], function() { // Return jQuery for attributes-only inclusion -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + + // Previously, `originalEvent: {}` was set here, so stopPropagation call + // would not be triggered on donor event, since in our own + // jQuery.event.stopPropagation function we had a check for existence of + // originalEvent.stopPropagation method, so, consequently it would be a noop. + // + // But now, this "simulate" function is used only for events + // for which stopPropagation() is noop, so there is no need for that anymore. + // + // For the 1.x branch though, guard for "click" and "submit" + // events is still used, but was moved to jQuery.event.stopPropagation function + // because `originalEvent` should point to the original event for the constancy + // with other events and for more focused logic + } + ); + + jQuery.event.trigger( e, null, elem ); + + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + "change select submit keydown keypress keyup error contextmenu" ).split( " " ), + function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { @@ -32637,33 +33990,66 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl this.on( name, null, data, fn ) : this.trigger( name ); }; -}); +} ); -jQuery.fn.extend({ +jQuery.fn.extend( { hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - }, + } +} ); - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); - } -}); +support.focusin = "onfocusin" in window; + + +// Support: Firefox +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome, Safari +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + var nonce = jQuery.now(); -var rquery = (/\?/); +var rquery = ( /\?/ ); @@ -32676,15 +34062,14 @@ jQuery.parseJSON = function( data ) { // Cross-browser xml parsing jQuery.parseXML = function( data ) { - var xml, tmp; + var xml; if ( !data || typeof data !== "string" ) { return null; } // Support: IE9 try { - tmp = new DOMParser(); - xml = tmp.parseFromString( data, "text/xml" ); + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) { xml = undefined; } @@ -32700,11 +34085,11 @@ var rhash = /#.*$/, rts = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, - rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) @@ -32727,11 +34112,9 @@ var // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), - // Document location - ajaxLocation = window.location.href, - - // Segment location into parts - ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -32749,16 +34132,18 @@ function addToPrefiltersOrTransports( structure ) { dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression - while ( (dataType = dataTypes[i++]) ) { + while ( ( dataType = dataTypes[ i++ ] ) ) { + // Prepend if requested - if ( dataType[0] === "+" ) { + if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; - (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { - (structure[ dataType ] = structure[ dataType ] || []).push( func ); + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } @@ -32776,14 +34161,16 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } - }); + } ); return selected; } @@ -32799,7 +34186,7 @@ function ajaxExtend( target, src ) { for ( key in src ) { if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { @@ -32823,7 +34210,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) { while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } @@ -32841,9 +34228,10 @@ function ajaxHandleResponses( s, jqXHR, responses ) { if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { + // Try convertible dataTypes for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } @@ -32851,6 +34239,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) { firstDataType = type; } } + // Or just use first one finalDataType = finalDataType || firstDataType; } @@ -32872,6 +34261,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) { function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, + // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); @@ -32924,6 +34314,7 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) { conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { + // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; @@ -32943,13 +34334,16 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) { if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them - if ( conv && s[ "throws" ] ) { + if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { - return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; } } } @@ -32960,7 +34354,7 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) { return { state: "success", data: response }; } -jQuery.extend({ +jQuery.extend( { // Counter for holding the number of active queries active: 0, @@ -32970,9 +34364,9 @@ jQuery.extend({ etag: {}, ajaxSettings: { - url: ajaxLocation, + url: location.href, type: "GET", - isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, @@ -32998,9 +34392,9 @@ jQuery.extend({ }, contents: { - xml: /xml/, - html: /html/, - json: /json/ + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ }, responseFields: { @@ -33065,39 +34459,55 @@ jQuery.extend({ options = options || {}; var transport, + // URL without anti-cache param cacheURL, + // Response headers responseHeadersString, responseHeaders, + // timeout handle timeoutTimer, - // Cross-domain detection vars - parts, + + // Url cleanup var + urlAnchor, + // To know if global events are to be dispatched fireGlobals, + // Loop variable i, + // Create the final options object s = jQuery.ajaxSetup( {}, options ), + // Callbacks context callbackContext = s.context || s, + // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + // Deferreds deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks("once memory"), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks statusCode = s.statusCode || {}, + // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, + // The jqXHR state state = 0, + // Default abort message strAbort = "canceled", + // Fake xhr jqXHR = { readyState: 0, @@ -33108,8 +34518,8 @@ jQuery.extend({ if ( state === 2 ) { if ( !responseHeaders ) { responseHeaders = {}; - while ( (match = rheaders.exec( responseHeadersString )) ) { - responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; } } match = responseHeaders[ key.toLowerCase() ]; @@ -33146,10 +34556,12 @@ jQuery.extend({ if ( map ) { if ( state < 2 ) { for ( code in map ) { + // Lazy-add the new callback in a way that preserves old ones statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } else { + // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } @@ -33177,8 +34589,8 @@ jQuery.extend({ // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available - s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) - .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" ) + .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; @@ -33186,14 +34598,26 @@ jQuery.extend({ // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; - // A cross-domain request is in order when we have a protocol:host:port mismatch + // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { - parts = rurl.exec( s.url.toLowerCase() ); - s.crossDomain = !!( parts && - ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || - ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== - ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) - ); + urlAnchor = document.createElement( "a" ); + + // Support: IE8-11+ + // IE throws exception if url is malformed, e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE8-11+ + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } } // Convert data if not already a string @@ -33215,7 +34639,7 @@ jQuery.extend({ // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger("ajaxStart"); + jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type @@ -33234,6 +34658,7 @@ jQuery.extend({ // If data is available, append data to url if ( s.data ) { cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); + // #9682: remove data so that it's not used in an eventual retry delete s.data; } @@ -33268,8 +34693,9 @@ jQuery.extend({ // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? - s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); @@ -33279,7 +34705,9 @@ jQuery.extend({ } // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return return jqXHR.abort(); } @@ -33305,10 +34733,16 @@ jQuery.extend({ if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } + + // If request was aborted inside ajaxSend, stop there + if ( state === 2 ) { + return jqXHR; + } + // Timeout if ( s.async && s.timeout > 0 ) { - timeoutTimer = setTimeout(function() { - jqXHR.abort("timeout"); + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); }, s.timeout ); } @@ -33316,9 +34750,11 @@ jQuery.extend({ state = 1; transport.send( requestHeaders, done ); } catch ( e ) { + // Propagate exception as error if not done if ( state < 2 ) { done( -1, e ); + // Simply rethrow otherwise } else { throw e; @@ -33341,7 +34777,7 @@ jQuery.extend({ // Clear timeout if it exists if ( timeoutTimer ) { - clearTimeout( timeoutTimer ); + window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection @@ -33370,11 +34806,11 @@ jQuery.extend({ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { - modified = jqXHR.getResponseHeader("Last-Modified"); + modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } - modified = jqXHR.getResponseHeader("etag"); + modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } @@ -33396,6 +34832,7 @@ jQuery.extend({ isSuccess = !error; } } else { + // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { @@ -33431,9 +34868,10 @@ jQuery.extend({ if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter if ( !( --jQuery.active ) ) { - jQuery.event.trigger("ajaxStop"); + jQuery.event.trigger( "ajaxStop" ); } } } @@ -33448,10 +34886,11 @@ jQuery.extend({ getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } -}); +} ); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { + // Shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { type = type || callback; @@ -33459,37 +34898,40 @@ jQuery.each( [ "get", "post" ], function( i, method ) { data = undefined; } - return jQuery.ajax({ + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback - }); + }, jQuery.isPlainObject( url ) && url ) ); }; -}); +} ); jQuery._evalUrl = function( url ) { - return jQuery.ajax({ + return jQuery.ajax( { url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", async: false, global: false, "throws": true - }); + } ); }; -jQuery.fn.extend({ +jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( jQuery.isFunction( html ) ) { - return this.each(function( i ) { - jQuery( this ).wrapAll( html.call(this, i) ); - }); + return this.each( function( i ) { + jQuery( this ).wrapAll( html.call( this, i ) ); + } ); } if ( this[ 0 ] ) { @@ -33501,7 +34943,7 @@ jQuery.fn.extend({ wrap.insertBefore( this[ 0 ] ); } - wrap.map(function() { + wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { @@ -33509,7 +34951,7 @@ jQuery.fn.extend({ } return elem; - }).append( this ); + } ).append( this ); } return this; @@ -33517,12 +34959,12 @@ jQuery.fn.extend({ wrapInner: function( html ) { if ( jQuery.isFunction( html ) ) { - return this.each(function( i ) { - jQuery( this ).wrapInner( html.call(this, i) ); - }); + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); } - return this.each(function() { + return this.each( function() { var self = jQuery( this ), contents = self.contents(); @@ -33532,34 +34974,37 @@ jQuery.fn.extend({ } else { self.append( html ); } - }); + } ); }, wrap: function( html ) { var isFunction = jQuery.isFunction( html ); - return this.each(function( i ) { - jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); - }); + return this.each( function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); + } ); }, unwrap: function() { - return this.parent().each(function() { + return this.parent().each( function() { if ( !jQuery.nodeName( this, "body" ) ) { jQuery( this ).replaceWith( this.childNodes ); } - }).end(); + } ).end(); } -}); +} ); jQuery.expr.filters.hidden = function( elem ) { - // Support: Opera <= 12.12 - // Opera reports offsetWidths and offsetHeights less than zero on some elements - return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; + return !jQuery.expr.filters.visible( elem ); }; jQuery.expr.filters.visible = function( elem ) { - return !jQuery.expr.filters.hidden( elem ); + + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + // Use OR instead of AND as the element is not visible if either is true + // See tickets #10406 and #13132 + return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0; }; @@ -33575,25 +35020,35 @@ function buildParams( prefix, obj, traditional, add ) { var name; if ( jQuery.isArray( obj ) ) { + // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. add( prefix, v ); } else { + // Item is non-scalar (array or object), encode its numeric index. - buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); } - }); + } ); } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { + // Serialize scalar item. add( prefix, obj ); } @@ -33605,6 +35060,7 @@ jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, value ) { + // If value is a function, invoke it and return its value value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); @@ -33617,12 +35073,14 @@ jQuery.param = function( a, traditional ) { // If an array was passed in, assume that it is an array of form elements. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); - }); + } ); } else { + // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { @@ -33634,25 +35092,26 @@ jQuery.param = function( a, traditional ) { return s.join( "&" ).replace( r20, "+" ); }; -jQuery.fn.extend({ +jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { - return this.map(function() { + return this.map( function() { + // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; - }) - .filter(function() { + } ) + .filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); - }) - .map(function( i, elem ) { + } ) + .map( function( i, elem ) { var val = jQuery( this ).val(); return val == null ? @@ -33660,56 +35119,50 @@ jQuery.fn.extend({ jQuery.isArray( val ) ? jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }) : + } ) : { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }).get(); + } ).get(); } -}); +} ); jQuery.ajaxSettings.xhr = function() { try { - return new XMLHttpRequest(); - } catch( e ) {} + return new window.XMLHttpRequest(); + } catch ( e ) {} }; -var xhrId = 0, - xhrCallbacks = {}, - xhrSuccessStatus = { - // file protocol always yields status code 0, assume 200 +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 0: 200, + // Support: IE9 // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); -// Support: IE9 -// Open requests must be manually aborted on unload (#5280) -// See https://support.microsoft.com/kb/2856746 for more info -if ( window.attachEvent ) { - window.attachEvent( "onunload", function() { - for ( var key in xhrCallbacks ) { - xhrCallbacks[ key ](); - } - }); -} - support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; -jQuery.ajaxTransport(function( options ) { - var callback; +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, - xhr = options.xhr(), - id = ++xhrId; - - xhr.open( options.type, options.url, options.async, options.username, options.password ); + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); // Apply custom fields if provided if ( options.xhrFields ) { @@ -33728,8 +35181,8 @@ jQuery.ajaxTransport(function( options ) { // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers["X-Requested-With"] ) { - headers["X-Requested-With"] = "XMLHttpRequest"; + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers @@ -33741,27 +35194,38 @@ jQuery.ajaxTransport(function( options ) { callback = function( type ) { return function() { if ( callback ) { - delete xhrCallbacks[ id ]; - callback = xhr.onload = xhr.onerror = null; + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { - complete( - // file: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); + + // Support: IE9 + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, - // Support: IE9 - // Accessing binary-data responseText throws an exception - // (#11426) - typeof xhr.responseText === "string" ? { - text: xhr.responseText - } : undefined, + + // Support: IE9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } @@ -33771,15 +35235,41 @@ jQuery.ajaxTransport(function( options ) { // Listen to events xhr.onload = callback(); - xhr.onerror = callback("error"); + errorCallback = xhr.onerror = callback( "error" ); + + // Support: IE9 + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } // Create the abort callback - callback = xhrCallbacks[ id ] = callback("abort"); + callback = callback( "abort" ); try { + // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { + // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; @@ -33794,18 +35284,19 @@ jQuery.ajaxTransport(function( options ) { } }; } -}); +} ); // Install script dataType -jQuery.ajaxSetup({ +jQuery.ajaxSetup( { accepts: { - script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" }, contents: { - script: /(?:java|ecma)script/ + script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { @@ -33813,7 +35304,7 @@ jQuery.ajaxSetup({ return text; } } -}); +} ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { @@ -33823,20 +35314,20 @@ jQuery.ajaxPrefilter( "script", function( s ) { if ( s.crossDomain ) { s.type = "GET"; } -}); +} ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { + // This transport only deals with cross domain requests if ( s.crossDomain ) { var script, callback; return { send: function( _, complete ) { - script = jQuery("<script>").prop({ - async: true, + script = jQuery( "<script>" ).prop( { charset: s.scriptCharset, src: s.url - }).on( + } ).on( "load error", callback = function( evt ) { script.remove(); @@ -33846,6 +35337,8 @@ jQuery.ajaxTransport( "script", function( s ) { } } ); + + // Use native DOM manipulation to avoid our domManip AJAX trickery document.head.appendChild( script[ 0 ] ); }, abort: function() { @@ -33855,7 +35348,7 @@ jQuery.ajaxTransport( "script", function( s ) { } }; } -}); +} ); @@ -33864,14 +35357,14 @@ var oldCallbacks = [], rjsonp = /(=)\?(?=&|$)|\?\?/; // Default jsonp settings -jQuery.ajaxSetup({ +jQuery.ajaxSetup( { jsonp: "callback", jsonpCallback: function() { var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); this[ callback ] = true; return callback; } -}); +} ); // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { @@ -33879,7 +35372,10 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? "url" : - typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" + typeof s.data === "string" && + ( s.contentType || "" ) + .indexOf( "application/x-www-form-urlencoded" ) === 0 && + rjsonp.test( s.data ) && "data" ); // Handle iff the expected data type is "jsonp" or we have a parameter to set @@ -33898,14 +35394,14 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { } // Use data converter to retrieve json after script execution - s.converters["script json"] = function() { + s.converters[ "script json" ] = function() { if ( !responseContainer ) { jQuery.error( callbackName + " was not called" ); } return responseContainer[ 0 ]; }; - // force json dataType + // Force json dataType s.dataTypes[ 0 ] = "json"; // Install callback @@ -33915,16 +35411,24 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { }; // Clean-up function (fires after converters) - jqXHR.always(function() { - // Restore preexisting value - window[ callbackName ] = overwritten; + jqXHR.always( function() { + + // If previous value didn't exist - remove it + if ( overwritten === undefined ) { + jQuery( window ).removeProp( callbackName ); + + // Otherwise restore preexisting value + } else { + window[ callbackName ] = overwritten; + } // Save back as free if ( s[ callbackName ] ) { - // make sure that re-using the options doesn't screw things around + + // Make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; - // save the callback name for future use + // Save the callback name for future use oldCallbacks.push( callbackName ); } @@ -33934,18 +35438,31 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { } responseContainer = overwritten = undefined; - }); + } ); // Delegate to script return "script"; } -}); +} ); + + +// Support: Safari 8+ +// In Safari 8 documents created via document.implementation.createHTMLDocument +// collapse sibling forms: the second one becomes a child of the first one. +// Because of that, this security measure has to be disabled in Safari 8. +// https://bugs.webkit.org/show_bug.cgi?id=137337 +support.createHTMLDocument = ( function() { + var body = document.implementation.createHTMLDocument( "" ).body; + body.innerHTML = "<form></form><form></form>"; + return body.childNodes.length === 2; +} )(); -// data: string of html -// context (optional): If specified, the fragment will be created in this context, defaults to document +// Argument "data" should be string of html +// context (optional): If specified, the fragment will be created in this context, +// defaults to document // keepScripts (optional): If true, will include scripts passed in the html string jQuery.parseHTML = function( data, context, keepScripts ) { if ( !data || typeof data !== "string" ) { @@ -33955,17 +35472,22 @@ jQuery.parseHTML = function( data, context, keepScripts ) { keepScripts = context; context = false; } - context = context || document; + + // Stop scripts or inline event handlers from being executed immediately + // by using document.implementation + context = context || ( support.createHTMLDocument ? + document.implementation.createHTMLDocument( "" ) : + document ); var parsed = rsingleTag.exec( data ), scripts = !keepScripts && []; // Single tag if ( parsed ) { - return [ context.createElement( parsed[1] ) ]; + return [ context.createElement( parsed[ 1 ] ) ]; } - parsed = jQuery.buildFragment( [ data ], context, scripts ); + parsed = buildFragment( [ data ], context, scripts ); if ( scripts && scripts.length ) { jQuery( scripts ).remove(); @@ -33988,9 +35510,9 @@ jQuery.fn.load = function( url, params, callback ) { var selector, type, response, self = this, - off = url.indexOf(" "); + off = url.indexOf( " " ); - if ( off >= 0 ) { + if ( off > -1 ) { selector = jQuery.trim( url.slice( off ) ); url = url.slice( 0, off ); } @@ -34009,14 +35531,16 @@ jQuery.fn.load = function( url, params, callback ) { // If we have elements to modify, make the request if ( self.length > 0 ) { - jQuery.ajax({ + jQuery.ajax( { url: url, - // if "type" variable is undefined, then "GET" method will be used - type: type, + // If "type" variable is undefined, then "GET" method will be used. + // Make value of this field explicit since + // user can override it through ajaxSetup method + type: type || "GET", dataType: "html", data: params - }).done(function( responseText ) { + } ).done( function( responseText ) { // Save response for use in complete callback response = arguments; @@ -34025,14 +35549,19 @@ jQuery.fn.load = function( url, params, callback ) { // If a selector was specified, locate the right elements in a dummy div // Exclude scripts to avoid IE 'Permission Denied' errors - jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : + jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : // Otherwise use the full result responseText ); - }).complete( callback && function( jqXHR, status ) { - self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); - }); + // If the request succeeds, this function gets "data", "status", "jqXHR" + // but they are ignored because response was set above. + // If it fails, this function gets "jqXHR", "status", "error" + } ).always( callback && function( jqXHR, status ) { + self.each( function() { + callback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] ); + } ); + } ); } return this; @@ -34042,26 +35571,31 @@ jQuery.fn.load = function( url, params, callback ) { // Attach a bunch of functions for handling common AJAX events -jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { +jQuery.each( [ + "ajaxStart", + "ajaxStop", + "ajaxComplete", + "ajaxError", + "ajaxSuccess", + "ajaxSend" +], function( i, type ) { jQuery.fn[ type ] = function( fn ) { return this.on( type, fn ); }; -}); +} ); jQuery.expr.filters.animated = function( elem ) { - return jQuery.grep(jQuery.timers, function( fn ) { + return jQuery.grep( jQuery.timers, function( fn ) { return elem === fn.elem; - }).length; + } ).length; }; -var docElem = window.document.documentElement; - /** * Gets a window from an element */ @@ -34085,7 +35619,7 @@ jQuery.offset = { curCSSTop = jQuery.css( elem, "top" ); curCSSLeft = jQuery.css( elem, "left" ); calculatePosition = ( position === "absolute" || position === "fixed" ) && - ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; + ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; // Need to be able to calculate position if either // top or left is auto and position is either absolute or fixed @@ -34100,7 +35634,9 @@ jQuery.offset = { } if ( jQuery.isFunction( options ) ) { - options = options.call( elem, i, curOffset ); + + // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) + options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); } if ( options.top != null ) { @@ -34119,14 +35655,14 @@ jQuery.offset = { } }; -jQuery.fn.extend({ +jQuery.fn.extend( { offset: function( options ) { if ( arguments.length ) { return options === undefined ? this : - this.each(function( i ) { + this.each( function( i ) { jQuery.offset.setOffset( this, options, i ); - }); + } ); } var docElem, win, @@ -34145,11 +35681,7 @@ jQuery.fn.extend({ return box; } - // Support: BlackBerry 5, iOS 3 (original iPhone) - // If we don't have gBCR, just use 0,0 rather than error - if ( typeof elem.getBoundingClientRect !== strundefined ) { - box = elem.getBoundingClientRect(); - } + box = elem.getBoundingClientRect(); win = getWindow( doc ); return { top: box.top + win.pageYOffset - docElem.clientTop, @@ -34166,12 +35698,15 @@ jQuery.fn.extend({ elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; - // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, + // because it is its only offset parent if ( jQuery.css( elem, "position" ) === "fixed" ) { + // Assume getBoundingClientRect is there when computed position is fixed offset = elem.getBoundingClientRect(); } else { + // Get *real* offsetParent offsetParent = this.offsetParent(); @@ -34193,18 +35728,28 @@ jQuery.fn.extend({ }; }, + // This method will return documentElement in the following cases: + // 1) For the element inside the iframe without offsetParent, this method will return + // documentElement of the parent window + // 2) For the hidden or detached element + // 3) For body or html element, i.e. in case of the html node - it will return itself + // + // but those exceptions were never presented as a real life use-cases + // and might be considered as more preferable results. + // + // This logic, however, is not guaranteed and can change at any point in the future offsetParent: function() { - return this.map(function() { - var offsetParent = this.offsetParent || docElem; + return this.map( function() { + var offsetParent = this.offsetParent; - while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { + while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.offsetParent; } - return offsetParent || docElem; - }); + return offsetParent || documentElement; + } ); } -}); +} ); // Create scrollLeft and scrollTop methods jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { @@ -34220,18 +35765,18 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( if ( win ) { win.scrollTo( - !top ? val : window.pageXOffset, - top ? val : window.pageYOffset + !top ? val : win.pageXOffset, + top ? val : win.pageYOffset ); } else { elem[ method ] = val; } - }, method, val, arguments.length, null ); + }, method, val, arguments.length ); }; -}); +} ); -// Support: Safari<7+, Chrome<37+ +// Support: Safari<7-8+, Chrome<37-44+ // Add the top/left cssHooks using jQuery.fn.position // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 @@ -34242,6 +35787,7 @@ jQuery.each( [ "top", "left" ], function( i, prop ) { function( elem, computed ) { if ( computed ) { computed = curCSS( elem, prop ); + // If curCSS returns percentage, fallback to offset return rnumnonpx.test( computed ) ? jQuery( elem ).position()[ prop ] + "px" : @@ -34249,12 +35795,14 @@ jQuery.each( [ "top", "left" ], function( i, prop ) { } } ); -}); +} ); // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { - jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, + function( defaultExtra, funcName ) { + // Margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), @@ -34264,6 +35812,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { var doc; if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there // isn't a whole lot we can do. See pull request at this URL for discussion: // https://github.com/jquery/jquery/pull/764 @@ -34284,6 +35833,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { } return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat jQuery.css( elem, type, extra ) : @@ -34291,14 +35841,33 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.style( elem, type, value, extra ); }, type, chainable ? margin : undefined, chainable, null ); }; - }); -}); + } ); +} ); -// The number of elements contained in the matched element set -jQuery.fn.size = function() { - return this.length; -}; +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + }, + size: function() { + return this.length; + } +} ); jQuery.fn.andSelf = jQuery.fn.addBack; @@ -34321,13 +35890,13 @@ jQuery.fn.andSelf = jQuery.fn.addBack; if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; - }); + } ); } - var + // Map over jQuery in case of overwrite _jQuery = window.jQuery, @@ -34349,26 +35918,22 @@ jQuery.noConflict = function( deep ) { // Expose jQuery and $ identifiers, even in AMD // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) -if ( typeof noGlobal === strundefined ) { +if ( !noGlobal ) { window.jQuery = window.$ = jQuery; } - - - return jQuery; - })); },{}],"lodash":[function(require,module,exports){ (function (global){ /** * @license - * lodash 3.10.1 (Custom Build) <https://lodash.com/> - * Build: `lodash modern -d -o ./index.js` - * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/> + * lodash 4.5.1 (Custom Build) <https://lodash.com/> + * Build: `lodash -d -o ./foo/lodash.js` + * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license <https://lodash.com/license> */ ;(function() { @@ -34377,7 +35942,7 @@ return jQuery; var undefined; /** Used as the semantic version number. */ - var VERSION = '3.10.1'; + var VERSION = '4.5.1'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -34388,13 +35953,18 @@ return jQuery; PARTIAL_FLAG = 32, PARTIAL_RIGHT_FLAG = 64, ARY_FLAG = 128, - REARG_FLAG = 256; + REARG_FLAG = 256, + FLIP_FLAG = 512; + + /** Used to compose bitmasks for comparison styles. */ + var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; - /** Used as default options for `_.trunc`. */ + /** Used as default options for `_.truncate`. */ var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = '...'; - /** Used to detect when a function becomes hot. */ + /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 150, HOT_SPAN = 16; @@ -34403,11 +35973,26 @@ return jQuery; /** Used to indicate the type of lazy iteratees. */ var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2; + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + /** Used as the internal argument placeholder. */ var PLACEHOLDER = '__lodash_placeholder__'; @@ -34418,13 +36003,16 @@ return jQuery; dateTag = '[object Date]', errorTag = '[object Error]', funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', mapTag = '[object Map]', numberTag = '[object Number]', objectTag = '[object Object]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; var arrayBufferTag = '[object ArrayBuffer]', float32Tag = '[object Float32Array]', @@ -34454,19 +36042,18 @@ return jQuery; reInterpolate = /<%=([\s\S]+?)%>/g; /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; - /** - * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) - * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). - */ - var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, - reHasRegExpChars = RegExp(reRegExpChars.source); + /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); - /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ - var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g, + reTrimStart = /^\s+/, + reTrimEnd = /\s+$/; /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; @@ -34478,13 +36065,22 @@ return jQuery; var reFlags = /\w*$/; /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0[xX]/; + var reHasHexPrefix = /^0x/i; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; /** Used to detect host constructors (Safari > 5). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + /** Used to detect unsigned integer values. */ - var reIsUint = /^\d+$/; + var reIsUint = /^(?:0|[1-9]\d*)$/; /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; @@ -34495,21 +36091,81 @@ return jQuery; /** Used to match unescaped characters in compiled string literals. */ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - /** Used to match words to create compound words. */ - var reWords = (function() { - var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', - lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; - - return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); - }()); + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', + rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + + /** Used to match non-compound words composed of alphanumeric characters. */ + var reBasicWord = /[a-zA-Z0-9]+/g; + + /** Used to match complex or compound words. */ + var reComplexWord = RegExp([ + rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', + rsUpper + '?' + rsLowerMisc + '+', + rsUpper + '+', + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; /** Used to assign default `context` object properties. */ var contextProps = [ - 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', - 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + 'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_', + 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' ]; /** Used to make template sourceURLs easier to identify. */ @@ -34537,12 +36193,13 @@ return jQuery; cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[stringTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[mapTag] = cloneableTags[numberTag] = + cloneableTags[objectTag] = cloneableTags[regexpTag] = + cloneableTags[setTag] = cloneableTags[stringTag] = + cloneableTags[symbolTag] = cloneableTags[uint8Tag] = + cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = + cloneableTags[uint32Tag] = true; cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[mapTag] = cloneableTags[setTag] = cloneableTags[weakMapTag] = false; /** Used to map latin-1 supplementary letters to basic latin letters. */ @@ -34592,15 +36249,6 @@ return jQuery; 'object': true }; - /** Used to escape characters for inclusion in compiled regexes. */ - var regexpEscapes = { - '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', - '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', - 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', - 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', - 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' - }; - /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { '\\': '\\', @@ -34611,23 +36259,36 @@ return jQuery; '\u2029': 'u2029' }; + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; /** Detect free variable `global` from Node.js. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); /** Detect free variable `self`. */ - var freeSelf = objectTypes[typeof self] && self && self.Object && self; + var freeSelf = checkGlobal(objectTypes[typeof self] && self); /** Detect free variable `window`. */ - var freeWindow = objectTypes[typeof window] && window && window.Object && window; + var freeWindow = checkGlobal(objectTypes[typeof window] && window); - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + /** Detect `this` as the global object. */ + var thisGlobal = checkGlobal(objectTypes[typeof this] && this); /** * Used as a reference to the global object. @@ -34635,46 +36296,386 @@ return jQuery; * The `this` value is used if it's the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); /*--------------------------------------------------------------------------*/ /** - * The base implementation of `compareAscending` which compares values and - * sorts them in ascending order without guaranteeing a stable sort. + * Adds the key-value `pair` to `map`. * * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. */ - function baseCompareAscending(value, other) { - if (value !== other) { - var valIsNull = value === null, - valIsUndef = value === undefined, - valIsReflexive = value === value; + function addMapEntry(map, pair) { + map.set(pair[0], pair[1]); + return map; + } - var othIsNull = other === null, - othIsUndef = other === undefined, - othIsReflexive = other === other; + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + set.add(value); + return set; + } - if ((value > other && !othIsNull) || !valIsReflexive || - (valIsNull && !othIsUndef && othIsReflexive) || - (valIsUndef && othIsReflexive)) { - return 1; + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; } - if ((value < other && !valIsNull) || !othIsReflexive || - (othIsNull && !valIsUndef && valIsReflexive) || - (othIsUndef && valIsReflexive)) { - return -1; + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; } } - return 0; + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + return !!array.length && baseIndexOf(array, value, 0) > -1; + } + + /** + * A specialized version of `_.includesWith` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; } /** * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for callback shorthands and `this` binding. + * support for iteratee shorthands. * * @private * @param {Array} array The array to search. @@ -34695,7 +36696,7 @@ return jQuery; } /** - * The base implementation of `_.indexOf` without support for binary searches. + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. * * @private * @param {Array} array The array to search. @@ -34719,89 +36720,219 @@ return jQuery; } /** - * The base implementation of `_.isFunction` without support for environments - * with incorrect `typeof` results. + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. */ - function baseIsFunction(value) { - // Avoid a Chakra JIT bug in compatibility modes of IE 11. - // See https://github.com/jashkenas/underscore/issues/1621 for more details. - return typeof value == 'function' || false; + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; } /** - * Converts `value` to a string if it's not one. An empty string is returned - * for `null` or `undefined` values. + * The base implementation of `_.sum` without support for iteratee shorthands. * * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. */ - function baseToString(value) { - return value == null ? '' : (value + ''); + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; } /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first character - * of `string` that is not found in `chars`. + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. * * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the first character not found in `chars`. + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the new array of key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.unary` without support for storing wrapper metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. */ - function charsLeftIndex(string, chars) { + function charsStartIndex(strSymbols, chrSymbols) { var index = -1, - length = string.length; + length = strSymbols.length; - while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} return index; } /** - * Used by `_.trim` and `_.trimRight` to get the index of the last character - * of `string` that is not found in `chars`. + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. * * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the last character not found in `chars`. + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. */ - function charsRightIndex(string, chars) { - var index = string.length; + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; - while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} return index; } /** - * Used by `_.sortBy` to compare transformed elements of a collection and stable - * sort them in ascending order. + * Checks if `value` is a global object. * * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @returns {number} Returns the sort order indicator for `object`. + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ + function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; } /** - * Used by `_.sortByOrder` to compare multiple properties of a value to another + * Used by `_.orderBy` to compare multiple properties of a value to another * and stable sort them. * - * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, - * a value is sorted in ascending order if its corresponding order is "asc", and - * descending if "desc". + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. - * @param {boolean[]} orders The order to sort by for each property. + * @param {boolean[]|string[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ function compareMultiple(object, other, orders) { @@ -34812,13 +36943,13 @@ return jQuery; ordersLength = orders.length; while (++index < length) { - var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + var result = compareAscending(objCriteria[index], othCriteria[index]); if (result) { if (index >= ordersLength) { return result; } var order = orders[index]; - return result * ((order === 'asc' || order === true) ? 1 : -1); + return result * (order == 'desc' ? -1 : 1); } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications @@ -34832,6 +36963,26 @@ return jQuery; } /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + result++; + } + } + return result; + } + + /** * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. * * @private @@ -34854,24 +37005,6 @@ return jQuery; } /** - * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. - * - * @private - * @param {string} chr The matched character to escape. - * @param {string} leadingChar The capture group for a leading character. - * @param {string} whitespaceChar The capture group for a whitespace character. - * @returns {string} Returns the escaped character. - */ - function escapeRegExpChar(chr, leadingChar, whitespaceChar) { - if (leadingChar) { - chr = regexpEscapes[chr]; - } else if (whitespaceChar) { - chr = stringEscapes[chr]; - } - return '\\' + chr; - } - - /** * Used by `_.template` to escape characters for inclusion in compiled string literals. * * @private @@ -34905,27 +37038,70 @@ return jQuery; } /** - * Checks if `value` is object-like. + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ - function isObjectLike(value) { - return !!value && typeof value == 'object'; + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; } /** - * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a - * character code is whitespace. + * Converts `iterator` to an array. * * @private - * @param {number} charCode The character code to inspect. - * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. */ - function isSpace(charCode) { - return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || - (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to an array. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the converted array. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; } /** @@ -34944,7 +37120,8 @@ return jQuery; result = []; while (++index < length) { - if (array[index] === placeholder) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { array[index] = PLACEHOLDER; result[++resIndex] = index; } @@ -34953,62 +37130,49 @@ return jQuery; } /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. + * Converts `set` to an array. * * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. + * @param {Object} set The set to convert. + * @returns {Array} Returns the converted array. */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; + function setToArray(set) { + var index = -1, + result = Array(set.size); - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } + set.forEach(function(value) { + result[++index] = value; + }); return result; } /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace - * character of `string`. + * Gets the number of symbols in `string`. * * @private * @param {string} string The string to inspect. - * @returns {number} Returns the index of the first non-whitespace character. + * @returns {number} Returns the string size. */ - function trimmedLeftIndex(string) { - var index = -1, - length = string.length; - - while (++index < length && isSpace(string.charCodeAt(index))) {} - return index; + function stringSize(string) { + if (!(string && reHasComplexSymbol.test(string))) { + return string.length; + } + var result = reComplexSymbol.lastIndex = 0; + while (reComplexSymbol.test(string)) { + result++; + } + return result; } /** - * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace - * character of `string`. + * Converts `string` to an array. * * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the last non-whitespace character. + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. */ - function trimmedRightIndex(string) { - var index = string.length; - - while (index-- && isSpace(string.charCodeAt(index))) {} - return index; + function stringToArray(string) { + return string.match(reComplexSymbol); } /** @@ -35025,11 +37189,11 @@ return jQuery; /*--------------------------------------------------------------------------*/ /** - * Create a new pristine `lodash` function using the given `context` object. + * Create a new pristine `lodash` function using the `context` object. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Object} [context=root] The context object. * @returns {Function} Returns a new `lodash` function. * @example @@ -35049,42 +37213,32 @@ return jQuery; * lodash.isFunction(lodash.bar); * // => true * - * // using `context` to mock `Date#getTime` use in `_.now` + * // Use `context` to mock `Date#getTime` use in `_.now`. * var mock = _.runInContext({ * 'Date': function() { * return { 'getTime': getTimeMock }; * } * }); * - * // or creating a suped-up `defer` in Node.js + * // Create a suped-up `defer` in Node.js. * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; */ function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See https://es5.github.io/#x11.1.5 for more details. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, + context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; + + /** Built-in constructor references. */ + var Date = context.Date, Error = context.Error, - Function = context.Function, Math = context.Math, - Number = context.Number, - Object = context.Object, RegExp = context.RegExp, - String = context.String, TypeError = context.TypeError; - /** Used for native method references. */ - var arrayProto = Array.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; + /** Used for built-in method references. */ + var arrayProto = context.Array.prototype, + objectProto = context.Object.prototype; /** Used to resolve the decompiled source of functions. */ - var fnToString = Function.prototype.toString; + var funcToString = context.Function.prototype.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; @@ -35092,82 +37246,96 @@ return jQuery; /** Used to generate unique IDs. */ var idCounter = 0; + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + /** * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ - var objToString = objectProto.toString; + var objectToString = objectProto.toString; /** Used to restore the original `_` reference in `_.noConflict`. */ var oldDash = root._; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + - fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); - /** Native method references. */ - var ArrayBuffer = context.ArrayBuffer, + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Reflect = context.Reflect, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, clearTimeout = context.clearTimeout, - parseFloat = context.parseFloat, - pow = Math.pow, + enumerate = Reflect ? Reflect.enumerate : undefined, + getPrototypeOf = Object.getPrototypeOf, + getOwnPropertySymbols = Object.getOwnPropertySymbols, + iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, + objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, - Set = getNative(context, 'Set'), setTimeout = context.setTimeout, - splice = arrayProto.splice, - Uint8Array = context.Uint8Array, - WeakMap = getNative(context, 'WeakMap'); + splice = arrayProto.splice; - /* Native method references for those with the same name as other `lodash` methods. */ + /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeCeil = Math.ceil, - nativeCreate = getNative(Object, 'create'), nativeFloor = Math.floor, - nativeIsArray = getNative(Array, 'isArray'), nativeIsFinite = context.isFinite, - nativeKeys = getNative(Object, 'keys'), + nativeJoin = arrayProto.join, + nativeKeys = Object.keys, nativeMax = Math.max, nativeMin = Math.min, - nativeNow = getNative(Date, 'now'), nativeParseInt = context.parseInt, - nativeRandom = Math.random; + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; - /** Used as references for `-Infinity` and `Infinity`. */ - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) - * of an array-like value. - */ - var MAX_SAFE_INTEGER = 9007199254740991; + /* Built-in method references that are verified to be native. */ + var Map = getNative(context, 'Map'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap; + /** Used to detect maps, sets, and weakmaps. */ + var mapCtorString = Map ? funcToString.call(Map) : '', + setCtorString = Set ? funcToString.call(Set) : '', + weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = Symbol ? symbolProto.valueOf : undefined, + symbolToString = Symbol ? symbolProto.toString : undefined; + /** Used to lookup unminified function names. */ var realNames = {}; /*------------------------------------------------------------------------*/ /** - * Creates a `lodash` object which wraps `value` to enable implicit chaining. - * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that retrieve a single value or may return a - * primitive value will automatically end the chain returning the unwrapped - * value. Explicit chaining may be enabled using `_.chain`. The execution of - * chained methods is lazy, that is, execution is deferred until `_#value` - * is implicitly or explicitly called. + * Creates a `lodash` object which wraps `value` to enable implicit method + * chaining. Methods that operate on and return arrays, collections, and + * functions can be chained together. Methods that retrieve a single value or + * may return a primitive value will automatically end the chain sequence and + * return the unwrapped value. Otherwise, the value must be unwrapped with + * `_#value`. + * + * Explicit chaining, which must be unwrapped with `_#value` in all cases, + * may be enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization strategy which merge iteratee calls; this can help - * to avoid the creation of intermediate data structures and greatly reduce the - * number of iteratee executions. + * fusion is an optimization to merge iteratee calls; this avoids the creation + * of intermediate arrays and can greatly reduce the number of iteratee executions. + * Sections of a chain sequence qualify for shortcut fusion if the section is + * applied to an array of at least two hundred elements and any iteratees + * accept only one argument. The heuristic for whether a section qualifies + * for shortcut fusion is subject to change. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. @@ -35175,75 +37343,83 @@ return jQuery; * In addition to lodash methods, wrappers have `Array` and `String` methods. * * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, - * `splice`, and `unshift` + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` * * The wrapper `String` methods are: * `replace` and `split` * * The wrapper methods that support shortcut fusion are: - * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, - * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, - * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, - * and `where` + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, - * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, - * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, - * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, - * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, - * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, - * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, - * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, - * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, + * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, + * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, + * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, + * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, + * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, + * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, + * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, + * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, + * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, + * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, + * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, + * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, + * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, - * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, - * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, - * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, - * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, - * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, - * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, - * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, - * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, - * `unescape`, `uniqueId`, `value`, and `words` - * - * The wrapper method `sample` will return a wrapped value when `n` is provided, - * otherwise an unwrapped value is returned. + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`, + * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`, + * `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, + * `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, + * `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, + * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, + * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, + * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, + * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, + * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, + * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, + * `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, + * `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `sample`, + * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, + * `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, + * `sum`, `sumBy`, `template`, `times`, `toLower`, `toInteger`, `toLength`, + * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, + * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, + * `value`, and `words` * * @name _ * @constructor - * @category Chain + * @category Seq * @param {*} value The value to wrap in a `lodash` instance. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * + * function square(n) { + * return n * n; + * } + * * var wrapped = _([1, 2, 3]); * - * // returns an unwrapped value - * wrapped.reduce(function(total, n) { - * return total + n; - * }); + * // Returns an unwrapped value. + * wrapped.reduce(_.add); * // => 6 * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { - * return n * n; - * }); + * // Returns a wrapped value. + * var squares = wrapped.map(square); * * _.isArray(squares); * // => false @@ -35256,7 +37432,7 @@ return jQuery; if (value instanceof LodashWrapper) { return value; } - if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + if (hasOwnProperty.call(value, '__wrapped__')) { return wrapperClone(value); } } @@ -35278,31 +37454,23 @@ return jQuery; * @private * @param {*} value The value to wrap. * @param {boolean} [chainAll] Enable chaining for all wrapper methods. - * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. */ - function LodashWrapper(value, chainAll, actions) { + function LodashWrapper(value, chainAll) { this.__wrapped__ = value; - this.__actions__ = actions || []; + this.__actions__ = []; this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; } /** - * An object environment feature flags. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - /** * By default, the template delimiters used by lodash are like those in * embedded Ruby (ERB). Change the following template settings to use * alternative delimiters. * * @static * @memberOf _ - * @type Object + * @type {Object} */ lodash.templateSettings = { @@ -35310,7 +37478,7 @@ return jQuery; * Used to detect `data` property values to be HTML-escaped. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'escape': reEscape, @@ -35318,7 +37486,7 @@ return jQuery; * Used to detect code to be evaluated. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'evaluate': reEvaluate, @@ -35326,7 +37494,7 @@ return jQuery; * Used to detect `data` property values to inject. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'interpolate': reInterpolate, @@ -35334,7 +37502,7 @@ return jQuery; * Used to reference the data object in the template text. * * @memberOf _.templateSettings - * @type string + * @type {string} */ 'variable': '', @@ -35342,7 +37510,7 @@ return jQuery; * Used to import variables into the compiled template. * * @memberOf _.templateSettings - * @type Object + * @type {Object} */ 'imports': { @@ -35350,7 +37518,7 @@ return jQuery; * A reference to the `lodash` function. * * @memberOf _.templateSettings.imports - * @type Function + * @type {Function} */ '_': lodash } @@ -35362,6 +37530,7 @@ return jQuery; * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private + * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { @@ -35370,7 +37539,7 @@ return jQuery; this.__dir__ = 1; this.__filtered__ = false; this.__iteratees__ = []; - this.__takeCount__ = POSITIVE_INFINITY; + this.__takeCount__ = MAX_ARRAY_LENGTH; this.__views__ = []; } @@ -35384,12 +37553,12 @@ return jQuery; */ function lazyClone() { var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = arrayCopy(this.__actions__); + result.__actions__ = copyArray(this.__actions__); result.__dir__ = this.__dir__; result.__filtered__ = this.__filtered__; - result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__iteratees__ = copyArray(this.__iteratees__); result.__takeCount__ = this.__takeCount__; - result.__views__ = arrayCopy(this.__views__); + result.__views__ = copyArray(this.__views__); return result; } @@ -35437,8 +37606,9 @@ return jQuery; resIndex = 0, takeCount = nativeMin(length, this.__takeCount__); - if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { - return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); } var result = []; @@ -35473,69 +37643,170 @@ return jQuery; /*------------------------------------------------------------------------*/ /** - * Creates a cache object to store key/value pairs. + * Creates an hash object. * * @private - * @static - * @name Cache - * @memberOf _.memoize + * @constructor + * @returns {Object} Returns the new hash object. + */ + function Hash() {} + + /** + * Removes `key` and its value from the hash. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(hash, key) { + return hashHas(hash, key) && delete hash[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(hash, key) { + if (nativeCreate) { + var result = hash[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(hash, key) ? hash[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ - function MapCache() { - this.__data__ = {}; + function hashHas(hash, key) { + return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); } /** - * Removes `key` and its value from the cache. + * Sets the hash `key` to `value`. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ + function hashSet(hash, key, value) { + hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function MapCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapClear() { + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. * * @private * @name delete - * @memberOf _.memoize.Cache + * @memberOf MapCache * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; + var data = this.__data__; + if (isKeyable(key)) { + return hashDelete(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map['delete'](key) : assocDelete(data.map, key); } /** - * Gets the cached value for `key`. + * Gets the map value for `key`. * * @private * @name get - * @memberOf _.memoize.Cache + * @memberOf MapCache * @param {string} key The key of the value to get. - * @returns {*} Returns the cached value. + * @returns {*} Returns the entry value. */ function mapGet(key) { - return key == '__proto__' ? undefined : this.__data__[key]; + var data = this.__data__; + if (isKeyable(key)) { + return hashGet(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.get(key) : assocGet(data.map, key); } /** - * Checks if a cached value for `key` exists. + * Checks if a map value for `key` exists. * * @private * @name has - * @memberOf _.memoize.Cache + * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapHas(key) { - return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + var data = this.__data__; + if (isKeyable(key)) { + return hashHas(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.has(key) : assocHas(data.map, key); } /** - * Sets `value` to `key` of the cache. + * Sets the map `key` to `value`. * * @private * @name set - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to cache. - * @param {*} value The value to cache. - * @returns {Object} Returns the cache object. + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache object. */ function mapSet(key, value) { - if (key != '__proto__') { - this.__data__[key] = value; + var data = this.__data__; + if (isKeyable(key)) { + hashSet(typeof key == 'string' ? data.string : data.hash, key, value); + } else if (Map) { + data.map.set(key, value); + } else { + assocSet(data.map, key, value); } return this; } @@ -35544,38 +37815,43 @@ return jQuery; /** * - * Creates a cache object to store unique values. + * Creates a set cache object to store unique values. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { - var length = values ? values.length : 0; + var index = -1, + length = values ? values.length : 0; - this.data = { 'hash': nativeCreate(null), 'set': new Set }; - while (length--) { - this.push(values[length]); + this.__data__ = new MapCache; + while (++index < length) { + this.push(values[index]); } } /** - * Checks if `value` is in `cache` mimicking the return signature of - * `_.indexOf` by returning `0` if the value is found, else `-1`. + * Checks if `value` is in `cache`. * * @private - * @param {Object} cache The cache to search. + * @param {Object} cache The set cache to search. * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. + * @returns {number} Returns `true` if `value` is found, else `false`. */ - function cacheIndexOf(cache, value) { - var data = cache.data, - result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + function cacheHas(cache, value) { + var map = cache.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; - return result ? 0 : -1; + return hash[value] === HASH_UNDEFINED; + } + return map.has(value); } /** - * Adds `value` to the cache. + * Adds `value` to the set cache. * * @private * @name push @@ -35583,366 +37859,285 @@ return jQuery; * @param {*} value The value to cache. */ function cachePush(value) { - var data = this.data; - if (typeof value == 'string' || isObject(value)) { - data.set.add(value); - } else { - data.hash[value] = true; + var map = this.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + hash[value] = HASH_UNDEFINED; + } + else { + map.set(value, HASH_UNDEFINED); } } /*------------------------------------------------------------------------*/ /** - * Creates a new array joining `array` with `other`. + * Creates a stack cache object to store key-value pairs. * * @private - * @param {Array} array The array to join. - * @param {Array} other The other array to join. - * @returns {Array} Returns the new concatenated array. + * @constructor + * @param {Array} [values] The values to cache. */ - function arrayConcat(array, other) { + function Stack(values) { var index = -1, - length = array.length, - othIndex = -1, - othLength = other.length, - result = Array(length + othLength); + length = values ? values.length : 0; + this.clear(); while (++index < length) { - result[index] = array[index]; - } - while (++othIndex < othLength) { - result[index++] = other[othIndex]; + var entry = values[index]; + this.set(entry[0], entry[1]); } - return result; } /** - * Copies the values of `source` to `array`. + * Removes all key-value entries from the stack. * * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. + * @name clear + * @memberOf Stack */ - function arrayCopy(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; + function stackClear() { + this.__data__ = { 'array': [], 'map': null }; } /** - * A specialized version of `_.forEach` for arrays without support for callback - * shorthands and `this` binding. + * Removes `key` and its value from the stack. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; + function stackDelete(key) { + var data = this.__data__, + array = data.array; - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; + return array ? assocDelete(array, key) : data.map['delete'](key); } /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands and `this` binding. + * Gets the stack value for `key`. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. */ - function arrayEachRight(array, iteratee) { - var length = array.length; + function stackGet(key) { + var data = this.__data__, + array = data.array; - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; + return array ? assocGet(array, key) : data.map.get(key); } /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands and `this` binding. + * Checks if a stack value for `key` exists. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; + function stackHas(key) { + var data = this.__data__, + array = data.array; - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; + return array ? assocHas(array, key) : data.map.has(key); } /** - * A specialized version of `baseExtremum` for arrays which invokes `iteratee` - * with one argument: (value). + * Sets the stack `key` to `value`. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache object. */ - function arrayExtremum(array, iteratee, comparator, exValue) { - var index = -1, - length = array.length, - computed = exValue, - result = computed; - - while (++index < length) { - var value = array[index], - current = +iteratee(value); + function stackSet(key, value) { + var data = this.__data__, + array = data.array; - if (comparator(current, computed)) { - computed = current; - result = value; + if (array) { + if (array.length < (LARGE_ARRAY_SIZE - 1)) { + assocSet(array, key, value); + } else { + data.array = null; + data.map = new MapCache(array); } } - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } + var map = data.map; + if (map) { + map.set(key, value); } - return result; + return this; } + /*------------------------------------------------------------------------*/ + /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands and `this` binding. + * Removes `key` and its value from the associative array. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. + * @param {Array} array The array to query. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); + function assocDelete(array, key) { + var index = assocIndexOf(array, key); + if (index < 0) { + return false; } - return result; + var lastIndex = array.length - 1; + if (index == lastIndex) { + array.pop(); + } else { + splice.call(array, index, 1); + } + return true; } /** - * Appends the elements of `values` to `array`. + * Gets the associative array value for `key`. * * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. + * @param {Array} array The array to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; + function assocGet(array, key) { + var index = assocIndexOf(array, key); + return index < 0 ? undefined : array[index][1]; } /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands and `this` binding. + * Checks if an associative array value for `key` exists. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the first element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. + * @param {Array} array The array to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; + function assocHas(array, key) { + return assocIndexOf(array, key) > -1; } /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands and `this` binding. + * Gets the index at which the first occurrence of `key` is found in `array` + * of key-value pairs. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the last element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + function assocIndexOf(array, key) { var length = array.length; - if (initFromArray && length) { - accumulator = array[--length]; - } while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); + if (eq(array[length][0], key)) { + return length; + } } - return accumulator; + return -1; } /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands and `this` binding. + * Sets the associative array `key` to `value`. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @param {Array} array The array to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } + function assocSet(array, key, value) { + var index = assocIndexOf(array, key); + if (index < 0) { + array.push([key, value]); + } else { + array[index][1] = value; } - return false; } + /*------------------------------------------------------------------------*/ + /** - * A specialized version of `_.sum` for arrays without support for callback - * shorthands and `this` binding.. + * Used by `_.defaults` to customize its `_.assignIn` use. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. */ - function arraySum(array, iteratee) { - var length = array.length, - result = 0; - - while (length--) { - result += +iteratee(array[length]) || 0; + function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; } - return result; + return objValue; } /** - * Used by `_.defaults` to customize its `_.assign` use. + * This function is like `assignValue` except that it doesn't assign `undefined` values. * * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ - function assignDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : objectValue; + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } } /** - * Used by `_.template` to customize its `_.assign` use. - * - * **Note:** This function is like `assignDefaults` except that it ignores - * inherited property values when checking if a property is `undefined`. + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. * * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @param {string} key The key associated with the object and source values. - * @param {Object} object The destination object. - * @returns {*} Returns the value to assign to the destination object. + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ - function assignOwnDefaults(objectValue, sourceValue, key, object) { - return (objectValue === undefined || !hasOwnProperty.call(object, key)) - ? sourceValue - : objectValue; + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } } /** - * A specialized version of `_.assign` for customizing assigned values without - * support for argument juggling, multiple sources, and `this` binding `customizer` - * functions. + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. * * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. */ - function assignWith(object, source, customizer) { - var index = -1, - props = keys(source), - length = props.length; - - while (++index < length) { - var key = props[index], - value = object[key], - result = customizer(value, source[key], key, object, source); - - if ((result === result ? (result !== value) : (value === value)) || - (value === undefined && !(key in object))) { - object[key] = result; - } - } - return object; + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; } /** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `customizer` functions. + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. * * @private * @param {Object} object The destination object. @@ -35950,107 +38145,100 @@ return jQuery; * @returns {Object} Returns `object`. */ function baseAssign(object, source) { - return source == null - ? object - : baseCopy(source, keys(source), object); + return object && copyObject(source, keys(source), object); } /** - * The base implementation of `_.at` without support for string collections - * and individual key arguments. + * The base implementation of `_.at` without support for individual paths. * * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths of elements to pick. * @returns {Array} Returns the new array of picked elements. */ - function baseAt(collection, props) { + function baseAt(object, paths) { var index = -1, - isNil = collection == null, - isArr = !isNil && isArrayLike(collection), - length = isArr ? collection.length : 0, - propsLength = props.length, - result = Array(propsLength); + isNil = object == null, + length = paths.length, + result = Array(length); - while(++index < propsLength) { - var key = props[index]; - if (isArr) { - result[index] = isIndex(key, length) ? collection[key] : undefined; - } else { - result[index] = isNil ? undefined : collection[key]; - } + while (++index < length) { + result[index] = isNil ? undefined : get(object, paths[index]); } return result; } /** - * Copies properties of `source` to `object`. + * Casts `value` to an empty array if it's not an array like object. * * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property names to copy. - * @param {Object} [object={}] The object to copy properties to. - * @returns {Object} Returns `object`. + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. */ - function baseCopy(source, props, object) { - object || (object = {}); - - var index = -1, - length = props.length; + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; } /** - * The base implementation of `_.callback` which supports specifying the - * number of arguments to provide to `func`. + * Casts `value` to a path array if it's not one. * * @private - * @param {*} [func=_.identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. */ - function baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return thisArg === undefined - ? func - : bindCallback(func, thisArg, argCount); - } - if (func == null) { - return identity; - } - if (type == 'object') { - return baseMatches(func); + function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } } - return thisArg === undefined - ? property(func) - : baseMatchesProperty(func, thisArg); + return number; } /** - * The base implementation of `_.clone` without support for argument juggling - * and `this` binding `customizer` functions. + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. * * @private * @param {*} value The value to clone. * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. + * @param {Function} [customizer] The function to customize cloning. * @param {string} [key] The key of `value`. - * @param {Object} [object] The object `value` belongs to. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. * @returns {*} Returns the cloned value. */ - function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + function baseClone(value, isDeep, customizer, key, object, stack) { var result; if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); + result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; @@ -36062,42 +38250,72 @@ return jQuery; if (isArr) { result = initCloneArray(value); if (!isDeep) { - return arrayCopy(value, result); + return copyArray(value, result); } } else { - var tag = objToString.call(value), - isFunc = tag == funcTag; + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } result = initCloneObject(isFunc ? {} : value); if (!isDeep) { - return baseAssign(result, value); + return copySymbols(value, baseAssign(result, value)); } } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); } } // Check for circular references and return its corresponding clone. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; } - // Add the source value to the stack of traversed objects and associate it with its clone. - stackA.push(value); - stackB.push(result); + stack.set(value, result); // Recursively populate clone (susceptible to call stack limits). (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { - result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack)); }); - return result; + return isArr ? result : copySymbols(value, result); + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + */ + function baseConforms(source) { + var props = keys(source), + length = props.length; + + return function(object) { + if (object == null) { + return !length; + } + var index = length; + while (index--) { + var key = props[index], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in Object(object))) || !predicate(value)) { + return false; + } + } + return true; + }; } /** @@ -36108,26 +38326,18 @@ return jQuery; * @param {Object} prototype The object to inherit from. * @returns {Object} Returns the new object. */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } /** - * The base implementation of `_.delay` and `_.defer` which accepts an index - * of where to slice the arguments to provide to `func`. + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. * * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The arguments provide to `func`. + * @param {Object} args The arguments to provide to `func`. * @returns {number} Returns the timer id. */ function baseDelay(func, wait, args) { @@ -36138,46 +38348,54 @@ return jQuery; } /** - * The base implementation of `_.difference` which accepts a single array - * of values to exclude. + * The base implementation of methods like `_.difference` without support for + * excluding multiple arrays or iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. */ - function baseDifference(array, values) { - var length = array ? array.length : 0, - result = []; + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; if (!length) { return result; } - var index = -1, - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, - valuesLength = values.length; - - if (cache) { - indexOf = cacheIndexOf; + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; isCommon = false; - values = cache; + values = new SetCache(values); } outer: while (++index < length) { - var value = array[index]; + var value = array[index], + computed = iteratee ? iteratee(value) : value; - if (isCommon && value === value) { + if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { - if (values[valuesIndex] === value) { + if (values[valuesIndex] === computed) { continue outer; } } result.push(value); } - else if (indexOf(values, value, 0) < 0) { + else if (!includes(values, computed, comparator)) { result.push(value); } } @@ -36185,36 +38403,32 @@ return jQuery; } /** - * The base implementation of `_.forEach` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.forEach` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. + * @returns {Array|Object} Returns `collection`. */ var baseEach = createBaseEach(baseForOwn); /** - * The base implementation of `_.forEachRight` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.forEachRight` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. + * @returns {Array|Object} Returns `collection`. */ var baseEachRight = createBaseEach(baseForOwnRight, true); /** - * The base implementation of `_.every` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.every` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` */ function baseEvery(collection, predicate) { var result = true; @@ -36226,32 +38440,6 @@ return jQuery; } /** - * Gets the extremum value of `collection` invoking `iteratee` for each value - * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments: (value, index|key, collection). - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(collection, iteratee, comparator, exValue) { - var computed = exValue, - result = computed; - - baseEach(collection, function(value, index, collection) { - var current = +iteratee(value, index, collection); - if (comparator(current, computed) || (current === exValue && current === result)) { - computed = current; - result = value; - } - }); - return result; - } - - /** * The base implementation of `_.fill` without an iteratee call guard. * * @private @@ -36264,29 +38452,26 @@ return jQuery; function baseFill(array, value, start, end) { var length = array.length; - start = start == null ? 0 : (+start || 0); + start = toInteger(start); if (start < 0) { start = -start > length ? 0 : (length + start); } - end = (end === undefined || end > length) ? length : (+end || 0); + end = (end === undefined || end > length) ? length : toInteger(end); if (end < 0) { end += length; } - length = start > end ? 0 : (end >>> 0); - start >>>= 0; - - while (start < length) { + end = start > end ? 0 : toLength(end); + while (start < end) { array[start++] = value; } return array; } /** - * The base implementation of `_.filter` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.filter` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ @@ -36301,41 +38486,16 @@ return jQuery; } /** - * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, - * without support for callback shorthands and `this` binding, which iterates - * over `collection` using the provided `eachFunc`. - * - * @private - * @param {Array|Object|string} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @param {boolean} [retKey] Specify returning the key of the found element - * instead of the element itself. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFind(collection, predicate, eachFunc, retKey) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = retKey ? key : value; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with added support for restricting - * flattening and specifying the start index. + * The base implementation of `_.flatten` with support for restricting flattening. * * @private * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. + * @param {number} depth The maximum recursion depth. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict, result) { + function baseFlatten(array, depth, isStrict, result) { result || (result = []); var index = -1, @@ -36343,11 +38503,11 @@ return jQuery; while (++index < length) { var value = array[index]; - if (isObjectLike(value) && isArrayLike(value) && + if (depth > 0 && isArrayLikeObject(value) && (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { + if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); + baseFlatten(value, depth - 1, isStrict, result); } else { arrayPush(result, value); } @@ -36385,8 +38545,7 @@ return jQuery; var baseForRight = createBaseFor(true); /** - * The base implementation of `_.forIn` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.forIn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. @@ -36394,12 +38553,11 @@ return jQuery; * @returns {Object} Returns `object`. */ function baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); + return object == null ? object : baseFor(object, iteratee, keysIn); } /** - * The base implementation of `_.forOwn` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. @@ -36407,12 +38565,11 @@ return jQuery; * @returns {Object} Returns `object`. */ function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); + return object && baseFor(object, iteratee, keys); } /** - * The base implementation of `_.forOwnRight` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. @@ -36420,12 +38577,12 @@ return jQuery; * @returns {Object} Returns `object`. */ function baseForOwnRight(object, iteratee) { - return baseForRight(object, iteratee, keys); + return object && baseForRight(object, iteratee, keys); } /** * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from those provided. + * `object` function property names filtered from `props`. * * @private * @param {Object} object The object to inspect. @@ -36433,37 +38590,22 @@ return jQuery; * @returns {Array} Returns the new array of filtered property names. */ function baseFunctions(object, props) { - var index = -1, - length = props.length, - resIndex = -1, - result = []; - - while (++index < length) { - var key = props[index]; - if (isFunction(object[key])) { - result[++resIndex] = key; - } - } - return result; + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); } /** - * The base implementation of `get` without support for string paths - * and default values. + * The base implementation of `_.get` without support for default values. * * @private * @param {Object} object The object to query. - * @param {Array} path The path of the property to get. - * @param {string} [pathKey] The key representation of path. + * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ - function baseGet(object, path, pathKey) { - if (object == null) { - return; - } - if (pathKey !== undefined && pathKey in toObject(object)) { - path = [pathKey]; - } + function baseGet(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + var index = 0, length = path.length; @@ -36474,26 +38616,167 @@ return jQuery; } /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototypeOf(object) === null); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + caches[othIndex] = !comparator && (iteratee || array.length >= 120) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + length = array.length, + seen = caches[0]; + + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + if (!isKey(path, object)) { + path = baseCastPath(path); + object = parent(object, path); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ - function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + function baseIsEqual(value, other, customizer, bitmask, stack) { if (value === other) { return true; } if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { return value !== value && other !== other; } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); } /** @@ -36505,20 +38788,19 @@ return jQuery; * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `value` objects. - * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ - function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = arrayTag, othTag = arrayTag; if (!objIsArr) { - objTag = objToString.call(object); + objTag = getTag(object); if (objTag == argsTag) { objTag = objectTag; } else if (objTag != objectTag) { @@ -36526,65 +38808,47 @@ return jQuery; } } if (!othIsArr) { - othTag = objToString.call(other); + othTag = getTag(other); if (othTag == argsTag) { othTag = objectTag; } else if (othTag != objectTag) { othIsArr = isTypedArray(other); } } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), isSameTag = objTag == othTag; if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); + return equalByTag(object, other, objTag, equalFunc, customizer, bitmask); } - if (!isLoose) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + if (!isPartial) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { - return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); } } if (!isSameTag) { return false; } - // Assume cyclic values are equal. - // For more information on detecting circular references see https://es5.github.io/#JO. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - // Add `object` and `other` to the stack of traversed objects. - stackA.push(object); - stackB.push(other); - - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; + stack || (stack = new Stack); + return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack); } /** - * The base implementation of `_.isMatch` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private * @param {Object} object The object to inspect. - * @param {Array} matchData The propery names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparing objects. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ - function baseIsMatch(object, matchData, customizer) { + function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; @@ -36592,7 +38856,7 @@ return jQuery; if (object == null) { return !length; } - object = toObject(object); + object = Object(object); while (index--) { var data = matchData[index]; if ((noCustomizer && data[2]) @@ -36613,8 +38877,13 @@ return jQuery; return false; } } else { - var result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + var stack = new Stack, + result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; + + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { return false; } } @@ -36623,11 +38892,70 @@ return jQuery; } /** - * The base implementation of `_.map` without support for callback shorthands - * and `this` binding. + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + var type = typeof value; + if (type == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (type == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; + } + + // Fallback for IE < 9 with es6-shim. + if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ @@ -36642,7 +38970,7 @@ return jQuery; } /** - * The base implementation of `_.matches` which does not clone `source`. + * The base implementation of `_.matches` which doesn't clone `source`. * * @private * @param {Object} source The object of property values to match. @@ -36658,92 +38986,70 @@ return jQuery; if (object == null) { return false; } - return object[key] === value && (value !== undefined || (key in toObject(object))); + return object[key] === value && + (value !== undefined || (key in Object(object))); }; } return function(object) { - return baseIsMatch(object, matchData); + return object === source || baseIsMatch(object, source, matchData); }; } /** - * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private * @param {string} path The path of the property to get. - * @param {*} srcValue The value to compare. + * @param {*} srcValue The value to match. * @returns {Function} Returns the new function. */ function baseMatchesProperty(path, srcValue) { - var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(srcValue), - pathKey = (path + ''); - - path = toPath(path); return function(object) { - if (object == null) { - return false; - } - var key = pathKey; - object = toObject(object); - if ((isArr || !isCommon) && !(key in object)) { - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - key = last(path); - object = toObject(object); - } - return object[key] === srcValue - ? (srcValue !== undefined || (key in object)) - : baseIsEqual(srcValue, object[key], undefined, true); + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); }; } /** - * The base implementation of `_.merge` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. + * The base implementation of `_.merge` without support for multiple sources. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. * @param {Function} [customizer] The function to customize merged values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {Object} Returns `object`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. */ - function baseMerge(object, source, customizer, stackA, stackB) { - if (!isObject(object)) { - return object; + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; } - var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), - props = isSrcArr ? undefined : keys(source); + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); arrayEach(props || source, function(srcValue, key) { if (props) { key = srcValue; srcValue = source[key]; } - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; - if (isCommon) { - result = srcValue; - } - if ((result !== undefined || (isSrcArr && !(key in object))) && - (isCommon || (result === result ? (result !== value) : (value === value)))) { - object[key] = result; + if (newValue === undefined) { + newValue = srcValue; } + assignMergeValue(object, key, newValue); } }); - return object; } /** @@ -36755,53 +39061,129 @@ return jQuery; * @param {Object} object The destination object. * @param {Object} source The source object. * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merged values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. */ - function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { - var length = stackA.length, - srcValue = source[key]; + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); - while (length--) { - if (stackA[length] == srcValue) { - object[key] = stackB[length]; - return; - } + if (stacked) { + assignMergeValue(object, key, stacked); + return; } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; if (isCommon) { - result = srcValue; - if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (isArrayLike(value) ? arrayCopy(value) : []); + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, true); + } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { - result = isArguments(value) - ? toPlainObject(value) - : (isPlainObject(value) ? value : {}); + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, true); + } + else { + newValue = objValue; + } } else { isCommon = false; } } - // Add the source value to the stack of traversed objects and associate - // it with its merged value. - stackA.push(srcValue); - stackB.push(result); + stack.set(srcValue, newValue); if (isCommon) { // Recursively merge objects and arrays (susceptible to call stack limits). - object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); - } else if (result === result ? (result !== value) : (value === value)) { - object[key] = result; + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + var index = -1, + toIteratee = getIteratee(); + + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) { + return toIteratee(iteratee); + }); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return arrayReduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, predicate) { + var result = {}; + baseForIn(object, function(value, key) { + if (predicate(value, key)) { + result[key] = value; + } + }); + return result; } /** @@ -36825,16 +39207,59 @@ return jQuery; * @returns {Function} Returns the new function. */ function basePropertyDeep(path) { - var pathKey = (path + ''); - path = toPath(path); return function(object) { - return baseGet(object, path, pathKey); + return baseGet(object, path); }; } /** + * The base implementation of `_.pullAll`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values) { + return basePullAllBy(array, values); + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAllBy(array, values, iteratee) { + var index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, function(value) { return iteratee(value); }); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** * The base implementation of `_.pullAt` without support for individual - * index arguments and capturing the removed elements. + * indexes or capturing the removed elements. * * @private * @param {Array} array The array to modify. @@ -36842,51 +39267,104 @@ return jQuery; * @returns {Array} Returns `array`. */ function basePullAt(array, indexes) { - var length = array ? indexes.length : 0; + var length = array ? indexes.length : 0, + lastIndex = length - 1; + while (length--) { var index = indexes[length]; - if (index != previous && isIndex(index)) { + if (lastIndex == length || index != previous) { var previous = index; - splice.call(array, index, 1); + if (isIndex(index)) { + splice.call(array, index, 1); + } + else if (!isKey(index, array)) { + var path = baseCastPath(index), + object = parent(array, path); + + if (object != null) { + delete object[last(path)]; + } + } + else { + delete array[index]; + } } } return array; } /** - * The base implementation of `_.random` without support for argument juggling - * and returning floating-point numbers. + * The base implementation of `_.random` without support for returning + * floating-point numbers. * * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. * @returns {number} Returns the random number. */ - function baseRandom(min, max) { - return min + nativeFloor(nativeRandom() * (max - min + 1)); + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); } /** - * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands and `this` binding, which iterates over `collection` - * using the provided `eachFunc`. + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments to numbers. * * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initFromCollection Specify using the first or last element - * of `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the new array of numbers. */ - function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initFromCollection - ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + var newValue = value; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; + } + } + assignValue(nested, key, newValue); + } + nested = nested[key]; + } + return object; } /** @@ -36915,11 +39393,10 @@ return jQuery; var index = -1, length = array.length; - start = start == null ? 0 : (+start || 0); if (start < 0) { start = -start > length ? 0 : (length + start); } - end = (end === undefined || end > length) ? length : (+end || 0); + end = end > length ? length : end; if (end < 0) { end += length; } @@ -36934,14 +39411,12 @@ return jQuery; } /** - * The base implementation of `_.some` without support for callback shorthands - * and `this` binding. + * The base implementation of `_.some` without support for iteratee shorthands. * * @private - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. */ function baseSome(collection, predicate) { var result; @@ -36954,98 +39429,164 @@ return jQuery; } /** - * The base implementation of `_.sortBy` which uses `comparer` to define - * the sort order of `array` and replaces criteria objects with their - * corresponding values. + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. * * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. */ - function baseSortBy(array, comparer) { - var length = array.length; + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; - array.sort(comparer); - while (length--) { - array[length] = array[length].value; + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; } - return array; + return baseSortedIndexBy(array, value, identity, retHighest); } /** - * The base implementation of `_.sortByOrder` without param guards. + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). * * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted into `array`. */ - function baseSortByOrder(collection, iteratees, orders) { - var callback = getCallback(), - index = -1; + function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); - iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; - var result = baseMap(collection, function(value) { - var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); } /** - * The base implementation of `_.sum` without support for callback shorthands - * and `this` binding. + * The base implementation of `_.sortedUniq`. * * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. */ - function baseSum(collection, iteratee) { - var result = 0; - baseEach(collection, function(value, index, collection) { - result += +iteratee(value, index, collection) || 0; - }); + function baseSortedUniq(array) { + return baseSortedUniqBy(array); + } + + /** + * The base implementation of `_.sortedUniqBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniqBy(array, iteratee) { + var index = 0, + length = array.length, + value = array[0], + computed = iteratee ? iteratee(value) : value, + seen = computed, + resIndex = 0, + result = [value]; + + while (++index < length) { + value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!eq(computed, seen)) { + seen = computed; + result[++resIndex] = value; + } + } return result; } /** - * The base implementation of `_.uniq` without support for callback shorthands - * and `this` binding. + * The base implementation of `_.uniqBy` without support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. */ - function baseUniq(array, iteratee) { + function baseUniq(array, iteratee, comparator) { var index = -1, - indexOf = getIndexOf(), + includes = arrayIncludes, length = array.length, - isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= LARGE_ARRAY_SIZE, - seen = isLarge ? createCache() : null, - result = []; + isCommon = true, + result = [], + seen = result; - if (seen) { - indexOf = cacheIndexOf; + if (comparator) { isCommon = false; - } else { - isLarge = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { seen = iteratee ? [] : result; } outer: while (++index < length) { var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; + computed = iteratee ? iteratee(value) : value; - if (isCommon && value === value) { + if (isCommon && computed === computed) { var seenIndex = seen.length; while (seenIndex--) { if (seen[seenIndex] === computed) { @@ -37057,8 +39598,8 @@ return jQuery; } result.push(value); } - else if (indexOf(seen, computed, 0) < 0) { - if (iteratee || isLarge) { + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { seen.push(computed); } result.push(value); @@ -37068,29 +39609,23 @@ return jQuery; } /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. + * The base implementation of `_.unset`. * * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; + function baseUnset(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + object = parent(object, path); + var key = last(path); + return (object != null && has(object, key)) ? delete object[key] : true; } /** - * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, - * and `_.takeWhile` without support for callback shorthands and `this` binding. + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. * * @private * @param {Array} array The array to query. @@ -37103,7 +39638,9 @@ return jQuery; var length = array.length, index = fromRight ? length : -1; - while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + return isDrop ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); @@ -37116,7 +39653,7 @@ return jQuery; * * @private * @param {*} value The unwrapped value. - * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. * @returns {*} Returns the resolved value. */ function baseWrapperValue(value, actions) { @@ -37124,147 +39661,159 @@ return jQuery; if (result instanceof LazyWrapper) { result = result.value(); } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { var index = -1, - length = actions.length; + length = arrays.length; while (++index < length) { - var action = actions[index]; - result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + var result = result + ? arrayPush( + baseDifference(result, arrays[index], iteratee, comparator), + baseDifference(arrays[index], result, iteratee, comparator) + ) + : arrays[index]; } - return result; + return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; } /** - * Performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. * * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @param {Array} props The property names. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. */ - function binaryIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; - if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { - low = mid + 1; - } else { - high = mid; - } - } - return high; + while (++index < length) { + assignFunc(result, props[index], index < valsLength ? values[index] : undefined); } - return binaryIndexBy(array, value, identity, retHighest); + return result; } /** - * This function is like `binaryIndex` except that it invokes `iteratee` for - * `value` and each element of `array` to compute their sort ranking. The - * iteratee is invoked with one argument; (value). + * Creates a clone of `buffer`. * * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. */ - function binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var Ctor = buffer.constructor, + result = new Ctor(buffer.length); - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsNull = value === null, - valIsUndef = value === undefined; + buffer.copy(result); + return result; + } - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - isDef = computed !== undefined, - isReflexive = computed === computed; + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var Ctor = arrayBuffer.constructor, + result = new Ctor(arrayBuffer.byteLength), + view = new Uint8Array(result); - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsNull) { - setLow = isReflexive && isDef && (retHighest || computed != null); - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || isDef); - } else if (computed == null) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); + view.set(new Uint8Array(arrayBuffer)); + return result; } /** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. + * Creates a clone of `map`. * * @private - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. + * @param {Object} map The map to clone. + * @returns {Object} Returns the cloned map. */ - function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (thisArg === undefined) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; - } - return function() { - return func.apply(thisArg, arguments); - }; + function cloneMap(map) { + var Ctor = map.constructor; + return arrayReduce(mapToArray(map), addMapEntry, new Ctor); } /** - * Creates a clone of the given array buffer. + * Creates a clone of `regexp`. * * @private - * @param {ArrayBuffer} buffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. */ - function bufferClone(buffer) { - var result = new ArrayBuffer(buffer.byteLength), - view = new Uint8Array(result); + function cloneRegExp(regexp) { + var Ctor = regexp.constructor, + result = new Ctor(regexp.source, reFlags.exec(regexp)); - view.set(new Uint8Array(buffer)); + result.lastIndex = regexp.lastIndex; return result; } /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set) { + var Ctor = set.constructor; + return arrayReduce(setToArray(set), addSetEntry, new Ctor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return Symbol ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var arrayBuffer = typedArray.buffer, + buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer, + Ctor = typedArray.constructor; + + return new Ctor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** * Creates an array that is the composition of partially applied arguments, * placeholders, and provided arguments into a single array of arguments. * @@ -37272,23 +39821,28 @@ return jQuery; * @param {Array|Object} args The provided arguments. * @param {Array} partials The arguments to prepend to those provided. * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ - function composeArgs(args, partials, holders) { - var holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, - result = Array(leftLength + argsLength); + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; } while (++argsIndex < holdersLength) { - result[holders[argsIndex]] = args[argsIndex]; + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } } - while (argsLength--) { + while (rangeLength--) { result[leftIndex++] = args[argsIndex++]; } return result; @@ -37302,18 +39856,21 @@ return jQuery; * @param {Array|Object} args The provided arguments. * @param {Array} partials The arguments to append to those provided. * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ - function composeArgsRight(args, partials, holders) { - var holdersIndex = -1, + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), rightIndex = -1, rightLength = partials.length, - result = Array(argsLength + rightLength); + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; - while (++argsIndex < argsLength) { + while (++argsIndex < rangeLength) { result[argsIndex] = args[argsIndex]; } var offset = argsIndex; @@ -37321,71 +39878,130 @@ return jQuery; result[offset + rightIndex] = partials[rightIndex]; } while (++holdersIndex < holdersLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } } return result; } /** - * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object) { + return copyObjectWith(source, props, object); + } + + /** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates a function like `_.groupBy`. * * @private - * @param {Function} setter The function to set keys and values of the accumulator object. - * @param {Function} [initializer] The function to initialize the accumulator object. + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. * @returns {Function} Returns the new aggregator function. */ function createAggregator(setter, initializer) { - return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; - iteratee = getCallback(iteratee, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; - while (++index < length) { - var value = collection[index]; - setter(result, value, iteratee(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, iteratee(value, key, collection), collection); - }); - } - return result; + return func(collection, setter, getIteratee(iteratee), accumulator); }; } /** - * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { - return restParam(function(object, sources) { + return rest(function(object, sources) { var index = -1, - length = object == null ? 0 : sources.length, - customizer = length > 2 ? sources[length - 2] : undefined, - guard = length > 2 ? sources[2] : undefined, - thisArg = length > 1 ? sources[length - 1] : undefined; - - if (typeof customizer == 'function') { - customizer = bindCallback(customizer, thisArg, 5); - length -= 2; - } else { - customizer = typeof thisArg == 'function' ? thisArg : undefined; - length -= (customizer ? 1 : 0); - } + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } + object = Object(object); while (++index < length) { var source = sources[index]; if (source) { - assigner(object, source, customizer); + assigner(object, source, index, customizer); } } return object; @@ -37402,12 +40018,15 @@ return jQuery; */ function createBaseEach(eachFunc, fromRight) { return function(collection, iteratee) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { return eachFunc(collection, iteratee); } - var index = fromRight ? length : -1, - iterable = toObject(collection); + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); while ((fromRight ? index-- : ++index < length)) { if (iteratee(iterable[index], index, iterable) === false) { @@ -37419,7 +40038,7 @@ return jQuery; } /** - * Creates a base function for `_.forIn` or `_.forInRight`. + * Creates a base function for methods like `_.forIn`. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. @@ -37427,13 +40046,13 @@ return jQuery; */ function createBaseFor(fromRight) { return function(object, iteratee, keysFunc) { - var iterable = toObject(object), + var index = -1, + iterable = Object(object), props = keysFunc(object), - length = props.length, - index = fromRight ? length : -1; + length = props.length; - while ((fromRight ? index-- : ++index < length)) { - var key = props[index]; + while (length--) { + var key = props[fromRight ? length : ++index]; if (iteratee(iterable[key], key, iterable) === false) { break; } @@ -37443,38 +40062,50 @@ return jQuery; } /** - * Creates a function that wraps `func` and invokes it with the `this` + * Creates a function that wraps `func` to invoke it with the optional `this` * binding of `thisArg`. * * @private - * @param {Function} func The function to bind. + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new bound function. + * @returns {Function} Returns the new wrapped function. */ - function createBindWrapper(func, thisArg) { - var Ctor = createCtorWrapper(func); + function createBaseWrapper(func, bitmask, thisArg) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); function wrapper() { var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(thisArg, arguments); + return fn.apply(isBind ? thisArg : this, arguments); } return wrapper; } /** - * Creates a `Set` cache object to optimize linear searches of large arrays. + * Creates a function like `_.lowerFirst`. * * @private - * @param {Array} [values] The values to cache. - * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new function. */ - function createCache(values) { - return (nativeCreate && Set) ? new SetCache(values) : null; + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), + trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); + + return chr[methodName]() + trailing; + }; } /** - * Creates a function that produces compound words out of the words in a - * given string. + * Creates a function like `_.camelCase`. * * @private * @param {Function} callback The function to combine each word. @@ -37482,15 +40113,7 @@ return jQuery; */ function createCompounder(callback) { return function(string) { - var index = -1, - array = words(deburr(string)), - length = array.length, - result = ''; - - while (++index < length) { - result = callback(result, array[index], index); - } - return result; + return arrayReduce(words(deburr(string)), callback, ''); }; } @@ -37528,116 +40151,40 @@ return jQuery; } /** - * Creates a `_.curry` or `_.curryRight` function. - * - * @private - * @param {boolean} flag The curry bit flag. - * @returns {Function} Returns the new curry function. - */ - function createCurry(flag) { - function curryFunc(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = undefined; - } - var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryFunc.placeholder; - return result; - } - return curryFunc; - } - - /** - * Creates a `_.defaults` or `_.defaultsDeep` function. + * Creates a function that wraps `func` to enable currying. * * @private - * @param {Function} assigner The function to assign values. - * @param {Function} customizer The function to customize assigned values. - * @returns {Function} Returns the new defaults function. + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. */ - function createDefaults(assigner, customizer) { - return restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(customizer); - return assigner.apply(undefined, args); - }); - } + function createCurryWrapper(func, bitmask, arity) { + var Ctor = createCtorWrapper(func); - /** - * Creates a `_.max` or `_.min` function. - * - * @private - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {Function} Returns the new extremum function. - */ - function createExtremum(comparator, exValue) { - return function(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - iteratee = getCallback(iteratee, thisArg, 3); - if (iteratee.length == 1) { - collection = isArray(collection) ? collection : toIterable(collection); - var result = arrayExtremum(collection, iteratee, comparator, exValue); - if (!(collection.length && result === exValue)) { - return result; - } - } - return baseExtremum(collection, iteratee, comparator, exValue); - }; - } + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getPlaceholder(wrapper); - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. - */ - function createFind(eachFunc, fromRight) { - return function(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate, fromRight); - return index > -1 ? collection[index] : undefined; + while (index--) { + args[index] = arguments[index]; } - return baseFind(collection, predicate, eachFunc); - }; - } - - /** - * Creates a `_.findIndex` or `_.findLastIndex` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. - */ - function createFindIndex(fromRight) { - return function(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, fromRight); - }; - } - - /** - * Creates a `_.findKey` or `_.findLastKey` function. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new find function. - */ - function createFindKey(objectFunc) { - return function(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, objectFunc, true); - }; + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; } /** @@ -37648,30 +40195,36 @@ return jQuery; * @returns {Function} Returns the new flow function. */ function createFlow(fromRight) { - return function() { - var wrapper, - length = arguments.length, - index = fromRight ? length : -1, - leftIndex = 0, - funcs = Array(length); + return rest(function(funcs) { + funcs = baseFlatten(funcs, 1); - while ((fromRight ? index-- : ++index < length)) { - var func = funcs[leftIndex++] = arguments[index]; + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { - wrapper = new LodashWrapper([], true); + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); } } - index = wrapper ? -1 : length; + index = wrapper ? index : length; while (++index < length) { func = funcs[index]; var funcName = getFuncName(func), data = funcName == 'wrapper' ? getData(func) : undefined; - if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); @@ -37681,7 +40234,8 @@ return jQuery; var args = arguments, value = args[0]; - if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { return wrapper.plant(value).value(); } var index = 0, @@ -37692,132 +40246,16 @@ return jQuery; } return result; }; - }; - } - - /** - * Creates a function for `_.forEach` or `_.forEachRight`. - * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. - */ - function createForEach(arrayFunc, eachFunc) { - return function(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee) - : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); - }; - } - - /** - * Creates a function for `_.forIn` or `_.forInRight`. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. - */ - function createForIn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee, keysIn); - }; - } - - /** - * Creates a function for `_.forOwn` or `_.forOwnRight`. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. - */ - function createForOwn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee); - }; - } - - /** - * Creates a function for `_.mapKeys` or `_.mapValues`. - * - * @private - * @param {boolean} [isMapKeys] Specify mapping keys instead of values. - * @returns {Function} Returns the new map function. - */ - function createObjectMapper(isMapKeys) { - return function(object, iteratee, thisArg) { - var result = {}; - iteratee = getCallback(iteratee, thisArg, 3); - - baseForOwn(object, function(value, key, object) { - var mapped = iteratee(value, key, object); - key = isMapKeys ? mapped : key; - value = isMapKeys ? value : mapped; - result[key] = value; - }); - return result; - }; - } - - /** - * Creates a function for `_.padLeft` or `_.padRight`. - * - * @private - * @param {boolean} [fromRight] Specify padding from the right. - * @returns {Function} Returns the new pad function. - */ - function createPadDir(fromRight) { - return function(string, length, chars) { - string = baseToString(string); - return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); - }; - } - - /** - * Creates a `_.partial` or `_.partialRight` function. - * - * @private - * @param {boolean} flag The partial bit flag. - * @returns {Function} Returns the new partial function. - */ - function createPartial(flag) { - var partialFunc = restParam(function(func, partials) { - var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, undefined, partials, holders); }); - return partialFunc; } /** - * Creates a function for `_.reduce` or `_.reduceRight`. + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. * * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. - */ - function createReduce(arrayFunc, eachFunc) { - return function(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); - }; - } - - /** - * Creates a function that wraps `func` and invokes it with optional `this` - * binding of, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to the new function. * @param {Array} [holders] The `partials` placeholder indexes. @@ -37832,14 +40270,11 @@ return jQuery; var isAry = bitmask & ARY_FLAG, isBind = bitmask & BIND_FLAG, isBindKey = bitmask & BIND_KEY_FLAG, - isCurry = bitmask & CURRY_FLAG, - isCurryBound = bitmask & CURRY_BOUND_FLAG, - isCurryRight = bitmask & CURRY_RIGHT_FLAG, + isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), + isFlip = bitmask & FLIP_FLAG, Ctor = isBindKey ? undefined : createCtorWrapper(func); function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it to other functions. var length = arguments.length, index = length, args = Array(length); @@ -37847,52 +40282,38 @@ return jQuery; while (index--) { args[index] = arguments[index]; } + if (isCurried) { + var placeholder = getPlaceholder(wrapper), + holdersCount = countHolders(args, placeholder); + } if (partials) { - args = composeArgs(args, partials, holders); + args = composeArgs(args, partials, holders, isCurried); } if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight); + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); } - if (isCurry || isCurryRight) { - var placeholder = wrapper.placeholder, - argsHolders = replaceHolders(args, placeholder); - - length -= argsHolders.length; - if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : undefined, - newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : undefined, - newHoldersRight = isCurry ? undefined : argsHolders, - newPartials = isCurry ? args : undefined, - newPartialsRight = isCurry ? undefined : args; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!isCurryBound) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], - result = createHybridWrapper.apply(undefined, newData); - - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return result; - } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); } var thisBinding = isBind ? thisArg : this, fn = isBindKey ? thisBinding[func] : func; + length = args.length; if (argPos) { args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); } - if (isAry && ary < args.length) { + if (isAry && ary < length) { args.length = ary; } if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtorWrapper(func); + fn = Ctor || createCtorWrapper(fn); } return fn.apply(thisBinding, args); } @@ -37900,51 +40321,87 @@ return jQuery; } /** - * Creates the padding required for `string` based on the given `length`. - * The `chars` string is truncated if the number of characters exceeds `length`. + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new invoker function. + */ + function createOver(arrayFunc) { + return rest(function(iteratees) { + iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee()); + return rest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. * * @private * @param {string} string The string to create padding for. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the pad for `string`. + * @returns {string} Returns the padding for `string`. */ function createPadding(string, length, chars) { - var strLength = string.length; - length = +length; + length = toInteger(length); - if (strLength >= length || !nativeIsFinite(length)) { + var strLength = stringSize(string); + if (!length || strLength >= length) { return ''; } var padLength = length - strLength; - chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + chars = chars === undefined ? ' ' : (chars + ''); + + var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + return reHasComplexSymbol.test(chars) + ? stringToArray(result).slice(0, padLength).join('') + : result.slice(0, padLength); } /** - * Creates a function that wraps `func` and invokes it with the optional `this` + * Creates a function that wraps `func` to invoke it with the optional `this` * binding of `thisArg` and the `partials` prepended to those provided to * the wrapper. * * @private - * @param {Function} func The function to partially apply arguments to. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. * @param {*} thisArg The `this` binding of `func`. * @param {Array} partials The arguments to prepend to those provided to the new function. - * @returns {Function} Returns the new bound function. + * @returns {Function} Returns the new wrapped function. */ function createPartialWrapper(func, bitmask, thisArg, partials) { var isBind = bitmask & BIND_FLAG, Ctor = createCtorWrapper(func); function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it `func`. var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, - args = Array(leftLength + argsLength); + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; @@ -37952,14 +40409,82 @@ return jQuery; while (argsLength--) { args[leftIndex++] = arguments[++argsIndex]; } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, args); + return apply(fn, isBind ? thisArg : this, args); } return wrapper; } /** - * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toNumber(start); + start = start === start ? start : 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & CURRY_FLAG, + newArgPos = argPos ? copyArray(argPos) : undefined, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!(bitmask & CURRY_BOUND_FLAG)) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + + /** + * Creates a function like `_.round`. * * @private * @param {string} methodName The name of the `Math` method to use when rounding. @@ -37968,38 +40493,39 @@ return jQuery; function createRound(methodName) { var func = Math[methodName]; return function(number, precision) { - precision = precision === undefined ? 0 : (+precision || 0); + number = toNumber(number); + precision = toInteger(precision); if (precision) { - precision = pow(10, precision); - return func(number * precision) / precision; + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); } return func(number); }; } /** - * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * Creates a set of `values`. * * @private - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {Function} Returns the new index function. - */ - function createSortedIndex(retHighest) { - return function(array, value, iteratee, thisArg) { - var callback = getCallback(iteratee); - return (iteratee == null && callback === baseCallback) - ? binaryIndex(array, value, retHighest) - : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); - }; - } + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + return new Set(values); + }; /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. * * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. * The bitmask may be composed of the following flags: * 1 - `_.bind` * 2 - `_.bindKey` @@ -38028,29 +40554,44 @@ return jQuery; bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); partials = holders = undefined; } - length -= (holders ? holders.length : 0); + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + if (bitmask & PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; partials = holders = undefined; } - var data = isBindKey ? undefined : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; if (data) { mergeData(newData, data); - bitmask = newData[1]; - arity = newData[9]; } - newData[9] = arity == null + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] == null ? (isBindKey ? 0 : func.length) - : (nativeMax(arity - length, 0) || 0); + : nativeMax(newData[9] - length, 0); - if (bitmask == BIND_FLAG) { - var result = createBindWrapper(newData[0], newData[2]); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { - result = createPartialWrapper.apply(undefined, newData); + if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { + bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == BIND_FLAG) { + var result = createBaseWrapper(func, bitmask, thisArg); + } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { + result = createCurryWrapper(func, bitmask, arity); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { + result = createPartialWrapper(func, bitmask, thisArg, partials); } else { result = createHybridWrapper.apply(undefined, newData); } @@ -38066,44 +40607,61 @@ return jQuery; * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ - function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, arrLength = array.length, othLength = other.length; - if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(array, other); + // Ignore non-index properties. while (++index < arrLength) { var arrValue = array[index], - othValue = other[index], - result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + othValue = other[index]; - if (result !== undefined) { - if (result) { + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { continue; } - return false; + result = false; + break; } // Recursively compare arrays (susceptible to call stack limits). - if (isLoose) { + if (isUnordered) { if (!arraySome(other, function(othValue) { - return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); })) { - return false; + result = false; + break; } - } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { - return false; + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; } } - return true; + stack['delete'](array); + return result; } /** @@ -38117,10 +40675,20 @@ return jQuery; * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ - function equalByTag(object, other, tag) { + function equalByTag(object, other, tag, equalFunc, customizer, bitmask) { switch (tag) { + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + case boolTag: case dateTag: // Coerce dates and booleans to numbers, dates to milliseconds and booleans @@ -38132,15 +40700,27 @@ return jQuery; case numberTag: // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - : object == +other; + return (object != +object) ? other != +other : object == +other; case regexpTag: case stringTag: // Coerce regexes to strings and treat strings primitives and string // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + // Recursively compare objects (susceptible to call stack limits). + return (isPartial || object.size == other.size) && + equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG); + + case symbolTag: + return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other)); } return false; } @@ -38153,42 +40733,58 @@ return jQuery; * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ - function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objProps = keys(object), + function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), objLength = objProps.length, othProps = keys(other), othLength = othProps.length; - if (objLength != othLength && !isLoose) { + if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; - if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + if (!(isPartial ? key in other : baseHas(other, key))) { return false; } } - var skipCtor = isLoose; + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(object, other); + + var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], - othValue = other[key], - result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + othValue = other[key]; + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } // Recursively compare objects (susceptible to call stack limits). - if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { - return false; + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; } skipCtor || (skipCtor = key == 'constructor'); } - if (!skipCtor) { + if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; @@ -38197,25 +40793,11 @@ return jQuery; ('constructor' in object && 'constructor' in other) && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { - return false; + result = false; } } - return true; - } - - /** - * Gets the appropriate "callback" function. If the `_.callback` method is - * customized this function returns the custom method, otherwise it returns - * the `baseCallback` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. - * - * @private - * @returns {Function} Returns the chosen function or its result. - */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; + stack['delete'](object); + return result; } /** @@ -38237,9 +40819,9 @@ return jQuery; * @returns {string} Returns the function name. */ function getFuncName(func) { - var result = func.name, + var result = (func.name + ''), array = realNames[result], - length = array ? array.length : 0; + length = hasOwnProperty.call(realNames, result) ? array.length : 0; while (length--) { var data = array[length], @@ -38252,18 +40834,20 @@ return jQuery; } /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * Gets the appropriate "iteratee" function. If the `_.iteratee` method is * customized this function returns the custom method, otherwise it returns - * the `baseIndexOf` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. + * `baseIteratee`. If arguments are provided the chosen function is invoked + * with them and its result is returned. * * @private - * @returns {Function|number} Returns the chosen function or its result. + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. */ - function getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; } /** @@ -38279,14 +40863,14 @@ return jQuery; var getLength = baseProperty('length'); /** - * Gets the propery names, values, and compare flags of `object`. + * Gets the property names, values, and compare flags of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { - var result = pairs(object), + var result = toPairs(object), length = result.length; while (length--) { @@ -38309,6 +40893,60 @@ return jQuery; } /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getPlaceholder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Creates an array of the own symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = getOwnPropertySymbols || function() { + return []; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function getTag(value) { + return objectToString.call(value); + } + + // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. + if ((Map && getTag(new Map) != mapTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : null, + ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case mapCtorString: return mapTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** * Gets the view, applying any `transforms` to the `start` and `end` positions. * * @private @@ -38337,6 +40975,35 @@ return jQuery; } /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + if (object == null) { + return false; + } + var result = hasFunc(object, path); + if (!result && !isKey(path)) { + path = baseCastPath(path); + object = parent(object, path); + if (object != null) { + path = last(path); + result = hasFunc(object, path); + } + } + var length = object ? object.length : undefined; + return result || ( + !!length && isLength(length) && isIndex(path, length) && + (isArray(object) || isString(object) || isArguments(object)) + ); + } + + /** * Initializes an array clone. * * @private @@ -38345,9 +41012,9 @@ return jQuery; */ function initCloneArray(array) { var length = array.length, - result = new array.constructor(length); + result = array.constructor(length); - // Add array properties assigned by `RegExp#exec`. + // Add properties assigned by `RegExp#exec`. if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { result.index = array.index; result.input = array.input; @@ -38363,11 +41030,9 @@ return jQuery; * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; - } - return new Ctor; + return (isFunction(object.constructor) && !isPrototype(object)) + ? baseCreate(getPrototypeOf(object)) + : {}; } /** @@ -38386,7 +41051,7 @@ return jQuery; var Ctor = object.constructor; switch (tag) { case arrayBufferTag: - return bufferClone(object); + return cloneArrayBuffer(object); case boolTag: case dateTag: @@ -38395,66 +41060,45 @@ return jQuery; case float32Tag: case float64Tag: case int8Tag: case int16Tag: case int32Tag: case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - var buffer = object.buffer; - return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object); case numberTag: case stringTag: return new Ctor(object); case regexpTag: - var result = new Ctor(object.source, reFlags.exec(object)); - result.lastIndex = object.lastIndex; + return cloneRegExp(object); + + case setTag: + return cloneSet(object); + + case symbolTag: + return cloneSymbol(object); } - return result; } /** - * Invokes the method at `path` on `object`. + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. * * @private * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. + * @returns {Array|null} Returns index keys, else `null`. */ - function invokePath(object, path, args) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); } - var func = object == null ? object : object[path]; - return func == null ? undefined : func.apply(object, args); - } - - /** - * Checks if `value` is array-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - */ - function isArrayLike(value) { - return value != null && isLength(getLength(value)); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; + return null; } /** - * Checks if the provided arguments are from an iteratee call. + * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. @@ -38470,8 +41114,7 @@ return jQuery; if (type == 'number' ? (isArrayLike(object) && isIndex(index, object.length)) : (type == 'string' && index in object)) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); + return eq(object[index], value); } return false; } @@ -38485,15 +41128,25 @@ return jQuery; * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { - var type = typeof value; - if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + if (typeof value == 'number') { return true; } - if (isArray(value)) { - return false; - } - var result = !reIsDeepProp.test(value); - return result || (object != null && value in toObject(object)); + return !isArray(value) && + (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object))); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return type == 'number' || type == 'boolean' || + (type == 'string' && value != '__proto__') || value == null; } /** @@ -38504,11 +41157,12 @@ return jQuery; * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. */ function isLaziable(func) { - var funcName = getFuncName(func); - if (!(funcName in LazyWrapper.prototype)) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { return false; } - var other = lodash[funcName]; if (func === other) { return true; } @@ -38517,16 +41171,17 @@ return jQuery; } /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ - function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (isFunction(Ctor) && Ctor.prototype) || objectProto; + + return value === proto; } /** @@ -38544,12 +41199,12 @@ return jQuery; /** * Merges the function metadata of `source` into `data`. * - * Merging metadata reduces the number of wrappers required to invoke a function. + * Merging metadata reduces the number of wrappers used to invoke a function. * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` - * augment function arguments, making the order in which they are executed important, + * modify function arguments, making the order in which they are executed important, * preventing the merging of metadata. However, we make an exception for a safe - * common case where curried functions have `_.ary` and or `_.rearg` applied. + * combined case where curried functions have `_.ary` and or `_.rearg` applied. * * @private * @param {Array} data The destination metadata. @@ -38560,12 +41215,12 @@ return jQuery; var bitmask = data[1], srcBitmask = source[1], newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < ARY_FLAG; + isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); var isCombo = - (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || - (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || - (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || + ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); // Exit early if metadata can't be merged. if (!(isCommon || isCombo)) { @@ -38575,26 +41230,26 @@ return jQuery; if (srcBitmask & BIND_FLAG) { data[2] = source[2]; // Set when currying a bound function. - newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; } // Compose partial arguments. var value = source[3]; if (value) { var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); } // Compose partial right arguments. value = source[5]; if (value) { partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); } // Use source `argPos` if available. value = source[7]; if (value) { - data[7] = arrayCopy(value); + data[7] = copyArray(value); } // Use source `ary` if it's smaller. if (srcBitmask & ARY_FLAG) { @@ -38615,56 +41270,32 @@ return jQuery; * Used by `_.defaultsDeep` to customize its `_.merge` use. * * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. - */ - function mergeDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); - } - - /** - * A specialized version of `_.pick` which picks `object` properties specified - * by `props`. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property names to pick. - * @returns {Object} Returns the new object. + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + * @returns {*} Returns the value to assign. */ - function pickByArray(object, props) { - object = toObject(object); - - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } + function mergeDefaults(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack); } - return result; + return objValue; } /** - * A specialized version of `_.pick` which picks `object` properties `predicate` - * returns truthy for. + * Gets the parent value at `path` of `object`. * * @private - * @param {Object} object The source object. - * @param {Function} predicate The function invoked per iteration. - * @returns {Object} Returns the new object. + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. */ - function pickByCallback(object, predicate) { - var result = {}; - baseForIn(object, function(value, key, object) { - if (predicate(value, key, object)) { - result[key] = value; - } - }); - return result; + function parent(object, path) { + return path.length == 1 ? object : get(object, baseSlice(path, 0, -1)); } /** @@ -38680,7 +41311,7 @@ return jQuery; function reorder(array, indexes) { var arrLength = array.length, length = nativeMin(indexes.length, arrLength), - oldArray = arrayCopy(array); + oldArray = copyArray(array); while (length--) { var index = indexes[length]; @@ -38723,74 +41354,15 @@ return jQuery; }()); /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; - - var allowIndexes = !!length && isLength(length) && - (isArray(object) || isArguments(object)); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to an array-like object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array|Object} Returns the array-like object. - */ - function toIterable(value) { - if (value == null) { - return []; - } - if (!isArrayLike(value)) { - return values(value); - } - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to an object if it's not one. + * Converts `string` to a property path array. * * @private - * @param {*} value The value to process. - * @returns {Object} Returns the object. - */ - function toObject(value) { - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to property path array if it's not one. - * - * @private - * @param {*} value The value to process. + * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ - function toPath(value) { - if (isArray(value)) { - return value; - } + function stringToPath(string) { var result = []; - baseToString(value).replace(rePropName, function(match, number, quote, string) { + toString(string).replace(rePropName, function(match, number, quote, string) { result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); }); return result; @@ -38804,24 +41376,28 @@ return jQuery; * @returns {Object} Returns the cloned wrapper. */ function wrapperClone(wrapper) { - return wrapper instanceof LazyWrapper - ? wrapper.clone() - : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; } /*------------------------------------------------------------------------*/ /** * Creates an array of elements split into groups the length of `size`. - * If `collection` can't be split evenly, the final chunk will be the remaining + * If `array` can't be split evenly, the final chunk will be the remaining * elements. * * @static * @memberOf _ * @category Array * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param {number} [size=0] The length of each chunk. * @returns {Array} Returns the new array containing chunks. * @example * @@ -38831,14 +41407,14 @@ return jQuery; * _.chunk(['a', 'b', 'c', 'd'], 3); * // => [['a', 'b', 'c'], ['d']] */ - function chunk(array, size, guard) { - if (guard ? isIterateeCall(array, size, guard) : size == null) { - size = 1; - } else { - size = nativeMax(nativeFloor(size) || 1, 1); + function chunk(array, size) { + size = nativeMax(toInteger(size), 0); + + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; } var index = 0, - length = array ? array.length : 0, resIndex = -1, result = Array(nativeCeil(length / size)); @@ -38878,24 +41454,113 @@ return jQuery; } /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); + }); + + /** * Creates an array of unique `array` values not included in the other - * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static * @memberOf _ * @category Array * @param {Array} array The array to inspect. - * @param {...Array} [values] The arrays of values to exclude. + * @param {...Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @example * - * _.difference([1, 2, 3], [4, 2]); - * // => [1, 3] + * _.difference([3, 2, 1], [4, 2]); + * // => [3, 1] + */ + var difference = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); + * // => [3.1, 1.3] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = rest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] */ - var difference = restParam(function(array, values) { - return (isObjectLike(array) && isArrayLike(array)) - ? baseDifference(array, baseFlatten(values, false, true)) + var differenceWith = rest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) : []; }); @@ -38907,7 +41572,7 @@ return jQuery; * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -38928,10 +41593,8 @@ return jQuery; if (!length) { return []; } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, n < 0 ? 0 : n); + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); } /** @@ -38942,7 +41605,7 @@ return jQuery; * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -38963,120 +41626,88 @@ return jQuery; if (!length) { return []; } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; return baseSlice(array, 0, n < 0 ? 0 : n); } /** * Creates a slice of `array` excluding elements dropped from the end. * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that match the properties of the given - * object, else `false`. + * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @category Array * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * - * _.dropRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [1] - * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['barney', 'fred'] + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); - * // => ['barney'] + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] * - * // using the `_.property` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] */ - function dropRightWhile(array, predicate, thisArg) { + function dropRightWhile(array, predicate) { return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + ? baseWhile(array, getIteratee(predicate, 3), true, true) : []; } /** * Creates a slice of `array` excluding elements dropped from the beginning. * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @category Array * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * - * _.dropWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [3] - * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['fred', 'pebbles'] + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropWhile(users, 'active', false), 'user'); - * // => ['pebbles'] + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] * - * // using the `_.property` callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] */ - function dropWhile(array, predicate, thisArg) { + function dropWhile(array, predicate) { return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + ? baseWhile(array, getIteratee(predicate, 3), true) : []; } @@ -39105,8 +41736,8 @@ return jQuery; * _.fill(Array(3), 2); * // => [2, 2, 2] * - * _.fill([4, 6, 8], '*', 1, 2); - * // => [4, '*', 8] + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] */ function fill(array, value, start, end) { var length = array ? array.length : 0; @@ -39124,24 +41755,11 @@ return jQuery; * This method is like `_.find` except that it returns the index of the first * element `predicate` returns truthy for instead of the element itself. * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * * @static * @memberOf _ * @category Array * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {number} Returns the index of the found element, else `-1`. * @example * @@ -39151,47 +41769,36 @@ return jQuery; * { 'user': 'pebbles', 'active': true } * ]; * - * _.findIndex(users, function(chr) { - * return chr.user == 'barney'; - * }); + * _.findIndex(users, function(o) { return o.user == 'barney'; }); * // => 0 * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.findIndex(users, { 'user': 'fred', 'active': false }); * // => 1 * - * // using the `_.matchesProperty` callback shorthand - * _.findIndex(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); * // => 0 * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.findIndex(users, 'active'); * // => 2 */ - var findIndex = createFindIndex(); + function findIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3)) + : -1; + } /** * This method is like `_.findIndex` except that it iterates over elements * of `collection` from right to left. * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * * @static * @memberOf _ * @category Array * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {number} Returns the index of the found element, else `-1`. * @example * @@ -39201,136 +41808,170 @@ return jQuery; * { 'user': 'pebbles', 'active': false } * ]; * - * _.findLastIndex(users, function(chr) { - * return chr.user == 'pebbles'; - * }); + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); * // => 2 * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * - * // using the `_.matchesProperty` callback shorthand - * _.findLastIndex(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); * // => 2 * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.findLastIndex(users, 'active'); * // => 0 */ - var findLastIndex = createFindIndex(true); + function findLastIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3), true) + : -1; + } /** - * Gets the first element of `array`. + * Flattens `array` a single level deep. * * @static * @memberOf _ - * @alias head * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. * @example * - * _.first([1, 2, 3]); - * // => 1 + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. * - * _.first([]); - * // => undefined + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] */ - function first(array) { - return array ? array[0] : undefined; + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; } /** - * Flattens a nested array. If `isDeep` is `true` the array is recursively - * flattened, otherwise it is only flattened a single level. + * Recursively flatten `array` up to `depth` times. * * @static * @memberOf _ * @category Array * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] + * var array = [1, [2, [3, [4]], 5]]; * - * // using `isDeep` - * _.flatten([1, [2, 3, [4]]], true); - * // => [1, 2, 3, 4] + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] */ - function flatten(array, isDeep, guard) { + function flattenDepth(array, depth) { var length = array ? array.length : 0; - if (guard && isIterateeCall(array, isDeep, guard)) { - isDeep = false; + if (!length) { + return []; } - return length ? baseFlatten(array, isDeep) : []; + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); } /** - * Recursively flattens a nested array. + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. * * @static * @memberOf _ * @category Array - * @param {Array} array The array to recursively flatten. - * @returns {Array} Returns the new flattened array. + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. * @example * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; + function fromPairs(pairs) { + var index = -1, + length = pairs ? pairs.length : 0, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return array ? array[0] : undefined; } /** * Gets the index at which the first occurrence of `value` is found in `array` * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it is used as the offset - * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` - * performs a faster binary search. + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. * * @static * @memberOf _ * @category Array * @param {Array} array The array to search. * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. + * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.indexOf([1, 2, 1, 2], 2); * // => 1 * - * // using `fromIndex` + * // Search from the `fromIndex`. * _.indexOf([1, 2, 1, 2], 2, 2); * // => 3 - * - * // performing a binary search - * _.indexOf([1, 1, 2, 2], 2, true); - * // => 2 */ function indexOf(array, value, fromIndex) { var length = array ? array.length : 0; if (!length) { return -1; } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; - } else if (fromIndex) { - var index = binaryIndex(array, value); - if (index < length && - (value === value ? (value === array[index]) : (array[index] !== array[index]))) { - return index; - } - return -1; + fromIndex = toInteger(fromIndex); + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); } - return baseIndexOf(array, value, fromIndex || 0); + return baseIndexOf(array, value, fromIndex); } /** @@ -39351,8 +41992,8 @@ return jQuery; } /** - * Creates an array of unique values that are included in all of the provided - * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -39361,47 +42002,103 @@ return jQuery; * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of shared values. * @example - * _.intersection([1, 2], [4, 2], [2, 1]); + * + * _.intersection([2, 1], [4, 2], [1, 2]); * // => [2] */ - var intersection = restParam(function(arrays) { - var othLength = arrays.length, - othIndex = othLength, - caches = Array(length), - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - result = []; + var intersection = rest(function(arrays) { + var mapped = arrayMap(arrays, baseCastArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); - while (othIndex--) { - var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; - caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of shared values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = rest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); } - var array = arrays[0], - index = -1, - length = array ? array.length : 0, - seen = caches[0]; + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee)) + : []; + }); - outer: - while (++index < length) { - value = array[index]; - if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { - var othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { - continue outer; - } - } - if (seen) { - seen.push(value); - } - result.push(value); - } + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = rest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (comparator === last(mapped)) { + comparator = undefined; + } else { + mapped.pop(); } - return result; + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; }); /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array ? nativeJoin.call(array, separator) : ''; + } + + /** * Gets the last element of `array`. * * @static @@ -39428,21 +42125,16 @@ return jQuery; * @category Array * @param {Array} array The array to search. * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=array.length-1] The index to search from - * or `true` to perform a binary search on a sorted array. + * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.lastIndexOf([1, 2, 1, 2], 2); * // => 3 * - * // using `fromIndex` + * // Search from the `fromIndex`. * _.lastIndexOf([1, 2, 1, 2], 2, 2); * // => 1 - * - * // performing a binary search - * _.lastIndexOf([1, 1, 2, 2], 2, true); - * // => 3 */ function lastIndexOf(array, value, fromIndex) { var length = array ? array.length : 0; @@ -39450,15 +42142,9 @@ return jQuery; return -1; } var index = length; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; - } else if (fromIndex) { - index = binaryIndex(array, value, true) - 1; - var other = array[index]; - if (value === value ? (value === other) : (other !== other)) { - return index; - } - return -1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; } if (value !== value) { return indexOfNaN(array, index, true); @@ -39472,11 +42158,12 @@ return jQuery; } /** - * Removes all provided values from `array` using + * Removes all given values from `array` using * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * - * **Note:** Unlike `_.without`, this method mutates `array`. + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. * * @static * @memberOf _ @@ -39492,32 +42179,64 @@ return jQuery; * console.log(array); * // => [1, 1] */ - function pull() { - var args = arguments, - array = args[0]; - - if (!(array && array.length)) { - return array; - } - var index = 0, - indexOf = getIndexOf(), - length = args.length; + var pull = rest(pullAll); - while (++index < length) { - var fromIndex = 0, - value = args[index]; + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pullAll(array, [2, 3]); + * console.log(array); + * // => [1, 1] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } - while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { - splice.call(array, fromIndex, 1); - } - } - return array; + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAllBy(array, values, getIteratee(iteratee)) + : array; } /** - * Removes elements from `array` corresponding to the given indexes and returns - * an array of the removed elements. Indexes may be specified as an array of - * indexes or as individual arguments. + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. * * **Note:** Unlike `_.at`, this method mutates `array`. * @@ -39526,7 +42245,7 @@ return jQuery; * @category Array * @param {Array} array The array to modify. * @param {...(number|number[])} [indexes] The indexes of elements to remove, - * specified as individual indexes or arrays of indexes. + * specified individually or in arrays. * @returns {Array} Returns the new array of removed elements. * @example * @@ -39539,39 +42258,27 @@ return jQuery; * console.log(evens); * // => [10, 20] */ - var pullAt = restParam(function(array, indexes) { - indexes = baseFlatten(indexes); + var pullAt = rest(function(array, indexes) { + indexes = arrayMap(baseFlatten(indexes, 1), String); var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(baseCompareAscending)); + basePullAt(array, indexes.sort(compareAscending)); return result; }); /** * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * **Note:** Unlike `_.filter`, this method mutates `array`. + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. * * @static * @memberOf _ * @category Array * @param {Array} array The array to modify. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new array of removed elements. * @example * @@ -39586,7 +42293,7 @@ return jQuery; * console.log(evens); * // => [2, 4] */ - function remove(array, predicate, thisArg) { + function remove(array, predicate) { var result = []; if (!(array && array.length)) { return result; @@ -39595,7 +42302,7 @@ return jQuery; indexes = [], length = array.length; - predicate = getCallback(predicate, thisArg, 3); + predicate = getIteratee(predicate, 3); while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { @@ -39608,28 +42315,35 @@ return jQuery; } /** - * Gets all but the first element of `array`. + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). * * @static * @memberOf _ - * @alias tail * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. + * @returns {Array} Returns `array`. * @example * - * _.rest([1, 2, 3]); - * // => [2, 3] + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] */ - function rest(array) { - return drop(array, 1); + function reverse(array) { + return array ? nativeReverse.call(array) : array; } /** * Creates a slice of `array` from `start` up to, but not including, `end`. * - * **Note:** This method is used instead of `Array#slice` to support node - * lists in IE < 9 and to ensure dense arrays are returned. + * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice) + * to ensure dense arrays are returned. * * @static * @memberOf _ @@ -39648,58 +42362,87 @@ return jQuery; start = 0; end = length; } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } return baseSlice(array, start, end); } /** * Uses a binary search to determine the lowest index at which `value` should - * be inserted into `array` in order to maintain its sort order. If an iteratee - * function is provided it is invoked for `value` and each element of `array` - * to compute their sort ranking. The iteratee is bound to `thisArg` and - * invoked with one argument; (value). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * be inserted into `array` in order to maintain its sort order. * * @static * @memberOf _ * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @returns {number} Returns the index at which `value` should be inserted into `array`. * @example * * _.sortedIndex([30, 50], 40); * // => 1 * - * _.sortedIndex([4, 4, 5, 5], 5); - * // => 2 + * _.sortedIndex([4, 5], 4); + * // => 0 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). * - * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example * - * // using an iteratee function - * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { - * return this.data[word]; - * }, dict); - * // => 1 + * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; * - * // using the `_.property` callback shorthand - * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([1, 1, 2, 2], 2); + * // => 2 */ - var sortedIndex = createSortedIndex(); + function sortedIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } /** * This method is like `_.sortedIndex` except that it returns the highest @@ -39711,17 +42454,121 @@ return jQuery; * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @returns {number} Returns the index at which `value` should be inserted into `array`. * @example * - * _.sortedLastIndex([4, 4, 5, 5], 5); - * // => 4 + * _.sortedLastIndex([4, 5], 4); + * // => 1 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([1, 1, 2, 2], 2); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniqBy(array, getIteratee(iteratee)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] */ - var sortedLastIndex = createSortedIndex(true); + function tail(array) { + return drop(array, 1); + } /** * Creates a slice of `array` with `n` elements taken from the beginning. @@ -39731,7 +42578,7 @@ return jQuery; * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -39748,13 +42595,10 @@ return jQuery; * // => [] */ function take(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { + if (!(array && array.length)) { return []; } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } + n = (guard || n === undefined) ? 1 : toInteger(n); return baseSlice(array, 0, n < 0 ? 0 : n); } @@ -39766,7 +42610,7 @@ return jQuery; * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -39787,126 +42631,94 @@ return jQuery; if (!length) { return []; } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, n < 0 ? 0 : n); + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); } /** * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is bound to `thisArg` - * and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * taken until `predicate` returns falsey. The predicate is invoked with three + * arguments: (value, index, array). * * @static * @memberOf _ * @category Array * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * - * _.takeRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [2, 3] - * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['pebbles'] + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); - * // => ['fred', 'pebbles'] + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] * - * // using the `_.property` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); * // => [] */ - function takeRightWhile(array, predicate, thisArg) { + function takeRightWhile(array, predicate) { return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + ? baseWhile(array, getIteratee(predicate, 3), false, true) : []; } /** * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). * * @static * @memberOf _ * @category Array * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * - * _.takeWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [1, 2] - * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false}, * { 'user': 'pebbles', 'active': true } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['barney'] + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeWhile(users, 'active', false), 'user'); - * // => ['barney', 'fred'] + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] * - * // using the `_.property` callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); * // => [] */ - function takeWhile(array, predicate, thisArg) { + function takeWhile(array, predicate) { return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3)) + ? baseWhile(array, getIteratee(predicate, 3)) : []; } /** - * Creates an array of unique values, in order, from all of the provided arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * * @static @@ -39916,79 +42728,138 @@ return jQuery; * @returns {Array} Returns the new array of combined values. * @example * - * _.union([1, 2], [4, 2], [2, 1]); - * // => [1, 2, 4] + * _.union([2, 1], [4, 2], [1, 2]); + * // => [2, 1, 4] */ - var union = restParam(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); + var union = rest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, true)); }); /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurence of each element - * is kept. Providing `true` for `isSorted` performs a faster search algorithm - * for sorted arrays. If an iteratee function is provided it is invoked for - * each element in the array to generate the criterion by which uniqueness - * is computed. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index, array). + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1, 1.2, 4.3] * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. * * @static * @memberOf _ - * @alias unique * @category Array * @param {Array} array The array to inspect. - * @param {boolean} [isSorted] Specify the array is sorted. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new duplicate-value-free array. + * @returns {Array} Returns the new duplicate free array. * @example * * _.uniq([2, 1, 2]); * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) + ? baseUniq(array) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). * - * // using `isSorted` - * _.uniq([1, 1, 2], true); - * // => [1, 2] + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example * - * // using an iteratee function - * _.uniq([1, 2.5, 1.5, 2], function(n) { - * return this.floor(n); - * }, Math); - * // => [1, 2.5] + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] * - * // using the `_.property` callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ - function uniq(array, isSorted, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (isSorted != null && typeof isSorted != 'boolean') { - thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; - isSorted = false; - } - var callback = getCallback(); - if (!(iteratee == null && callback === baseCallback)) { - iteratee = callback(iteratee, thisArg, 3); - } - return (isSorted && getIndexOf() == baseIndexOf) - ? sortedUniq(array, iteratee) - : baseUniq(array, iteratee); + function uniqBy(array, iteratee) { + return (array && array.length) + ? baseUniq(array, getIteratee(iteratee)) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + return (array && array.length) + ? baseUniq(array, undefined, comparator) + : []; } /** @@ -40013,33 +42884,28 @@ return jQuery; if (!(array && array.length)) { return []; } - var index = -1, - length = 0; - + var length = 0; array = arrayFilter(array, function(group) { - if (isArrayLike(group)) { + if (isArrayLikeObject(group)) { length = nativeMax(group.length, length); return true; } }); - var result = Array(length); - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); } /** - * This method is like `_.unzip` except that it accepts an iteratee to specify - * how regrouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). * * @static * @memberOf _ * @category Array * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee] The function to combine regrouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Function} [iteratee=_.identity] The function to combine regrouped values. * @returns {Array} Returns the new array of regrouped elements. * @example * @@ -40049,23 +42915,21 @@ return jQuery; * _.unzipWith(zipped, _.add); * // => [3, 30, 300] */ - function unzipWith(array, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { + function unzipWith(array, iteratee) { + if (!(array && array.length)) { return []; } var result = unzip(array); if (iteratee == null) { return result; } - iteratee = bindCallback(iteratee, thisArg, 4); return arrayMap(result, function(group) { - return arrayReduce(group, iteratee, undefined, true); + return apply(iteratee, undefined, group); }); } /** - * Creates an array excluding all provided values using + * Creates an array excluding all given values using * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) * for equality comparisons. * @@ -40080,15 +42944,15 @@ return jQuery; * _.without([1, 2, 1, 3], 1, 2); * // => [3] */ - var without = restParam(function(array, values) { - return isArrayLike(array) + var without = rest(function(array, values) { + return isArrayLikeObject(array) ? baseDifference(array, values) : []; }); /** * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the provided arrays. + * of the given arrays. * * @static * @memberOf _ @@ -40097,23 +42961,67 @@ return jQuery; * @returns {Array} Returns the new array of values. * @example * - * _.xor([1, 2], [4, 2]); + * _.xor([2, 1], [4, 2]); * // => [1, 4] */ - function xor() { - var index = -1, - length = arguments.length; + var xor = rest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); - while (++index < length) { - var array = arguments[index]; - if (isArrayLike(array)) { - var result = result - ? arrayPush(baseDifference(result, array), baseDifference(array, result)) - : array; - } + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [1.2, 4.3] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; } - return result ? baseUniq(result) : []; - } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); /** * Creates an array of grouped elements, the first of which contains the first @@ -40130,89 +43038,80 @@ return jQuery; * _.zip(['fred', 'barney'], [30, 40], [true, false]); * // => [['fred', 30, true], ['barney', 40, false]] */ - var zip = restParam(unzip); + var zip = rest(unzip); /** - * The inverse of `_.pairs`; this method returns an object composed from arrays - * of property names and values. Provide either a single two dimensional array, - * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names - * and one of corresponding values. + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property names and one of corresponding values. * * @static * @memberOf _ - * @alias object * @category Array - * @param {Array} props The property names. + * @param {Array} [props=[]] The property names. * @param {Array} [values=[]] The property values. * @returns {Object} Returns the new object. * @example * - * _.zipObject([['fred', 30], ['barney', 40]]); - * // => { 'fred': 30, 'barney': 40 } - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } */ function zipObject(props, values) { - var index = -1, - length = props ? props.length : 0, - result = {}; + return baseZipObject(props || [], values || [], assignValue); + } - if (length && !values && !isArray(props[0])) { - values = []; - } - while (++index < length) { - var key = props[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} [props=[]] The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); } /** - * This method is like `_.zip` except that it accepts an iteratee to specify - * how grouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). * * @static * @memberOf _ * @category Array * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee] The function to combine grouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Function} [iteratee=_.identity] The function to combine grouped values. * @returns {Array} Returns the new array of grouped elements. * @example * - * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); * // => [111, 222] */ - var zipWith = restParam(function(arrays) { + var zipWith = rest(function(arrays) { var length = arrays.length, - iteratee = length > 2 ? arrays[length - 2] : undefined, - thisArg = length > 1 ? arrays[length - 1] : undefined; + iteratee = length > 1 ? arrays[length - 1] : undefined; - if (length > 2 && typeof iteratee == 'function') { - length -= 2; - } else { - iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; - thisArg = undefined; - } - arrays.length = length; - return unzipWith(arrays, iteratee, thisArg); + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); }); /*------------------------------------------------------------------------*/ /** - * Creates a `lodash` object that wraps `value` with explicit method - * chaining enabled. + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. * * @static * @memberOf _ - * @category Chain + * @category Seq * @param {*} value The value to wrap. * @returns {Object} Returns the new `lodash` wrapper instance. * @example @@ -40223,12 +43122,13 @@ return jQuery; * { 'user': 'pebbles', 'age': 1 } * ]; * - * var youngest = _.chain(users) + * var youngest = _ + * .chain(users) * .sortBy('age') - * .map(function(chr) { - * return chr.user + ' is ' + chr.age; + * .map(function(o) { + * return o.user + ' is ' + o.age; * }) - * .first() + * .head() * .value(); * // => 'pebbles is 1' */ @@ -40239,42 +43139,42 @@ return jQuery; } /** - * This method invokes `interceptor` and returns `value`. The interceptor is - * bound to `thisArg` and invoked with one argument; (value). The purpose of - * this method is to "tap into" a method chain in order to perform operations - * on intermediate results within the chain. + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain in order to modify intermediate results. * * @static * @memberOf _ - * @category Chain + * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. * @returns {*} Returns `value`. * @example * * _([1, 2, 3]) * .tap(function(array) { + * // Mutate input array. * array.pop(); * }) * .reverse() * .value(); * // => [2, 1] */ - function tap(value, interceptor, thisArg) { - interceptor.call(thisArg, value); + function tap(value, interceptor) { + interceptor(value); return value; } /** * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain. * * @static * @memberOf _ - * @category Chain + * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. * @returns {*} Returns the result of `interceptor`. * @example * @@ -40287,16 +43187,60 @@ return jQuery; * .value(); * // => ['abc'] */ - function thru(value, interceptor, thisArg) { - return interceptor.call(thisArg, value); + function thru(value, interceptor) { + return interceptor(value); } /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @category Seq + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + * + * _(['a', 'b', 'c']).at(0, 2).value(); + * // => ['a', 'c'] + */ + var wrapperAt = rest(function(paths) { + paths = baseFlatten(paths, 1); + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** * Enables explicit method chaining on the wrapper object. * * @name chain * @memberOf _ - * @category Chain + * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * @@ -40305,13 +43249,14 @@ return jQuery; * { 'user': 'fred', 'age': 40 } * ]; * - * // without explicit chaining - * _(users).first(); + * // A sequence without explicit chaining. + * _(users).head(); * // => { 'user': 'barney', 'age': 36 } * - * // with explicit chaining - * _(users).chain() - * .first() + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() * .pick('user') * .value(); * // => { 'user': 'barney' } @@ -40325,7 +43270,7 @@ return jQuery; * * @name commit * @memberOf _ - * @category Chain + * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * @@ -40350,50 +43295,96 @@ return jQuery; } /** - * Creates a new array joining a wrapped array with any additional arrays - * and/or values. + * This method is the wrapper version of `_.flatMap`. * - * @name concat + * @name flatMap * @memberOf _ - * @category Chain - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. + * @category Seq + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * - * var array = [1]; - * var wrapped = _(array).concat(2, [3], [[4]]); + * function duplicate(n) { + * return [n, n]; + * } * - * console.log(wrapped.value()); - * // => [1, 2, 3, [4]] + * _([1, 2]).flatMap(duplicate).value(); + * // => [1, 1, 2, 2] + */ + function wrapperFlatMap(iteratee) { + return this.map(iteratee).flatten(); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). * - * console.log(array); - * // => [1] + * @name next + * @memberOf _ + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } */ - var wrapperConcat = restParam(function(values) { - values = baseFlatten(values); - return this.thru(function(array) { - return arrayConcat(isArray(array) ? array : [toObject(array)], values); - }); - }); + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } /** * Creates a clone of the chained sequence planting `value` as the wrapped value. * * @name plant * @memberOf _ - * @category Chain + * @category Seq + * @param {*} value The value to plant. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * - * var array = [1, 2]; - * var wrapped = _(array).map(function(value) { - * return Math.pow(value, 2); - * }); + * function square(n) { + * return n * n; + * } * - * var other = [3, 4]; - * var otherWrapped = wrapped.plant(other); + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); * - * otherWrapped.value(); + * other.value(); * // => [9, 16] * * wrapped.value(); @@ -40405,6 +43396,8 @@ return jQuery; while (parent instanceof baseLodash) { var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; if (result) { previous.__wrapped__ = clone; } else { @@ -40418,15 +43411,14 @@ return jQuery; } /** - * Reverses the wrapped array so the first element becomes the last, the - * second element becomes the second to last, and so on. + * This method is the wrapper version of `_.reverse`. * * **Note:** This method mutates the wrapped array. * * @name reverse * @memberOf _ - * @category Chain - * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var array = [1, 2, 3]; @@ -40439,36 +43431,20 @@ return jQuery; */ function wrapperReverse() { var value = this.__wrapped__; - - var interceptor = function(value) { - return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); - }; if (value instanceof LazyWrapper) { var wrapped = value; if (this.__actions__.length) { wrapped = new LazyWrapper(this); } wrapped = wrapped.reverse(); - wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); return new LodashWrapper(wrapped, this.__chain__); } - return this.thru(interceptor); - } - - /** - * Produces the result of coercing the unwrapped value to a string. - * - * @name toString - * @memberOf _ - * @category Chain - * @returns {string} Returns the coerced string value. - * @example - * - * _([1, 2, 3]).toString(); - * // => '1,2,3' - */ - function wrapperToString() { - return (this.value() + ''); + return this.thru(reverse); } /** @@ -40476,8 +43452,8 @@ return jQuery; * * @name value * @memberOf _ - * @alias run, toJSON, valueOf - * @category Chain + * @alias toJSON, valueOf + * @category Seq * @returns {*} Returns the resolved unwrapped value. * @example * @@ -40491,65 +43467,20 @@ return jQuery; /*------------------------------------------------------------------------*/ /** - * Creates an array of elements corresponding to the given keys, or indexes, - * of `collection`. Keys may be specified as individual arguments or as arrays - * of keys. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [props] The property names - * or indexes of elements to pick, specified individually or in arrays. - * @returns {Array} Returns the new array of picked elements. - * @example - * - * _.at(['a', 'b', 'c'], [0, 2]); - * // => ['a', 'c'] - * - * _.at(['barney', 'fred', 'pebbles'], 0, 2); - * // => ['barney', 'pebbles'] - */ - var at = restParam(function(collection, props) { - return baseAt(collection, baseFlatten(props)); - }); - - /** * Creates an object composed of keys generated from the results of running * each element of `collection` through `iteratee`. The corresponding value * of each key is the number of times the key was returned by `iteratee`. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return Math.floor(n); - * }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); + * _.countBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': 1, '6': 2 } * * _.countBy(['one', 'two', 'three'], 'length'); @@ -40561,30 +43492,16 @@ return jQuery; /** * Checks if `predicate` returns truthy for **all** elements of `collection`. - * The predicate is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). * * @static * @memberOf _ - * @alias all * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. * @example * * _.every([true, 1, null, 'yes'], Boolean); @@ -40595,108 +43512,74 @@ return jQuery; * { 'user': 'fred', 'active': false } * ]; * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.every(users, { 'user': 'barney', 'active': false }); * // => false * - * // using the `_.matchesProperty` callback shorthand - * _.every(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); * // => true * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.every(users, 'active'); * // => false */ - function every(collection, predicate, thisArg) { + function every(collection, predicate, guard) { var func = isArray(collection) ? arrayEvery : baseEvery; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); + return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). * * @static * @memberOf _ - * @alias select * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @example * - * _.filter([4, 5, 6], function(n) { - * return n % 2 == 0; - * }); - * // => [4, 6] - * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); - * // => ['barney'] + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.filter(users, 'active', false), 'user'); - * // => ['fred'] + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] * - * // using the `_.property` callback shorthand - * _.pluck(_.filter(users, 'active'), 'user'); - * // => ['barney'] + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] */ - function filter(collection, predicate, thisArg) { + function filter(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, predicate); + return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). * * @static * @memberOf _ - * @alias detect * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {*} Returns the matched element, else `undefined`. * @example * @@ -40706,24 +43589,29 @@ return jQuery; * { 'user': 'pebbles', 'age': 1, 'active': true } * ]; * - * _.result(_.find(users, function(chr) { - * return chr.age < 40; - * }), 'user'); - * // => 'barney' + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' * - * // using the `_.matches` callback shorthand - * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); - * // => 'pebbles' + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' * - * // using the `_.matchesProperty` callback shorthand - * _.result(_.find(users, 'active', false), 'user'); - * // => 'fred' + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' * - * // using the `_.property` callback shorthand - * _.result(_.find(users, 'active'), 'user'); - * // => 'barney' + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' */ - var find = createFind(baseEach); + function find(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEach); + } /** * This method is like `_.find` except that it iterates over elements of @@ -40732,10 +43620,8 @@ return jQuery; * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {*} Returns the matched element, else `undefined`. * @example * @@ -40744,72 +43630,72 @@ return jQuery; * }); * // => 3 */ - var findLast = createFind(baseEachRight, true); + function findLast(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, true); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEachRight); + } /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning the first element that has equivalent property - * values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. + * Creates an array of flattened values by running each element in `collection` + * through `iteratee` and concating its result to the other mapped values. + * The iteratee is invoked with three arguments: (value, index|key, collection). * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {*} Returns the matched element, else `undefined`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); - * // => 'barney' + * function duplicate(n) { + * return [n, n]; + * } * - * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); - * // => 'fred' + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] */ - function findWhere(collection, source) { - return find(collection, baseMatches(source)); + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); } /** * Iterates over elements of `collection` invoking `iteratee` for each element. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). Iteratee functions may exit iteration early - * by explicitly returning `false`. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. * * **Note:** As with other "Collections" methods, objects with a "length" property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. * * @static * @memberOf _ * @alias each * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. + * @returns {Array|Object} Returns `collection`. * @example * - * _([1, 2]).forEach(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from left to right and returns the array + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` * - * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { - * console.log(n, key); + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); * }); - * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + * // => logs 'a' then 'b' (iteration order is not guaranteed) */ - var forEach = createForEach(arrayEach, baseEach); + function forEach(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, baseCastFunction(iteratee)); + } /** * This method is like `_.forEach` except that it iterates over elements of @@ -40819,58 +43705,40 @@ return jQuery; * @memberOf _ * @alias eachRight * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. + * @returns {Array|Object} Returns `collection`. * @example * - * _([1, 2]).forEachRight(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from right to left and returns the array + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => logs `2` then `1` */ - var forEachRight = createForEach(arrayEachRight, baseEachRight); + function forEachRight(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, baseCastFunction(iteratee)); + } /** * Creates an object composed of keys generated from the results of running * each element of `collection` through `iteratee`. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * of each key is an array of elements responsible for generating the key. + * The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return Math.floor(n); - * }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ @@ -40883,20 +43751,19 @@ return jQuery; }); /** - * Checks if `value` is in `collection` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it is used as the offset - * from the end of `collection`. + * Checks if `value` is in `collection`. If `collection` is a string it's checked + * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. * * @static * @memberOf _ - * @alias contains, include * @category Collection * @param {Array|Object|string} collection The collection to search. - * @param {*} target The value to search for. + * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. * @example * * _.includes([1, 2, 3], 1); @@ -40911,95 +43778,42 @@ return jQuery; * _.includes('pebbles', 'eb'); * // => true */ - function includes(collection, target, fromIndex, guard) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - collection = values(collection); - length = collection.length; - } - if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { - fromIndex = 0; - } else { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); } - return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) - : (!!length && getIndexOf(collection, target, fromIndex) > -1); + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); } /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the last element responsible for generating the key. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keyData = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keyData, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { - * return String.fromCharCode(object.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { - * return this.fromCharCode(object.code); - * }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** * Invokes the method at `path` of each element in `collection`, returning * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `methodName` is a function it is + * are provided to each invoked method. If `methodName` is a function it's * invoked for, and `this` bound to, each element in `collection`. * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Array|Function|string} path The path of the method to invoke or * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke the method with. + * @param {...*} [args] The arguments to invoke each method with. * @returns {Array} Returns the array of results. * @example * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); * // => [[1, 5, 7], [1, 2, 3]] * - * _.invoke([123, 456], String.prototype.split, ''); + * _.invokeMap([123, 456], String.prototype.split, ''); * // => [['1', '2', '3'], ['4', '5', '6']] */ - var invoke = restParam(function(collection, path, args) { + var invokeMap = rest(function(collection, path, args) { var index = -1, isFunc = typeof path == 'function', isProp = isKey(path), @@ -41007,201 +43821,209 @@ return jQuery; baseEach(collection, function(value) { var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); - result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); }); return result; }); /** - * Creates an array of values by running each element in `collection` through - * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. * * The guarded methods are: - * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, - * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, - * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, - * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, - * `sum`, `uniq`, and `words` + * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, + * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, + * and `words` * * @static * @memberOf _ - * @alias collect * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new mapped array. * @example * - * function timesThree(n) { - * return n * 3; + * function square(n) { + * return n * n; * } * - * _.map([1, 2], timesThree); - * // => [3, 6] + * _.map([4, 8], square); + * // => [16, 64] * - * _.map({ 'a': 1, 'b': 2 }, timesThree); - * // => [3, 6] (iteration order is not guaranteed) + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) * * var users = [ * { 'user': 'barney' }, * { 'user': 'fred' } * ]; * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.map(users, 'user'); * // => ['barney', 'fred'] */ - function map(collection, iteratee, thisArg) { + function map(collection, iteratee) { var func = isArray(collection) ? arrayMap : baseMap; - iteratee = getCallback(iteratee, thisArg, 3); - return func(collection, iteratee); + return func(collection, getIteratee(iteratee, 3)); } /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, while the second of which - * contains elements `predicate` returns falsey for. The predicate is bound - * to `thisArg` and invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the array of grouped elements. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. * @example * - * _.partition([1, 2, 3], function(n) { - * return n % 2; - * }); - * // => [[1, 3], [2]] - * - * _.partition([1.2, 2.3, 3.4], function(n) { - * return this.floor(n) % 2; - * }, Math); - * // => [[1.2, 3.4], [2.3]] - * * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } * ]; * - * var mapper = function(array) { - * return _.pluck(array, 'user'); - * }; - * - * // using the `_.matches` callback shorthand - * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); - * // => [['pebbles'], ['barney', 'fred']] - * - * // using the `_.matchesProperty` callback shorthand - * _.map(_.partition(users, 'active', false), mapper); - * // => [['barney', 'pebbles'], ['fred']] - * - * // using the `_.property` callback shorthand - * _.map(_.partition(users, 'active'), mapper); - * // => [['fred'], ['barney', 'pebbles']] + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } /** - * Gets the property value of `path` from all elements in `collection`. + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|string} path The path of the property to pluck. - * @returns {Array} Returns the property values. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. * @example * * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } * ]; * - * _.pluck(users, 'user'); - * // => ['barney', 'fred'] + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] * - * var userIndex = _.indexBy(users, 'user'); - * _.pluck(userIndex, 'age'); - * // => [36, 40] (iteration order is not guaranteed) + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] */ - function pluck(collection, path) { - return map(collection, property(path)); - } + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); /** * Reduces `collection` to a value which is the accumulated result of running * each element in `collection` through `iteratee`, where each successive * invocation is supplied the return value of the previous. If `accumulator` - * is not provided the first element of `collection` is used as the initial - * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * is not given the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: * (accumulator, value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, - * and `sortByOrder` + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` * * @static * @memberOf _ - * @alias foldl, inject * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {*} Returns the accumulated value. * @example * - * _.reduce([1, 2], function(total, n) { - * return total + n; - * }); + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); * // => 3 * - * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { - * result[key] = n * 3; + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); * return result; * }, {}); - * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) */ - var reduce = createReduce(arrayReduce, baseEach); + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } /** * This method is like `_.reduce` except that it iterates over elements of @@ -41209,12 +44031,10 @@ return jQuery; * * @static * @memberOf _ - * @alias foldr * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {*} Returns the accumulated value. * @example * @@ -41225,7 +44045,12 @@ return jQuery; * }, []); * // => [4, 5, 2, 3, 0, 1] */ - var reduceRight = createReduce(arrayReduceRight, baseEachRight); + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } /** * The opposite of `_.filter`; this method returns the elements of `collection` @@ -41234,73 +44059,84 @@ return jQuery; * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @example * - * _.reject([1, 2, 3, 4], function(n) { - * return n % 2 == 0; - * }); - * // => [1, 3] - * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true } * ]; * - * // using the `_.matches` callback shorthand - * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); - * // => ['barney'] + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.reject(users, 'active', false), 'user'); - * // => ['fred'] + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] * - * // using the `_.property` callback shorthand - * _.pluck(_.reject(users, 'active'), 'user'); - * // => ['barney'] + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] */ - function reject(collection, predicate, thisArg) { + function reject(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); + predicate = getIteratee(predicate, 3); return func(collection, function(value, index, collection) { return !predicate(value, index, collection); }); } /** - * Gets a random element or `n` random elements from a collection. + * Gets a random element from `collection`. * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {*} Returns the random sample(s). + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. * @example * * _.sample([1, 2, 3, 4]); * // => 2 + */ + function sample(collection) { + var array = isArrayLike(collection) ? collection : values(collection), + length = array.length; + + return length > 0 ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=0] The number of elements to sample. + * @returns {Array} Returns the random elements. + * @example * - * _.sample([1, 2, 3, 4], 2); + * _.sampleSize([1, 2, 3], 2); * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] */ - function sample(collection, n, guard) { - if (guard ? isIterateeCall(collection, n, guard) : n == null) { - collection = toIterable(collection); - var length = collection.length; - return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; - } + function sampleSize(collection, n) { var index = -1, result = toArray(collection), length = result.length, lastIndex = length - 1; - n = nativeMin(n < 0 ? 0 : (+n || 0), length); + n = baseClamp(toInteger(n), 0, length); while (++index < n) { var rand = baseRandom(index, lastIndex), value = result[rand]; @@ -41319,7 +44155,7 @@ return jQuery; * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to shuffle. + * @param {Array|Object} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. * @example * @@ -41327,7 +44163,7 @@ return jQuery; * // => [4, 1, 3, 2] */ function shuffle(collection) { - return sample(collection, POSITIVE_INFINITY); + return sampleSize(collection, MAX_ARRAY_LENGTH); } /** @@ -41337,8 +44173,8 @@ return jQuery; * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the size of `collection`. + * @param {Array|Object} collection The collection to inspect. + * @returns {number} Returns the collection size. * @example * * _.size([1, 2, 3]); @@ -41351,37 +44187,28 @@ return jQuery; * // => 7 */ function size(collection) { - var length = collection ? getLength(collection) : 0; - return isLength(length) ? length : keys(collection).length; + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + var result = collection.length; + return (result && isString(collection)) ? stringSize(collection) : result; + } + return keys(collection).length; } /** * Checks if `predicate` returns truthy for **any** element of `collection`. - * The function returns as soon as it finds a passing value and does not iterate - * over the entire collection. The predicate is bound to `thisArg` and invoked - * with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). * * @static * @memberOf _ - * @alias any * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. * @example * * _.some([null, 0, 'yes', false], Boolean); @@ -41392,110 +44219,38 @@ return jQuery; * { 'user': 'fred', 'active': false } * ]; * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.some(users, { 'user': 'barney', 'active': false }); * // => false * - * // using the `_.matchesProperty` callback shorthand - * _.some(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); * // => true * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.some(users, 'active'); * // => true */ - function some(collection, predicate, thisArg) { + function some(collection, predicate, guard) { var func = isArray(collection) ? arraySome : baseSome; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); + return func(collection, getIteratee(predicate, 3)); } /** * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through `iteratee`. This method performs - * a stable sort, that is, it preserves the original sort order of equal elements. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new sorted array. - * @example - * - * _.sortBy([1, 2, 3], function(n) { - * return Math.sin(n); - * }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(n) { - * return this.sin(n); - * }, Math); - * // => [3, 1, 2] - * - * var users = [ - * { 'user': 'fred' }, - * { 'user': 'pebbles' }, - * { 'user': 'barney' } - * ]; - * - * // using the `_.property` callback shorthand - * _.pluck(_.sortBy(users, 'user'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function sortBy(collection, iteratee, thisArg) { - if (collection == null) { - return []; - } - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - var index = -1; - iteratee = getCallback(iteratee, thisArg, 3); - - var result = baseMap(collection, function(value, key, collection) { - return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; - }); - return baseSortBy(result, compareAscending); - } - - /** - * This method is like `_.sortBy` except that it can sort by multiple iteratees - * or property names. - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). * * @static * @memberOf _ * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees - * The iteratees to sort by, specified as individual values or arrays of values. + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. * @returns {Array} Returns the new sorted array. * @example * @@ -41506,117 +44261,41 @@ return jQuery; * { 'user': 'barney', 'age': 34 } * ]; * - * _.map(_.sortByAll(users, ['user', 'age']), _.values); - * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] * - * _.map(_.sortByAll(users, 'user', function(chr) { - * return Math.floor(chr.age / 10); - * }), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - var sortByAll = restParam(function(collection, iteratees) { + var sortBy = rest(function(collection, iteratees) { if (collection == null) { return []; } - var guard = iteratees[2]; - if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { iteratees.length = 1; } - return baseSortByOrder(collection, baseFlatten(iteratees), []); + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); }); - /** - * This method is like `_.sortByAll` except that it allows specifying the - * sort orders of the iteratees to sort by. If `orders` is unspecified, all - * values are sorted in ascending order. Otherwise, a value is sorted in - * ascending order if its corresponding order is "asc", and descending if "desc". - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 42 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // sort by `user` in ascending order and by `age` in descending order - * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] - */ - function sortByOrder(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (guard && isIterateeCall(iteratees, orders, guard)) { - orders = undefined; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseSortByOrder(collection, iteratees, orders); - } - - /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning an array of all elements that have equivalent - * property values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {Array} Returns the new filtered array. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, - * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); - * // => ['barney'] - * - * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); - * // => ['fred'] - */ - function where(collection, source) { - return filter(collection, baseMatches(source)); - } - /*------------------------------------------------------------------------*/ /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ + * @type {Function} * @category Date + * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { @@ -41624,15 +44303,13 @@ return jQuery; * }, _.now()); * // => logs the number of milliseconds it took for the deferred function to be invoked */ - var now = nativeNow || function() { - return new Date().getTime(); - }; + var now = Date.now; /*------------------------------------------------------------------------*/ /** * The opposite of `_.before`; this method creates a function that invokes - * `func` once it is called `n` or more times. + * `func` once it's called `n` or more times. * * @static * @memberOf _ @@ -41655,15 +44332,9 @@ return jQuery; */ function after(n, func) { if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } + throw new TypeError(FUNC_ERROR_TEXT); } - n = nativeIsFinite(n = +n) ? n : 0; + n = toInteger(n); return function() { if (--n < 1) { return func.apply(this, arguments); @@ -41672,7 +44343,7 @@ return jQuery; } /** - * Creates a function that accepts up to `n` arguments ignoring any + * Creates a function that accepts up to `n` arguments, ignoring any * additional arguments. * * @static @@ -41680,7 +44351,7 @@ return jQuery; * @category Function * @param {Function} func The function to cap arguments for. * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Function} Returns the new function. * @example * @@ -41688,16 +44359,14 @@ return jQuery; * // => [6, 8, 10] */ function ary(func, n, guard) { - if (guard && isIterateeCall(func, n, guard)) { - n = undefined; - } - n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it is called less than `n` times. Subsequent + * of the created function, while it's called less than `n` times. Subsequent * calls to the created function return the result of the last `func` invocation. * * @static @@ -41708,20 +44377,15 @@ return jQuery; * @returns {Function} Returns the new restricted function. * @example * - * jQuery('#add').on('click', _.before(5, addContactToList)); + * jQuery(element).on('click', _.before(5, addContactToList)); * // => allows adding up to 4 contacts to the list */ function before(n, func) { var result; if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } + throw new TypeError(FUNC_ERROR_TEXT); } + n = toInteger(n); return function() { if (--n > 0) { result = func.apply(this, arguments); @@ -41741,7 +44405,7 @@ return jQuery; * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for partially applied arguments. * - * **Note:** Unlike native `Function#bind` this method does not set the "length" + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" * property of bound functions. * * @static @@ -41763,62 +44427,21 @@ return jQuery; * bound('!'); * // => 'hi fred!' * - * // using placeholders + * // Bound with placeholders. * var bound = _.bind(greet, object, _, '!'); * bound('hi'); * // => 'hi fred!' */ - var bind = restParam(function(func, thisArg, partials) { + var bind = rest(function(func, thisArg, partials) { var bitmask = BIND_FLAG; if (partials.length) { - var holders = replaceHolders(partials, bind.placeholder); + var holders = replaceHolders(partials, getPlaceholder(bind)); bitmask |= PARTIAL_FLAG; } return createWrapper(func, bitmask, thisArg, partials, holders); }); /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all enumerable function - * properties, own and inherited, of `object` are bound. - * - * **Note:** This method does not set the "length" property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...(string|string[])} [methodNames] The object method names to bind, - * specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { - * console.log('clicked ' + this.label); - * } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs' when the element is clicked - */ - var bindAll = restParam(function(object, methodNames) { - methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); - - var index = -1, - length = methodNames.length; - - while (++index < length) { - var key = methodNames[index]; - object[key] = createWrapper(object[key], BIND_FLAG, object); - } - return object; - }); - - /** * Creates a function that invokes the method at `object[key]` and prepends * any additional `_.bindKey` arguments to those provided to the bound function. * @@ -41833,7 +44456,7 @@ return jQuery; * @static * @memberOf _ * @category Function - * @param {Object} object The object the method belongs to. + * @param {Object} object The object to invoke the method on. * @param {string} key The key of the method. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. @@ -41857,38 +44480,38 @@ return jQuery; * bound('!'); * // => 'hiya fred!' * - * // using placeholders + * // Bound with placeholders. * var bound = _.bindKey(object, 'greet', _, '!'); * bound('hi'); * // => 'hiya fred!' */ - var bindKey = restParam(function(object, key, partials) { + var bindKey = rest(function(object, key, partials) { var bitmask = BIND_FLAG | BIND_KEY_FLAG; if (partials.length) { - var holders = replaceHolders(partials, bindKey.placeholder); + var holders = replaceHolders(partials, getPlaceholder(bindKey)); bitmask |= PARTIAL_FLAG; } return createWrapper(key, bitmask, object, partials, holders); }); /** - * Creates a function that accepts one or more arguments of `func` that when - * called either invokes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` may be specified - * if `func.length` is not sufficient. + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. * * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for provided arguments. * - * **Note:** This method does not set the "length" property of curried functions. + * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Function} Returns the new curried function. * @example * @@ -41907,11 +44530,16 @@ return jQuery; * curried(1, 2, 3); * // => [1, 2, 3] * - * // using placeholders + * // Curried with placeholders. * curried(1)(_, 3)(2); * // => [1, 2, 3] */ - var curry = createCurry(CURRY_FLAG); + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } /** * This method is like `_.curry` except that arguments are applied to `func` @@ -41920,14 +44548,14 @@ return jQuery; * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for provided arguments. * - * **Note:** This method does not set the "length" property of curried functions. + * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Function} Returns the new curried function. * @example * @@ -41946,23 +44574,29 @@ return jQuery; * curried(1, 2, 3); * // => [1, 2, 3] * - * // using placeholders + * // Curried with placeholders. * curried(3)(1, _)(2); * // => [1, 2, 3] */ - var curryRight = createCurry(CURRY_RIGHT_FLAG); + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel - * delayed invocations. Provide an options object to indicate that `func` - * should be invoked on the leading and/or trailing edge of the `wait` timeout. - * Subsequent calls to the debounced function return the result of the last - * `func` invocation. + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide an options object to indicate whether `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent calls + * to the debounced function return the result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the debounced function is + * on the trailing edge of the timeout only if the debounced function is * invoked more than once during the `wait` timeout. * * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) @@ -41977,43 +44611,28 @@ return jQuery; * @param {boolean} [options.leading=false] Specify invoking on the leading * edge of the timeout. * @param {number} [options.maxWait] The maximum time `func` is allowed to be - * delayed before it is invoked. + * delayed before it's invoked. * @param {boolean} [options.trailing=true] Specify invoking on the trailing * edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * - * // avoid costly calculations while the window size is in flux + * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * - * // invoke `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * - * // ensure `batchLog` is invoked once after 1 second of debounced calls + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); - * jQuery(source).on('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * })); - * - * // cancel a debounced call - * var todoChanges = _.debounce(batchLog, 1000); - * Object.observe(models.todo, todoChanges); - * - * Object.observe(models, function(changes) { - * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { - * todoChanges.cancel(); - * } - * }, ['delete']); - * - * // ...at some point `models.todo` is changed - * models.todo.completed = true; + * jQuery(source).on('message', debounced); * - * // ...before 1 second has passed `models.todo` is deleted - * // which cancels the debounced `todoChanges` call - * delete models.todo; + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var args, @@ -42024,19 +44643,17 @@ return jQuery; timeoutId, trailingCall, lastCalled = 0, + leading = false, maxWait = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - wait = wait < 0 ? 0 : (+wait || 0); - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { + wait = toNumber(wait) || 0; + if (isObject(options)) { leading = !!options.leading; - maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); trailing = 'trailing' in options ? !!options.trailing : trailing; } @@ -42048,7 +44665,7 @@ return jQuery; clearTimeout(maxTimeoutId); } lastCalled = 0; - maxTimeoutId = timeoutId = trailingCall = undefined; + args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; } function complete(isCalled, id) { @@ -42074,6 +44691,14 @@ return jQuery; } } + function flush() { + if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { + result = func.apply(thisArg, args); + } + cancel(); + return result; + } + function maxDelayed() { complete(trailing, timeoutId); } @@ -42087,11 +44712,13 @@ return jQuery; if (maxWait === false) { var leadingCall = leading && !timeoutId; } else { - if (!maxTimeoutId && !leading) { + if (!lastCalled && !maxTimeoutId && !leading) { lastCalled = stamp; } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); if (isCalled) { if (maxTimeoutId) { @@ -42120,40 +44747,41 @@ return jQuery; return result; } debounced.cancel = cancel; + debounced.flush = flush; return debounced; } /** * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it is invoked. + * additional arguments are provided to `func` when it's invoked. * * @static * @memberOf _ * @category Function * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke the function with. + * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * * _.defer(function(text) { * console.log(text); * }, 'deferred'); - * // logs 'deferred' after one or more milliseconds + * // => logs 'deferred' after one or more milliseconds */ - var defer = restParam(function(func, args) { + var defer = rest(function(func, args) { return baseDelay(func, 1, args); }); /** * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it is invoked. + * provided to `func` when it's invoked. * * @static * @memberOf _ * @category Function * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke the function with. + * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * @@ -42162,66 +44790,42 @@ return jQuery; * }, 1000, 'later'); * // => logs 'later' after one second */ - var delay = restParam(function(func, wait, args) { - return baseDelay(func, wait, args); + var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); }); /** - * Creates a function that returns the result of invoking the provided - * functions with the `this` binding of the created function, where each - * successive invocation is supplied the return value of the previous. - * - * @static - * @memberOf _ - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flow(_.add, square); - * addSquare(1, 2); - * // => 9 - */ - var flow = createFlow(); - - /** - * This method is like `_.flow` except that it creates a function that - * invokes the provided functions from right to left. + * Creates a function that invokes `func` with arguments reversed. * * @static * @memberOf _ - * @alias backflow, compose * @category Function - * @param {...Function} [funcs] Functions to invoke. + * @param {Function} func The function to flip arguments for. * @returns {Function} Returns the new function. * @example * - * function square(n) { - * return n * n; - * } + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); * - * var addSquare = _.flowRight(square, _.add); - * addSquare(1, 2); - * // => 9 + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] */ - var flowRight = createFlow(true); + function flip(func) { + return createWrapper(func, FLIP_FLAG); + } /** * Creates a function that memoizes the result of `func`. If `resolver` is * provided it determines the cache key for storing the result based on the * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is coerced to a string and used as the - * cache key. The `func` is invoked with the `this` binding of the memoized - * function. + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) - * method interface of `get`, `has`, and `set`. + * method interface of `delete`, `get`, `has`, and `set`. * * @static * @memberOf _ @@ -42231,35 +44835,27 @@ return jQuery; * @returns {Function} Returns the new memoizing function. * @example * - * var upperCase = _.memoize(function(string) { - * return string.toUpperCase(); - * }); + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; * - * upperCase('fred'); - * // => 'FRED' + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] * - * // modifying the result cache - * upperCase.cache.set('fred', 'BARNEY'); - * upperCase('fred'); - * // => 'BARNEY' + * values(other); + * // => [3, 4] * - * // replacing `_.memoize.Cache` - * var object = { 'user': 'fred' }; - * var other = { 'user': 'barney' }; - * var identity = _.memoize(_.identity); + * object.a = 2; + * values(object); + * // => [1, 2] * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'fred' } + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] * + * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'barney' } */ function memoize(func, resolver) { if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { @@ -42282,52 +44878,6 @@ return jQuery; } /** - * Creates a function that runs each argument through a corresponding - * transform function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms] The functions to transform - * arguments, specified as individual functions or arrays of functions. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var modded = _.modArgs(function(x, y) { - * return [x, y]; - * }, square, doubled); - * - * modded(1, 2); - * // => [1, 4] - * - * modded(5, 10); - * // => [25, 20] - */ - var modArgs = restParam(function(func, transforms) { - transforms = baseFlatten(transforms); - if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = transforms.length; - return restParam(function(args) { - var index = nativeMin(args.length, length); - while (index--) { - args[index] = transforms[index](args[index]); - } - return func.apply(this, args); - }); - }); - - /** * Creates a function that negates the result of the predicate `func`. The * `func` predicate is invoked with the `this` binding and arguments of the * created function. @@ -42357,8 +44907,8 @@ return jQuery; /** * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first call. The `func` is invoked - * with the `this` binding and arguments of the created function. + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. * * @static * @memberOf _ @@ -42377,6 +44927,52 @@ return jQuery; } /** + * Creates a function that invokes `func` with arguments transformed by + * corresponding `transforms`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified individually or in arrays. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = rest(function(func, transforms) { + transforms = arrayMap(baseFlatten(transforms, 1), getIteratee()); + + var funcsLength = transforms.length; + return rest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** * Creates a function that invokes `func` with `partial` arguments prepended * to those provided to the new function. This method is like `_.bind` except * it does **not** alter the `this` binding. @@ -42384,7 +44980,7 @@ return jQuery; * The `_.partial.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * - * **Note:** This method does not set the "length" property of partially + * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static @@ -42403,12 +44999,15 @@ return jQuery; * sayHelloTo('fred'); * // => 'hello fred' * - * // using placeholders + * // Partially applied with placeholders. * var greetFred = _.partial(greet, _, 'fred'); * greetFred('hi'); * // => 'hi fred' */ - var partial = createPartial(PARTIAL_FLAG); + var partial = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partial)); + return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders); + }); /** * This method is like `_.partial` except that partially applied arguments @@ -42417,7 +45016,7 @@ return jQuery; * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * - * **Note:** This method does not set the "length" property of partially + * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static @@ -42436,12 +45035,15 @@ return jQuery; * greetFred('hi'); * // => 'hi fred' * - * // using placeholders + * // Partially applied with placeholders. * var sayHelloTo = _.partialRight(greet, 'hello', _); * sayHelloTo('fred'); * // => 'hello fred' */ - var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + var partialRight = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partialRight)); + return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); /** * Creates a function that invokes `func` with arguments arranged according @@ -42454,7 +45056,7 @@ return jQuery; * @category Function * @param {Function} func The function to rearrange arguments for. * @param {...(number|number[])} indexes The arranged argument indexes, - * specified as individual indexes or arrays of indexes. + * specified individually or in arrays. * @returns {Function} Returns the new function. * @example * @@ -42464,22 +45066,16 @@ return jQuery; * * rearged('b', 'c', 'a') * // => ['a', 'b', 'c'] - * - * var map = _.rearg(_.map, [1, 0]); - * map(function(n) { - * return n * 3; - * }, [1, 2, 3]); - * // => [3, 6, 9] */ - var rearg = restParam(function(func, indexes) { - return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + var rearg = rest(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); }); /** * Creates a function that invokes `func` with the `this` binding of the * created function and arguments from `start` and beyond provided as an array. * - * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters). * * @static * @memberOf _ @@ -42489,7 +45085,7 @@ return jQuery; * @returns {Function} Returns the new function. * @example * - * var say = _.restParam(function(what, names) { + * var say = _.rest(function(what, names) { * return what + ' ' + _.initial(names).join(', ') + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); @@ -42497,32 +45093,32 @@ return jQuery; * say('hello', 'fred', 'barney', 'pebbles'); * // => 'hello fred, barney, & pebbles' */ - function restParam(func, start) { + function rest(func, start) { if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), - rest = Array(length); + array = Array(length); while (++index < length) { - rest[index] = args[start + index]; + array[index] = args[start + index]; } switch (start) { - case 0: return func.call(this, rest); - case 1: return func.call(this, args[0], rest); - case 2: return func.call(this, args[0], args[1], rest); + case 0: return func.call(this, array); + case 1: return func.call(this, args[0], array); + case 2: return func.call(this, args[0], args[1], array); } var otherArgs = Array(start + 1); index = -1; while (++index < start) { otherArgs[index] = args[index]; } - otherArgs[start] = rest; - return func.apply(this, otherArgs); + otherArgs[start] = array; + return apply(func, this, otherArgs); }; } @@ -42530,12 +45126,13 @@ return jQuery; * Creates a function that invokes `func` with the `this` binding of the created * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). * - * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator). * * @static * @memberOf _ * @category Function * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. * @returns {Function} Returns the new function. * @example * @@ -42546,7 +45143,6 @@ return jQuery; * say(['fred', 'hello']); * // => 'fred says hello' * - * // with a Promise * var numbers = Promise.all([ * Promise.resolve(40), * Promise.resolve(36) @@ -42557,25 +45153,34 @@ return jQuery; * })); * // => a Promise of 76 */ - function spread(func) { + function spread(func, start) { if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - return function(array) { - return func.apply(this, array); - }; + start = start === undefined ? 0 : nativeMax(toInteger(start), 0); + return rest(function(args) { + var array = args[start], + otherArgs = args.slice(0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); } /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed invocations. Provide an options object to indicate - * that `func` should be invoked on the leading and/or trailing edge of the - * `wait` timeout. Subsequent calls to the throttled function return the - * result of the last `func` call. + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide an options object to indicate whether + * `func` should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the throttled function is + * on the trailing edge of the timeout only if the throttled function is * invoked more than once during the `wait` timeout. * * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) @@ -42594,15 +45199,14 @@ return jQuery; * @returns {Function} Returns the new throttled function. * @example * - * // avoid excessively updating the position while scrolling + * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * - * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); * - * // cancel a trailing throttled call + * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { @@ -42612,13 +45216,33 @@ return jQuery; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - if (options === false) { - leading = false; - } else if (isObject(options)) { + if (isObject(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } - return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); } /** @@ -42631,7 +45255,7 @@ return jQuery; * @memberOf _ * @category Function * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. + * @param {Function} [wrapper=identity] The wrapper function. * @returns {Function} Returns the new function. * @example * @@ -42644,125 +45268,194 @@ return jQuery; */ function wrap(value, wrapper) { wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); + return partial(wrapper, value); } /*------------------------------------------------------------------------*/ /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, - * otherwise they are assigned by reference. If `customizer` is provided it is - * invoked to produce the cloned values. If `customizer` returns `undefined` - * cloning is handled by the method instead. The `customizer` is bound to - * `thisArg` and invoked with two argument; (value [, index|key, object]). + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. * * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. * * @static * @memberOf _ * @category Lang * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {*} Returns the cloned value. * @example * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; + * var objects = [{ 'a': 1 }, { 'b': 2 }]; * - * var shallow = _.clone(users); - * shallow[0] === users[0]; + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); * // => true + */ + function clone(value) { + return baseClone(value); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). * - * var deep = _.clone(users, true); - * deep[0] === users[0]; - * // => false + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @example * - * // using a customizer callback - * var el = _.clone(document.body, function(value) { + * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(false); * } - * }); + * } + * + * var el = _.cloneWith(document.body, customizer); * - * el === document.body + * console.log(el === document.body); * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); * // => 0 */ - function clone(value, isDeep, customizer, thisArg) { - if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { - isDeep = false; - } - else if (typeof isDeep == 'function') { - thisArg = customizer; - customizer = isDeep; - isDeep = false; - } - return typeof customizer == 'function' - ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) - : baseClone(value, isDeep); + function cloneWith(value, customizer) { + return baseClone(value, false, customizer); } /** - * Creates a deep clone of `value`. If `customizer` is provided it is invoked - * to produce the cloned values. If `customizer` returns `undefined` cloning - * is handled by the method instead. The `customizer` is bound to `thisArg` - * and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. + * This method is like `_.clone` except that it recursively clones `value`. * * @static * @memberOf _ * @category Lang - * @param {*} value The value to deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. + * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. * @example * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; + * var objects = [{ 'a': 1 }, { 'b': 2 }]; * - * var deep = _.cloneDeep(users); - * deep[0] === users[0]; + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); * // => false + */ + function cloneDeep(value) { + return baseClone(value, true); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. * - * // using a customizer callback - * var el = _.cloneDeep(document.body, function(value) { + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @example + * + * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(true); * } - * }); + * } + * + * var el = _.cloneDeepWith(document.body, customizer); * - * el === document.body + * console.log(el === document.body); * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); * // => 20 */ - function cloneDeep(value, customizer, thisArg) { - return typeof customizer == 'function' - ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) - : baseClone(value, true); + function cloneDeepWith(value, customizer) { + return baseClone(value, true, customizer); + } + + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); } /** @@ -42814,7 +45507,7 @@ return jQuery; } /** - * Checks if `value` is classified as an `arguments` object. + * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ @@ -42830,8 +45523,9 @@ return jQuery; * // => false */ function isArguments(value) { - return isObjectLike(value) && isArrayLike(value) && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); } /** @@ -42839,6 +45533,7 @@ return jQuery; * * @static * @memberOf _ + * @type {Function} * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -42847,12 +45542,92 @@ return jQuery; * _.isArray([1, 2, 3]); * // => true * - * _.isArray(function() { return arguments; }()); + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); * // => false */ - var isArray = nativeIsArray || function(value) { - return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; - }; + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + function isArrayBuffer(value) { + return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && + !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value)); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } /** * Checks if `value` is classified as a boolean primitive or object. @@ -42871,10 +45646,31 @@ return jQuery; * // => false */ function isBoolean(value) { - return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); } /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = !Buffer ? constant(false) : function(value) { + return value instanceof Buffer; + }; + + /** * Checks if `value` is classified as a `Date` object. * * @static @@ -42891,11 +45687,11 @@ return jQuery; * // => false */ function isDate(value) { - return isObjectLike(value) && objToString.call(value) == dateTag; + return isObjectLike(value) && objectToString.call(value) == dateTag; } /** - * Checks if `value` is a DOM element. + * Checks if `value` is likely a DOM element. * * @static * @memberOf _ @@ -42915,7 +45711,7 @@ return jQuery; } /** - * Checks if `value` is empty. A value is considered empty unless it is an + * Checks if `value` is empty. A value is considered empty unless it's an * `arguments` object, array, string, or jQuery-like collection with a length * greater than `0` or an object with own enumerable properties. * @@ -42942,64 +45738,85 @@ return jQuery; * // => false */ function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || - (isObjectLike(value) && isFunction(value.splice)))) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { return !value.length; } - return !keys(value).length; + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; } /** * Performs a deep comparison between two values to determine if they are - * equivalent. If `customizer` is provided it is invoked to compare values. - * If `customizer` returns `undefined` comparisons are handled by the method - * instead. The `customizer` is bound to `thisArg` and invoked with three - * arguments: (value, other [, index|key]). + * equivalent. * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. Functions and DOM nodes - * are **not** supported. Provide a customizer function to extend support - * for comparing other values. + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. * * @static * @memberOf _ - * @alias eq * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'user': 'fred' }; * var other = { 'user': 'fred' }; * - * object == other; - * // => false - * * _.isEqual(object, other); * // => true * - * // using a customizer callback - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example * - * _.isEqual(array, other, function(value, other) { - * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { * return true; * } - * }); + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); * // => true */ - function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; } /** @@ -43020,13 +45837,17 @@ return jQuery; * // => false */ function isError(value) { - return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + if (!isObjectLike(value)) { + return false; + } + return (objectToString.call(value) == errorTag) || + (typeof value.message == 'string' && typeof value.name == 'string'); } /** * Checks if `value` is a finite primitive number. * - * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). * * @static * @memberOf _ @@ -43035,17 +45856,14 @@ return jQuery; * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. * @example * - * _.isFinite(10); + * _.isFinite(3); * // => true * - * _.isFinite('10'); - * // => false - * - * _.isFinite(true); - * // => false + * _.isFinite(Number.MAX_VALUE); + * // => true * - * _.isFinite(Object(10)); - * // => false + * _.isFinite(3.14); + * // => true * * _.isFinite(Infinity); * // => false @@ -43072,9 +45890,67 @@ return jQuery; */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return isObject(value) && objToString.call(value) == funcTag; + // in Safari 8 which returns 'object' for typed array constructors, and + // PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** @@ -43094,35 +45970,76 @@ return jQuery; * _.isObject([1, 2, 3]); * // => true * - * _.isObject(1); + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); * // => false */ function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. If `customizer` is provided - * it is invoked to compare values. If `customizer` returns `undefined` - * comparisons are handled by the method instead. The `customizer` is bound - * to `thisArg` and invoked with three arguments: (value, other, index|key). + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + function isMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. * - * **Note:** This method supports comparing properties of arrays, booleans, - * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions - * and DOM nodes are **not** supported. Provide a customizer function to extend - * support for comparing other values. + * **Note:** This method supports comparing the same values as `_.isEqual`. * * @static * @memberOf _ * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * @@ -43133,19 +46050,45 @@ return jQuery; * * _.isMatch(object, { 'age': 36 }); * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } * - * // using a customizer callback * var object = { 'greeting': 'hello' }; * var source = { 'greeting': 'hi' }; * - * _.isMatch(object, source, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; - * }); + * _.isMatchWith(object, source, customizer); * // => true */ - function isMatch(object, source, customizer, thisArg) { - customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; - return baseIsMatch(object, getMatchData(source), customizer); + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); } /** @@ -43175,7 +46118,7 @@ return jQuery; */ function isNaN(value) { // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. return isNumber(value) && value != +value; } @@ -43200,9 +46143,10 @@ return jQuery; return false; } if (isFunction(value)) { - return reIsNative.test(fnToString.call(value)); + return reIsNative.test(funcToString.call(value)); } - return isObjectLike(value) && reIsHostCtor.test(value); + return isObjectLike(value) && + (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); } /** @@ -43226,6 +46170,29 @@ return jQuery; } /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** * Checks if `value` is classified as a `Number` primitive or object. * * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified @@ -43238,26 +46205,27 @@ return jQuery; * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.isNumber(8.4); + * _.isNumber(3); * // => true * - * _.isNumber(NaN); + * _.isNumber(Number.MIN_VALUE); * // => true * - * _.isNumber('8.4'); + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); * // => false */ function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); } /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * - * **Note:** This method assumes objects created by the `Object` constructor - * have no inherited enumerable properties. - * * @static * @memberOf _ * @category Lang @@ -43282,24 +46250,17 @@ return jQuery; * // => true */ function isPlainObject(value) { - var Ctor; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || - (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { return false; } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); + var proto = getPrototypeOf(value); + if (proto === null) { + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); } /** @@ -43319,7 +46280,56 @@ return jQuery; * // => false */ function isRegExp(value) { - return isObject(value) && objToString.call(value) == regexpTag; + return isObject(value) && objectToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + function isSet(value) { + return isObjectLike(value) && getTag(value) == setTag; } /** @@ -43339,7 +46349,29 @@ return jQuery; * // => false */ function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); } /** @@ -43359,7 +46391,8 @@ return jQuery; * // => false */ function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; } /** @@ -43383,6 +46416,46 @@ return jQuery; } /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && objectToString.call(value) == weakSetTag; + } + + /** * Checks if `value` is less than `other`. * * @static @@ -43440,20 +46513,135 @@ return jQuery; * @returns {Array} Returns the converted array. * @example * - * (function() { - * return _.toArray(arguments).slice(1); - * }(1, 2, 3)); - * // => [2, 3] + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] */ function toArray(value) { - var length = value ? getLength(value) : 0; - if (!isLength(length)) { - return values(value); - } - if (!length) { + if (!value) { return []; } - return arrayCopy(value); + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (iteratorSymbol && value[iteratorSymbol]) { + return iteratorToArray(value[iteratorSymbol]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + function toInteger(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + var remainder = value % 1; + return value === value ? (remainder ? value - remainder : value) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + function toNumber(value) { + if (isObject(value)) { + var other = isFunction(value.valueOf) ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); } /** @@ -43480,70 +46668,112 @@ return jQuery; * // => { 'a': 1, 'b': 2, 'c': 3 } */ function toPlainObject(value) { - return baseCopy(value, keysIn(value)); + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3'); + * // => 3 + */ + function toSafeInteger(value) { + return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (value == null) { + return ''; + } + if (isSymbol(value)) { + return Symbol ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } /*------------------------------------------------------------------------*/ /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it is invoked to produce the merged values of the destination and - * source properties. If `customizer` returns `undefined` merging is handled - * by the method instead. The `customizer` is bound to `thisArg` and invoked - * with five arguments: (objectValue, sourceValue, key, object, source). + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). * * @static * @memberOf _ * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {Object} Returns `object`. * @example * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * function Foo() { + * this.c = 3; + * } * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; + * function Bar() { + * this.e = 5; + * } * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; * - * _.merge(object, other, function(a, b) { - * if (_.isArray(a)) { - * return a.concat(b); - * } - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } */ - var merge = createAssigner(baseMerge); + var assign = createAssigner(function(object, source) { + copyObject(source, keys(source), object); + }); /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources overwrite property assignments of previous sources. - * If `customizer` is provided it is invoked to produce the assigned values. - * The `customizer` is bound to `thisArg` and invoked with five arguments: - * (objectValue, sourceValue, key, object, source). + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. * - * **Note:** This method mutates `object` and is based on - * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * **Note:** This method mutates `object`. * * @static * @memberOf _ @@ -43551,39 +46781,121 @@ return jQuery; * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {Object} Returns `object`. * @example * - * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); - * // => { 'user': 'fred', 'age': 40 } + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } * - * // using a customizer callback - * var defaults = _.partialRight(_.assign, function(value, other) { - * return _.isUndefined(value) ? other : value; - * }); + * var defaults = _.partialRight(_.assignInWith, customizer); * - * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + * + * _.at(['a', 'b', 'c'], 0, 2); + * // => ['a', 'c'] */ - var assign = createAssigner(function(object, source, customizer) { - return customizer - ? assignWith(object, source, customizer) - : baseAssign(object, source); + var at = rest(function(object, paths) { + return baseAt(object, baseFlatten(paths, 1)); }); /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. * * @static * @memberOf _ * @category Object * @param {Object} prototype The object to inherit from. * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Object} Returns the new object. * @example * @@ -43607,18 +46919,16 @@ return jQuery; * circle instanceof Shape; * // => true */ - function create(prototype, properties, guard) { + function create(prototype, properties) { var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = undefined; - } return properties ? baseAssign(result, properties) : result; } /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional values of the same property are ignored. + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. * * **Note:** This method mutates `object`. * @@ -43633,7 +46943,10 @@ return jQuery; * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); * // => { 'user': 'barney', 'age': 36 } */ - var defaults = createDefaults(assign, assignDefaults); + var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return apply(assignInWith, undefined, args); + }); /** * This method is like `_.defaults` except that it recursively assigns @@ -43653,30 +46966,20 @@ return jQuery; * // => { 'user': { 'name': 'barney', 'age': 36 } } * */ - var defaultsDeep = createDefaults(merge, mergeDefaults); + var defaultsDeep = rest(function(args) { + args.push(undefined, mergeDefaults); + return apply(mergeWith, undefined, args); + }); /** * This method is like `_.find` except that it returns the key of the first * element `predicate` returns truthy for instead of the element itself. * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * * @static * @memberOf _ * @category Object * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * @@ -43686,47 +46989,34 @@ return jQuery; * 'pebbles': { 'age': 1, 'active': true } * }; * - * _.findKey(users, function(chr) { - * return chr.age < 40; - * }); + * _.findKey(users, function(o) { return o.age < 40; }); * // => 'barney' (iteration order is not guaranteed) * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.findKey(users, { 'age': 1, 'active': true }); * // => 'pebbles' * - * // using the `_.matchesProperty` callback shorthand - * _.findKey(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); * // => 'fred' * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.findKey(users, 'active'); * // => 'barney' */ - var findKey = createFindKey(baseForOwn); + function findKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwn, true); + } /** * This method is like `_.findKey` except that it iterates over elements of * a collection in the opposite order. * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * * @static * @memberOf _ * @category Object * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * @@ -43736,37 +47026,36 @@ return jQuery; * 'pebbles': { 'age': 1, 'active': true } * }; * - * _.findLastKey(users, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles` assuming `_.findKey` returns `barney` + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' * - * // using the `_.matches` callback shorthand + * // The `_.matches` iteratee shorthand. * _.findLastKey(users, { 'age': 36, 'active': true }); * // => 'barney' * - * // using the `_.matchesProperty` callback shorthand - * _.findLastKey(users, 'active', false); + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); * // => 'fred' * - * // using the `_.property` callback shorthand + * // The `_.property` iteratee shorthand. * _.findLastKey(users, 'active'); * // => 'pebbles' */ - var findLastKey = createFindKey(baseForOwnRight); + function findLastKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); + } /** * Iterates over own and inherited enumerable properties of an object invoking - * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. + * `iteratee` for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by explicitly + * returning `false`. * * @static * @memberOf _ * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns `object`. * @example * @@ -43780,9 +47069,13 @@ return jQuery; * _.forIn(new Foo, function(value, key) { * console.log(key); * }); - * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ - var forIn = createForIn(baseFor); + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); + } /** * This method is like `_.forIn` except that it iterates over properties of @@ -43793,7 +47086,6 @@ return jQuery; * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns `object`. * @example * @@ -43807,22 +47099,25 @@ return jQuery; * _.forInRight(new Foo, function(value, key) { * console.log(key); * }); - * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ - var forInRight = createForIn(baseForRight); + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); + } /** * Iterates over own enumerable properties of an object invoking `iteratee` - * for each property. The `iteratee` is bound to `thisArg` and invoked with - * three arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. + * for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by + * explicitly returning `false`. * * @static * @memberOf _ * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns `object`. * @example * @@ -43836,9 +47131,11 @@ return jQuery; * _.forOwn(new Foo, function(value, key) { * console.log(key); * }); - * // => logs 'a' and 'b' (iteration order is not guaranteed) + * // => logs 'a' then 'b' (iteration order is not guaranteed) */ - var forOwn = createForOwn(baseForOwn); + function forOwn(object, iteratee) { + return object && baseForOwn(object, baseCastFunction(iteratee)); + } /** * This method is like `_.forOwn` except that it iterates over properties of @@ -43849,7 +47146,6 @@ return jQuery; * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns `object`. * @example * @@ -43863,31 +47159,64 @@ return jQuery; * _.forOwnRight(new Foo, function(value, key) { * console.log(key); * }); - * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' */ - var forOwnRight = createForOwn(baseForOwnRight); + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, baseCastFunction(iteratee)); + } /** - * Creates an array of function property names from all enumerable properties, - * own and inherited, of `object`. + * Creates an array of function property names from own enumerable properties + * of `object`. * * @static * @memberOf _ - * @alias methods * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of property names. * @example * - * _.functions(_); - * // => ['after', 'ary', 'assign', ...] + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] */ function functions(object) { - return baseFunctions(object, keysIn(object)); + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); } /** - * Gets the property value at `path` of `object`. If the resolved value is + * Gets the value at `path` of `object`. If the resolved value is * `undefined` the `defaultValue` is used in its place. * * @static @@ -43911,22 +47240,23 @@ return jQuery; * // => 'default' */ function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + var result = object == null ? undefined : baseGet(object, path); return result === undefined ? defaultValue : result; } /** - * Checks if `path` is a direct property. + * Checks if `path` is a direct property of `object`. * * @static * @memberOf _ * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); * * _.has(object, 'a'); * // => true @@ -43936,36 +47266,52 @@ return jQuery; * * _.has(object, ['a', 'b', 'c']); * // => true + * + * _.has(other, 'a'); + * // => false */ function has(object, path) { - if (object == null) { - return false; - } - var result = hasOwnProperty.call(object, path); - if (!result && !isKey(path)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - path = last(path); - result = hasOwnProperty.call(object, path); - } - return result || (isLength(object.length) && isIndex(path, object.length) && - (isArray(object) || isArguments(object))); + return hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return hasPath(object, path, baseHasIn); } /** * Creates an object composed of the inverted keys and values of `object`. * If `object` contains duplicate values, subsequent values overwrite property - * assignments of previous values unless `multiValue` is `true`. + * assignments of previous values. * * @static * @memberOf _ * @category Object * @param {Object} object The object to invert. - * @param {boolean} [multiValue] Allow multiple values per key. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Object} Returns the new inverted object. * @example * @@ -43973,37 +47319,62 @@ return jQuery; * * _.invert(object); * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` through `iteratee`. + * The corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). * - * // with `multiValue` - * _.invert(object, true); + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } */ - function invert(object, multiValue, guard) { - if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = undefined; + var invertBy = createInverter(function(result, value, key) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; } - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; + }, getIteratee); - if (multiValue) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - } - else { - result[value] = key; - } - } - return result; - } + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = rest(baseInvoke); /** * Creates an array of the own enumerable property names of `object`. @@ -44032,14 +47403,25 @@ return jQuery; * _.keys('hi'); * // => ['0', '1'] */ - var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? undefined : object.constructor; - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isArrayLike(object))) { - return shimKeys(object); + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); } - return isObject(object) ? nativeKeys(object) : []; - }; + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } /** * Creates an array of the own and inherited enumerable property names of `object`. @@ -44064,27 +47446,18 @@ return jQuery; * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || isArguments(object)) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { result.push(key); } @@ -44095,15 +47468,14 @@ return jQuery; /** * The opposite of `_.mapValues`; this method creates an object with the * same values as `object` and keys generated by running each own enumerable - * property of `object` through `iteratee`. + * property of `object` through `iteratee`. The iteratee is invoked with + * three arguments: (value, key, object). * * @static * @memberOf _ * @category Object * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @example * @@ -44112,50 +47484,124 @@ return jQuery; * }); * // => { 'a1': 1, 'b2': 2 } */ - var mapKeys = createObjectMapper(true); + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[iteratee(value, key, object)] = value; + }); + return result; + } /** * Creates an object with the same keys as `object` and values generated by * running each own enumerable property of `object` through `iteratee`. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, key, object). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * iteratee is invoked with three arguments: (value, key, object). * * @static * @memberOf _ * @category Object * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @example * - * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { - * return n * 3; - * }); - * // => { 'a': 3, 'b': 6 } - * * var users = { * 'fred': { 'user': 'fred', 'age': 40 }, * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * - * // using the `_.property` callback shorthand + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ - var mapValues = createObjectMapper(); + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; + } + + /** + * Recursively merges own and inherited enumerable properties of source objects + * into the destination object. Source properties that resolve to `undefined` + * are skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined` merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.mergeWith(object, other, customizer); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); /** * The opposite of `_.pick`; this method creates an object composed of the @@ -44165,102 +47611,95 @@ return jQuery; * @memberOf _ * @category Object * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to omit, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {...(string|string[])} [props] The property names to omit, specified + * individually or in arrays. * @returns {Object} Returns the new object. * @example * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.omit(object, 'age'); - * // => { 'user': 'fred' } + * var object = { 'a': 1, 'b': '2', 'c': 3 }; * - * _.omit(object, _.isNumber); - * // => { 'user': 'fred' } + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } */ - var omit = restParam(function(object, props) { + var omit = rest(function(object, props) { if (object == null) { return {}; } - if (typeof props[0] != 'function') { - var props = arrayMap(baseFlatten(props), String); - return pickByArray(object, baseDifference(keysIn(object), props)); - } - var predicate = bindCallback(props[0], props[1], 3); - return pickByCallback(object, function(value, key, object) { - return !predicate(value, key, object); - }); + props = arrayMap(baseFlatten(props, 1), String); + return basePick(object, baseDifference(keysIn(object), props)); }); /** - * Creates a two dimensional array of the key-value pairs for `object`, - * e.g. `[[key1, value1], [key2, value2]]`. + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable properties of `object` that `predicate` + * doesn't return truthy for. The predicate is invoked with two arguments: + * (value, key). * * @static * @memberOf _ * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the new array of key-value pairs. + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. * @example * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } */ - function pairs(object) { - object = toObject(object); - - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; + function omitBy(object, predicate) { + predicate = getIteratee(predicate); + return basePickBy(object, function(value, key) { + return !predicate(value, key); + }); } /** - * Creates an object composed of the picked `object` properties. Property - * names may be specified as individual arguments or as arrays of property - * names. If `predicate` is provided it is invoked for each property of `object` - * picking the properties `predicate` returns truthy for. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, key, object). + * Creates an object composed of the picked `object` properties. * * @static * @memberOf _ * @category Object * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. + * @param {...(string|string[])} [props] The property names to pick, specified + * individually or in arrays. * @returns {Object} Returns the new object. * @example * - * var object = { 'user': 'fred', 'age': 40 }; + * var object = { 'a': 1, 'b': '2', 'c': 3 }; * - * _.pick(object, 'user'); - * // => { 'user': 'fred' } - * - * _.pick(object, _.isString); - * // => { 'user': 'fred' } + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } */ - var pick = restParam(function(object, props) { - if (object == null) { - return {}; - } - return typeof props[0] == 'function' - ? pickByCallback(object, bindCallback(props[0], props[1], 3)) - : pickByArray(object, baseFlatten(props)); + var pick = rest(function(object, props) { + return object == null ? {} : basePick(object, baseFlatten(props, 1)); }); /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + return object == null ? {} : basePickBy(object, getIteratee(predicate)); + } + + /** * This method is like `_.get` except that if the resolved value is a function - * it is invoked with the `this` binding of its parent object and its result + * it's invoked with the `this` binding of its parent object and its result * is returned. * * @static @@ -44280,33 +47719,38 @@ return jQuery; * _.result(object, 'a[0].b.c2'); * // => 4 * - * _.result(object, 'a.b.c', 'default'); + * _.result(object, 'a[0].b.c3', 'default'); * // => 'default' * - * _.result(object, 'a.b.c', _.constant('default')); + * _.result(object, 'a[0].b.c3', _.constant('default')); * // => 'default' */ function result(object, path, defaultValue) { - var result = object == null ? undefined : object[path]; + if (!isKey(path, object)) { + path = baseCastPath(path); + var result = get(object, path); + object = parent(object, path); + } else { + result = object == null ? undefined : object[path]; + } if (result === undefined) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - result = object == null ? undefined : object[last(path)]; - } - result = result === undefined ? defaultValue : result; + result = defaultValue; } return isFunction(result) ? result.call(object) : result; } /** - * Sets the property value of `path` on `object`. If a portion of `path` - * does not exist it is created. + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. * * @static * @memberOf _ * @category Object - * @param {Object} object The object to augment. + * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @returns {Object} Returns `object`. @@ -44323,38 +47767,92 @@ return jQuery; * // => 5 */ function set(object, path, value) { - if (object == null) { - return object; - } - var pathKey = (path + ''); - path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + return object == null ? object : baseSet(object, path, value); + } - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object); + * // => { '0': { '1': { '2': 3 }, 'length': 2 } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } - while (nested != null && ++index < length) { - var key = path[index]; - if (isObject(nested)) { - if (index == lastIndex) { - nested[key] = value; - } else if (nested[key] == null) { - nested[key] = isIndex(path[index + 1]) ? [] : {}; - } - } - nested = nested[key]; - } - return object; + /** + * Creates an array of own enumerable key-value pairs for `object` which + * can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + function toPairs(object) { + return baseToPairs(object, keys(object)); + } + + /** + * Creates an array of own and inherited enumerable key-value pairs for + * `object` which can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) + */ + function toPairsIn(object) { + return baseToPairs(object, keysIn(object)); } /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own enumerable * properties through `iteratee`, with each invocation potentially mutating - * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked - * with four arguments: (accumulator, value, key, object). Iteratee functions - * may exit iteration early by explicitly returning `false`. + * the `accumulator` object. The iteratee is invoked with four arguments: + * (accumulator, value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. * * @static * @memberOf _ @@ -44362,24 +47860,23 @@ return jQuery; * @param {Array|Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {*} Returns the accumulated value. * @example * * _.transform([2, 3, 4], function(result, n) { * result.push(n *= n); * return n % 2 == 0; - * }); + * }, []); * // => [4, 9] * - * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { - * result[key] = n * 3; - * }); - * // => { 'a': 3, 'b': 6 } + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } */ - function transform(object, iteratee, accumulator, thisArg) { + function transform(object, iteratee, accumulator) { var isArr = isArray(object) || isTypedArray(object); - iteratee = getCallback(iteratee, thisArg, 4); + iteratee = getIteratee(iteratee, 4); if (accumulator == null) { if (isArr || isObject(object)) { @@ -44387,7 +47884,7 @@ return jQuery; if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); + accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {}; } } else { accumulator = {}; @@ -44400,6 +47897,36 @@ return jQuery; } /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** * Creates an array of the own enumerable property values of `object`. * * **Note:** Non-object values are coerced to objects. @@ -44425,12 +47952,11 @@ return jQuery; * // => ['h', 'i'] */ function values(object) { - return baseValues(object, keys(object)); + return object ? baseValues(object, keys(object)) : []; } /** - * Creates an array of the own and inherited enumerable property values - * of `object`. + * Creates an array of the own and inherited enumerable property values of `object`. * * **Note:** Non-object values are coerced to objects. * @@ -44452,22 +47978,58 @@ return jQuery; * // => [1, 2, 3] (iteration order is not guaranteed) */ function valuesIn(object) { - return baseValues(object, keysIn(object)); + return object == null ? [] : baseValues(object, keysIn(object)); } /*------------------------------------------------------------------------*/ /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** * Checks if `n` is between `start` and up to but not including, `end`. If - * `end` is not specified it is set to `start` with `start` then set to `0`. + * `end` is not specified it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. * * @static * @memberOf _ * @category Number - * @param {number} n The number to check. + * @param {number} number The number to check. * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. * @example * * _.inRange(3, 2, 4); @@ -44487,29 +48049,36 @@ return jQuery; * * _.inRange(5.2, 4); * // => false + * + * _.inRange(-3, -2, -6); + * // => true */ - function inRange(value, start, end) { - start = +start || 0; + function inRange(number, start, end) { + start = toNumber(start) || 0; if (end === undefined) { end = start; start = 0; } else { - end = +end || 0; + end = toNumber(end) || 0; } - return value >= nativeMin(start, end) && value < nativeMax(start, end); + number = toNumber(number); + return baseInRange(number, start, end); } /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number is returned. - * If `floating` is `true`, or either `min` or `max` are floats, a floating-point - * number is returned instead of an integer. + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are floats, + * a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. * * @static * @memberOf _ * @category Number - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. * @param {boolean} [floating] Specify returning a floating-point number. * @returns {number} Returns the random number. * @example @@ -44526,39 +48095,43 @@ return jQuery; * _.random(1.2, 5.2); * // => a floating-point number between 1.2 and 5.2 */ - function random(min, max, floating) { - if (floating && isIterateeCall(min, max, floating)) { - max = floating = undefined; + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; } - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (noMax && typeof min == 'boolean') { - floating = min; - min = 1; + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; } - else if (typeof max == 'boolean') { - floating = max; - noMax = true; + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; } } - if (noMin && noMax) { - max = 1; - noMax = false; + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; + else { + lower = toNumber(lower) || 0; + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toNumber(upper) || 0; + } } - if (floating || min % 1 || max % 1) { + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); } - return baseRandom(min, max); + return baseRandom(lower, upper); } /*------------------------------------------------------------------------*/ @@ -44584,11 +48157,12 @@ return jQuery; */ var camelCase = createCompounder(function(result, word, index) { word = word.toLowerCase(); - return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + return result + (index ? capitalize(word) : word); }); /** - * Capitalizes the first character of `string`. + * Converts the first character of `string` to upper case and the remaining + * to lower case. * * @static * @memberOf _ @@ -44597,12 +48171,11 @@ return jQuery; * @returns {string} Returns the capitalized string. * @example * - * _.capitalize('fred'); + * _.capitalize('FRED'); * // => 'Fred' */ function capitalize(string) { - string = baseToString(string); - return string && (string.charAt(0).toUpperCase() + string.slice(1)); + return upperFirst(toString(string).toLowerCase()); } /** @@ -44620,7 +48193,7 @@ return jQuery; * // => 'deja vu' */ function deburr(string) { - string = baseToString(string); + string = toString(string); return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); } @@ -44646,24 +48219,24 @@ return jQuery; * // => true */ function endsWith(string, target, position) { - string = baseToString(string); - target = (target + ''); + string = toString(string); + target = typeof target == 'string' ? target : (target + ''); var length = string.length; position = position === undefined ? length - : nativeMin(position < 0 ? 0 : (+position || 0), length); + : baseClamp(toInteger(position), 0, length); position -= target.length; return position >= 0 && string.indexOf(target, position) == position; } /** - * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to * their corresponding HTML entities. * - * **Note:** No other characters are escaped. To escape additional characters - * use a third-party library like [_he_](https://mths.be/he). + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). * * Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't need escaping in HTML and have no special meaning @@ -44671,8 +48244,8 @@ return jQuery; * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) * (under "semi-related fun fact") for more details. * - * Backticks are escaped because in Internet Explorer < 9, they can break out - * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) * for more details. @@ -44691,16 +48264,15 @@ return jQuery; * // => 'fred, barney, & pebbles' */ function escape(string) { - // Reset `lastIndex` because in IE < 9 `String#replace` does not. - string = baseToString(string); + string = toString(string); return (string && reHasUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } /** - * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", - * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. * * @static * @memberOf _ @@ -44710,13 +48282,13 @@ return jQuery; * @example * * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + * // => '\[lodash\]\(https://lodash\.com/\)' */ function escapeRegExp(string) { - string = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, escapeRegExpChar) - : (string || '(?:)'); + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; } /** @@ -44743,6 +48315,65 @@ return jQuery; }); /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Converts the first character of `string` to upper case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.upperFirst('fred'); + * // => 'Fred' + * + * _.upperFirst('FRED'); + * // => 'FRED' + */ + var upperFirst = createCaseFirst('toUpperCase'); + + /** * Pads `string` on the left and right sides if it's shorter than `length`. * Padding characters are truncated if they can't be evenly divided by `length`. * @@ -44765,23 +48396,22 @@ return jQuery; * // => 'abc' */ function pad(string, length, chars) { - string = baseToString(string); - length = +length; + string = toString(string); + length = toInteger(length); - var strLength = string.length; - if (strLength >= length || !nativeIsFinite(length)) { + var strLength = stringSize(string); + if (!length || strLength >= length) { return string; } var mid = (length - strLength) / 2, leftLength = nativeFloor(mid), rightLength = nativeCeil(mid); - chars = createPadding('', rightLength, chars); - return chars.slice(0, leftLength) + string + chars; + return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars); } /** - * Pads `string` on the left side if it's shorter than `length`. Padding + * Pads `string` on the right side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static @@ -44793,19 +48423,22 @@ return jQuery; * @returns {string} Returns the padded string. * @example * - * _.padLeft('abc', 6); - * // => ' abc' + * _.padEnd('abc', 6); + * // => 'abc ' * - * _.padLeft('abc', 6, '_-'); - * // => '_-_abc' + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' * - * _.padLeft('abc', 3); + * _.padEnd('abc', 3); * // => 'abc' */ - var padLeft = createPadDir(); + function padEnd(string, length, chars) { + string = toString(string); + return string + createPadding(string, length, chars); + } /** - * Pads `string` on the right side if it's shorter than `length`. Padding + * Pads `string` on the left side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static @@ -44817,31 +48450,34 @@ return jQuery; * @returns {string} Returns the padded string. * @example * - * _.padRight('abc', 6); - * // => 'abc ' + * _.padStart('abc', 6); + * // => ' abc' * - * _.padRight('abc', 6, '_-'); - * // => 'abc_-_' + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' * - * _.padRight('abc', 3); + * _.padStart('abc', 3); * // => 'abc' */ - var padRight = createPadDir(true); + function padStart(string, length, chars) { + string = toString(string); + return createPadding(string, length, chars) + string; + } /** * Converts `string` to an integer of the specified radix. If `radix` is * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, * in which case a `radix` of `16` is used. * - * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2) * of `parseInt`. * * @static * @memberOf _ * @category String * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {number} Returns the converted integer. * @example * @@ -44852,15 +48488,14 @@ return jQuery; * // => [6, 8, 10] */ function parseInt(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. // Chrome fails to trim leading <BOM> whitespace characters. // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + if (guard || radix == null) { radix = 0; } else if (radix) { radix = +radix; } - string = trim(string); + string = toString(string).replace(reTrim, ''); return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); } @@ -44885,10 +48520,11 @@ return jQuery; * // => '' */ function repeat(string, n) { + string = toString(string); + n = toInteger(n); + var result = ''; - string = baseToString(string); - n = +n; - if (n < 1 || !string || !nativeIsFinite(n)) { + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { return result; } // Leverage the exponentiation by squaring algorithm for a faster repeat. @@ -44905,6 +48541,30 @@ return jQuery; } /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). * * @static @@ -44928,6 +48588,27 @@ return jQuery; }); /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the new array of string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + return toString(string).split(separator, limit); + } + + /** * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static @@ -44947,7 +48628,7 @@ return jQuery; * // => 'Foo Bar' */ var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + return result + (index ? ' ' : '') + capitalize(word); }); /** @@ -44972,11 +48653,8 @@ return jQuery; * // => true */ function startsWith(string, target, position) { - string = baseToString(string); - position = position == null - ? 0 - : nativeMin(position < 0 ? 0 : (+position || 0), string.length); - + string = toString(string); + position = baseClamp(toInteger(position), 0, string.length); return string.lastIndexOf(target, position) == position; } @@ -44985,7 +48663,7 @@ return jQuery; * in "interpolate" delimiters, HTML-escape interpolated data properties in * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data * properties may be accessed as free variables in the template. If a setting - * object is provided it takes precedence over `_.templateSettings` values. + * object is given it takes precedence over `_.templateSettings` values. * * **Note:** In the development build `_.template` utilizes * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) @@ -45008,58 +48686,58 @@ return jQuery; * @param {RegExp} [options.interpolate] The "interpolate" delimiter. * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. * @param {string} [options.variable] The data object variable name. - * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Function} Returns the compiled template function. * @example * - * // using the "interpolate" delimiter to create a compiled template + * // Use the "interpolate" delimiter to create a compiled template. * var compiled = _.template('hello <%= user %>!'); * compiled({ 'user': 'fred' }); * // => 'hello fred!' * - * // using the HTML "escape" delimiter to escape data property values + * // Use the HTML "escape" delimiter to escape data property values. * var compiled = _.template('<b><%- value %></b>'); * compiled({ 'value': '<script>' }); * // => '<b><script></b>' * - * // using the "evaluate" delimiter to execute JavaScript and generate HTML + * // Use the "evaluate" delimiter to execute JavaScript and generate HTML. * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>'); * compiled({ 'users': ['fred', 'barney'] }); * // => '<li>fred</li><li>barney</li>' * - * // using the internal `print` function in "evaluate" delimiters + * // Use the internal `print` function in "evaluate" delimiters. * var compiled = _.template('<% print("hello " + user); %>!'); * compiled({ 'user': 'barney' }); * // => 'hello barney!' * - * // using the ES delimiter as an alternative to the default "interpolate" delimiter + * // Use the ES delimiter as an alternative to the default "interpolate" delimiter. * var compiled = _.template('hello ${ user }!'); * compiled({ 'user': 'pebbles' }); * // => 'hello pebbles!' * - * // using custom template delimiters + * // Use custom template delimiters. * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; * var compiled = _.template('hello {{ user }}!'); * compiled({ 'user': 'mustache' }); * // => 'hello mustache!' * - * // using backslashes to treat delimiters as plain text + * // Use backslashes to treat delimiters as plain text. * var compiled = _.template('<%= "\\<%- value %\\>" %>'); * compiled({ 'value': 'ignored' }); * // => '<%- value %>' * - * // using the `imports` option to import `jQuery` as `jq` + * // Use the `imports` option to import `jQuery` as `jq`. * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>'; * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); * compiled({ 'users': ['fred', 'barney'] }); * // => '<li>fred</li><li>barney</li>' * - * // using the `sourceURL` option to specify a custom sourceURL for the template + * // Use the `sourceURL` option to specify a custom sourceURL for the template. * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); * compiled(data); * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector * - * // using the `variable` option to ensure a with-statement isn't used in the compiled template + * // Use the `variable` option to ensure a with-statement isn't used in the compiled template. * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); * compiled.source; * // => function(data) { @@ -45068,26 +48746,26 @@ return jQuery; * // return __p; * // } * - * // using the `source` property to inline compiled templates for meaningful - * // line numbers in error messages and a stack trace + * // Use the `source` property to inline compiled templates for meaningful + * // line numbers in error messages and stack traces. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ * var JST = {\ * "main": ' + _.template(mainText).source + '\ * };\ * '); */ - function template(string, options, otherOptions) { + function template(string, options, guard) { // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/) // and Laura Doktorova's doT.js (https://github.com/olado/doT). var settings = lodash.templateSettings; - if (otherOptions && isIterateeCall(string, options, otherOptions)) { - options = otherOptions = undefined; + if (guard && isIterateeCall(string, options, guard)) { + options = undefined; } - string = baseToString(string); - options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults); + string = toString(string); + options = assignInWith({}, options, settings, assignInDefaults); - var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults), + var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults), importsKeys = keys(imports), importsValues = baseValues(imports, importsKeys); @@ -45132,8 +48810,8 @@ return jQuery; } index = offset + match.length; - // The JS engine embedded in Adobe products requires returning the `match` - // string in order to produce the correct `offset` value. + // The JS engine embedded in Adobe products needs `match` returned in + // order to produce the correct `offset` value. return match; }); @@ -45170,7 +48848,8 @@ return jQuery; 'return __p\n}'; var result = attempt(function() { - return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues); + return Function(importsKeys, sourceURL + 'return ' + source) + .apply(undefined, importsValues); }); // Provide the compiled function's source by its `toString` method or @@ -45183,6 +48862,52 @@ return jQuery; } /** + * Converts `string`, as a whole, to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.toLower('--Foo-Bar'); + * // => '--foo-bar' + * + * _.toLower('fooBar'); + * // => 'foobar' + * + * _.toLower('__FOO_BAR__'); + * // => '__foo_bar__' + */ + function toLower(value) { + return toString(value).toLowerCase(); + } + + /** + * Converts `string`, as a whole, to upper case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the upper cased string. + * @example + * + * _.toUpper('--foo-bar'); + * // => '--FOO-BAR' + * + * _.toUpper('fooBar'); + * // => 'FOOBAR' + * + * _.toUpper('__foo_bar__'); + * // => '__FOO_BAR__' + */ + function toUpper(value) { + return toString(value).toUpperCase(); + } + + /** * Removes leading and trailing whitespace or specified characters from `string`. * * @static @@ -45190,7 +48915,7 @@ return jQuery; * @category String * @param {string} [string=''] The string to trim. * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {string} Returns the trimmed string. * @example * @@ -45204,76 +48929,95 @@ return jQuery; * // => ['foo', 'bar'] */ function trim(string, chars, guard) { - var value = string; - string = baseToString(string); + string = toString(string); if (!string) { return string; } - if (guard ? isIterateeCall(value, chars, guard) : chars == null) { - return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1); + if (guard || chars === undefined) { + return string.replace(reTrim, ''); } chars = (chars + ''); - return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1); + if (!chars) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars); + + return strSymbols + .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1) + .join(''); } /** - * Removes leading whitespace or specified characters from `string`. + * Removes trailing whitespace or specified characters from `string`. * * @static * @memberOf _ * @category String * @param {string} [string=''] The string to trim. * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {string} Returns the trimmed string. * @example * - * _.trimLeft(' abc '); - * // => 'abc ' + * _.trimEnd(' abc '); + * // => ' abc' * - * _.trimLeft('-_-abc-_-', '_-'); - * // => 'abc-_-' + * _.trimEnd('-_-abc-_-', '_-'); + * // => '-_-abc' */ - function trimLeft(string, chars, guard) { - var value = string; - string = baseToString(string); + function trimEnd(string, chars, guard) { + string = toString(string); if (!string) { return string; } - if (guard ? isIterateeCall(value, chars, guard) : chars == null) { - return string.slice(trimmedLeftIndex(string)); + if (guard || chars === undefined) { + return string.replace(reTrimEnd, ''); + } + chars = (chars + ''); + if (!chars) { + return string; } - return string.slice(charsLeftIndex(string, (chars + ''))); + var strSymbols = stringToArray(string); + return strSymbols + .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1) + .join(''); } /** - * Removes trailing whitespace or specified characters from `string`. + * Removes leading whitespace or specified characters from `string`. * * @static * @memberOf _ * @category String * @param {string} [string=''] The string to trim. * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {string} Returns the trimmed string. * @example * - * _.trimRight(' abc '); - * // => ' abc' + * _.trimStart(' abc '); + * // => 'abc ' * - * _.trimRight('-_-abc-_-', '_-'); - * // => '-_-abc' + * _.trimStart('-_-abc-_-', '_-'); + * // => 'abc-_-' */ - function trimRight(string, chars, guard) { - var value = string; - string = baseToString(string); + function trimStart(string, chars, guard) { + string = toString(string); if (!string) { return string; } - if (guard ? isIterateeCall(value, chars, guard) : chars == null) { - return string.slice(0, trimmedRightIndex(string) + 1); + if (guard || chars === undefined) { + return string.replace(reTrimStart, ''); } - return string.slice(0, charsRightIndex(string, (chars + '')) + 1); + chars = (chars + ''); + if (!chars) { + return string; + } + var strSymbols = stringToArray(string); + return strSymbols + .slice(charsStartIndex(strSymbols, stringToArray(chars))) + .join(''); } /** @@ -45285,79 +49029,79 @@ return jQuery; * @memberOf _ * @category String * @param {string} [string=''] The string to truncate. - * @param {Object|number} [options] The options object or maximum string length. + * @param {Object} [options=({})] The options object. * @param {number} [options.length=30] The maximum string length. * @param {string} [options.omission='...'] The string to indicate text is omitted. * @param {RegExp|string} [options.separator] The separator pattern to truncate to. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {string} Returns the truncated string. * @example * - * _.trunc('hi-diddly-ho there, neighborino'); + * _.truncate('hi-diddly-ho there, neighborino'); * // => 'hi-diddly-ho there, neighbo...' * - * _.trunc('hi-diddly-ho there, neighborino', 24); - * // => 'hi-diddly-ho there, n...' - * - * _.trunc('hi-diddly-ho there, neighborino', { + * _.truncate('hi-diddly-ho there, neighborino', { * 'length': 24, * 'separator': ' ' * }); * // => 'hi-diddly-ho there,...' * - * _.trunc('hi-diddly-ho there, neighborino', { + * _.truncate('hi-diddly-ho there, neighborino', { * 'length': 24, * 'separator': /,? +/ * }); * // => 'hi-diddly-ho there...' * - * _.trunc('hi-diddly-ho there, neighborino', { + * _.truncate('hi-diddly-ho there, neighborino', { * 'omission': ' [...]' * }); * // => 'hi-diddly-ho there, neig [...]' */ - function trunc(string, options, guard) { - if (guard && isIterateeCall(string, options, guard)) { - options = undefined; - } + function truncate(string, options) { var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION; - if (options != null) { - if (isObject(options)) { - var separator = 'separator' in options ? options.separator : separator; - length = 'length' in options ? (+options.length || 0) : length; - omission = 'omission' in options ? baseToString(options.omission) : omission; - } else { - length = +options || 0; - } + if (isObject(options)) { + var separator = 'separator' in options ? options.separator : separator; + length = 'length' in options ? toInteger(options.length) : length; + omission = 'omission' in options ? toString(options.omission) : omission; } - string = baseToString(string); - if (length >= string.length) { + string = toString(string); + + var strLength = string.length; + if (reHasComplexSymbol.test(string)) { + var strSymbols = stringToArray(string); + strLength = strSymbols.length; + } + if (length >= strLength) { return string; } - var end = length - omission.length; + var end = length - stringSize(omission); if (end < 1) { return omission; } - var result = string.slice(0, end); - if (separator == null) { + var result = strSymbols + ? strSymbols.slice(0, end).join('') + : string.slice(0, end); + + if (separator === undefined) { return result + omission; } + if (strSymbols) { + end += (result.length - end); + } if (isRegExp(separator)) { if (string.slice(end).search(separator)) { var match, - newEnd, - substring = string.slice(0, end); + substring = result; if (!separator.global) { - separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g'); + separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g'); } separator.lastIndex = 0; while ((match = separator.exec(substring))) { - newEnd = match.index; + var newEnd = match.index; } - result = result.slice(0, newEnd == null ? end : newEnd); + result = result.slice(0, newEnd === undefined ? end : newEnd); } } else if (string.indexOf(separator, end) != end) { var index = result.lastIndexOf(separator); @@ -45387,13 +49131,36 @@ return jQuery; * // => 'fred, barney, & pebbles' */ function unescape(string) { - string = baseToString(string); + string = toString(string); return (string && reHasEscapedHtml.test(string)) ? string.replace(reEscapedHtml, unescapeHtmlChar) : string; } /** + * Converts `string`, as space separated words, to upper case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the upper cased string. + * @example + * + * _.upperCase('--foo-bar'); + * // => 'FOO BAR' + * + * _.upperCase('fooBar'); + * // => 'FOO BAR' + * + * _.upperCase('__foo_bar__'); + * // => 'FOO BAR' + */ + var upperCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toUpperCase(); + }); + + /** * Splits `string` into an array of its words. * * @static @@ -45401,7 +49168,7 @@ return jQuery; * @category String * @param {string} [string=''] The string to inspect. * @param {RegExp|string} [pattern] The pattern to match words. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {Array} Returns the words of `string`. * @example * @@ -45412,27 +49179,29 @@ return jQuery; * // => ['fred', 'barney', '&', 'pebbles'] */ function words(string, pattern, guard) { - if (guard && isIterateeCall(string, pattern, guard)) { - pattern = undefined; + string = toString(string); + pattern = guard ? undefined : pattern; + + if (pattern === undefined) { + pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord; } - string = baseToString(string); - return string.match(pattern || reWords) || []; + return string.match(pattern) || []; } /*------------------------------------------------------------------------*/ /** * Attempts to invoke `func`, returning either the result or the caught error - * object. Any additional arguments are provided to `func` when it is invoked. + * object. Any additional arguments are provided to `func` when it's invoked. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Function} func The function to attempt. * @returns {*} Returns the `func` result or error object. * @example * - * // avoid throwing errors for invalid selectors + * // Avoid throwing errors for invalid selectors. * var elements = _.attempt(function(selector) { * return document.querySelectorAll(selector); * }, '>_>'); @@ -45441,29 +49210,107 @@ return jQuery; * elements = []; * } */ - var attempt = restParam(function(func, args) { + var attempt = rest(function(func, args) { try { - return func.apply(undefined, args); - } catch(e) { + return apply(func, undefined, args); + } catch (e) { return isError(e) ? e : new Error(e); } }); /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and arguments of the created function. If `func` is a property name the - * created callback returns the property value for a given element. If `func` - * is an object the created callback returns `true` for elements that contain - * the equivalent object properties, otherwise it returns `false`. + * Binds methods of an object to the object itself, overwriting the existing + * method. + * + * **Note:** This method doesn't set the "length" property of bound functions. * * @static * @memberOf _ - * @alias iteratee - * @category Utility - * @param {*} [func=_.identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the callback. + * @category Util + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} methodNames The object method names to bind, + * specified individually or in arrays. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view, 'onClick'); + * jQuery(element).on('click', view.onClick); + * // => logs 'clicked docs' when clicked + */ + var bindAll = rest(function(object, methodNames) { + arrayEach(baseFlatten(methodNames, 1), function(key) { + object[key] = bind(object[key], object); + }); + return object; + }); + + /** + * Creates a function that iterates over `pairs` invoking the corresponding + * function of the first predicate to return truthy. The predicate-function + * pairs are invoked with the `this` binding and arguments of the created + * function. + * + * @static + * @memberOf _ + * @category Util + * @param {Array} pairs The predicate-function pairs. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.cond([ + * [_.matches({ 'a': 1 }), _.constant('matches A')], + * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], + * [_.constant(true), _.constant('no match')] + * ]); + * + * func({ 'a': 1, 'b': 2 }); + * // => 'matches A' + * + * func({ 'a': 0, 'b': 1 }); + * // => 'matches B' + * + * func({ 'a': '1', 'b': '2' }); + * // => 'no match' + */ + function cond(pairs) { + var length = pairs ? pairs.length : 0, + toIteratee = getIteratee(); + + pairs = !length ? [] : arrayMap(pairs, function(pair) { + if (typeof pair[1] != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return [toIteratee(pair[0]), pair[1]]; + }); + + return rest(function(args) { + var index = -1; + while (++index < length) { + var pair = pairs[index]; + if (apply(pair[0], this, args)) { + return apply(pair[1], this, args); + } + } + }); + } + + /** + * Creates a function that invokes the predicate properties of `source` with + * the corresponding property values of a given object, returning `true` if + * all predicates return truthy, else `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. * @example * * var users = [ @@ -45471,29 +49318,11 @@ return jQuery; * { 'user': 'fred', 'age': 40 } * ]; * - * // wrap to create custom callback shorthands - * _.callback = _.wrap(_.callback, function(callback, func, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(func); - * if (!match) { - * return callback(func, thisArg); - * } - * return function(object) { - * return match[2] == 'gt' - * ? object[match[1]] > match[3] - * : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(users, 'age__gt36'); + * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); * // => [{ 'user': 'fred', 'age': 40 }] */ - function callback(func, thisArg, guard) { - if (guard && isIterateeCall(func, thisArg, guard)) { - thisArg = undefined; - } - return isObjectLike(func) - ? matches(func) - : baseCallback(func, thisArg); + function conforms(source) { + return baseConforms(baseClone(source, true)); } /** @@ -45501,7 +49330,7 @@ return jQuery; * * @static * @memberOf _ - * @category Utility + * @category Util * @param {*} value The value to return from the new function. * @returns {Function} Returns the new function. * @example @@ -45519,11 +49348,54 @@ return jQuery; } /** - * This method returns the first argument provided to it. + * Creates a function that returns the result of invoking the given functions + * with the `this` binding of the created function, where each successive + * invocation is supplied the return value of the previous. * * @static * @memberOf _ - * @category Utility + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the given functions from right to left. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * This method returns the first argument given to it. + * + * @static + * @memberOf _ + * @category Util * @param {*} value Any value. * @returns {*} Returns `value`. * @example @@ -45538,18 +49410,50 @@ return jQuery; } /** - * Creates a function that performs a deep comparison between a given object - * and `source`, returning `true` if the given object has equivalent property - * values, else `false`. + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ + function iteratee(func) { + return baseIteratee(typeof func == 'function' ? func : baseClone(func, true)); + } + + /** + * Creates a function that performs a partial deep comparison between a given + * object and `source`, returning `true` if the given object has equivalent + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. + * **Note:** This method supports comparing the same values as `_.isEqual`. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Object} source The object of property values to match. * @returns {Function} Returns the new function. * @example @@ -45567,16 +49471,15 @@ return jQuery; } /** - * Creates a function that compares the property value of `path` on a given - * object to `value`. + * Creates a function that performs a partial deep comparison between the + * value at `path` of a given object to `srcValue`, returning `true` if the + * object value is equivalent, else `false`. * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. + * **Note:** This method supports comparing the same values as `_.isEqual`. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Array|string} path The path of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new function. @@ -45595,12 +49498,12 @@ return jQuery; } /** - * Creates a function that invokes the method at `path` on a given object. + * Creates a function that invokes the method at `path` of a given object. * Any additional arguments are provided to the invoked method. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Array|string} path The path of the method to invoke. * @param {...*} [args] The arguments to invoke the method with. * @returns {Function} Returns the new function. @@ -45614,23 +49517,23 @@ return jQuery; * _.map(objects, _.method('a.b.c')); * // => [2, 1] * - * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); + * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); * // => [1, 2] */ - var method = restParam(function(path, args) { + var method = rest(function(path, args) { return function(object) { - return invokePath(object, path, args); + return baseInvoke(object, path, args); }; }); /** * The opposite of `_.method`; this method creates a function that invokes - * the method at a given path on `object`. Any additional arguments are + * the method at a given path of `object`. Any additional arguments are * provided to the invoked method. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Object} object The object to query. * @param {...*} [args] The arguments to invoke the method with. * @returns {Function} Returns the new function. @@ -45645,9 +49548,9 @@ return jQuery; * _.map([['a', '2'], ['c', '0']], _.methodOf(object)); * // => [2, 0] */ - var methodOf = restParam(function(object, args) { + var methodOf = rest(function(object, args) { return function(path) { - return invokePath(object, path, args); + return baseInvoke(object, path, args); }; }); @@ -45661,7 +49564,7 @@ return jQuery; * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Function|Object} [object=lodash] The destination object. * @param {Object} source The object of functions to add. * @param {Object} [options] The options object. @@ -45688,53 +49591,38 @@ return jQuery; * // => ['e'] */ function mixin(object, source, options) { - if (options == null) { - var isObj = isObject(source), - props = isObj ? keys(source) : undefined, - methodNames = (props && props.length) ? baseFunctions(source, props) : undefined; - - if (!(methodNames ? methodNames.length : isObj)) { - methodNames = false; - options = source; - source = object; - object = this; - } - } - if (!methodNames) { + var props = keys(source), + methodNames = baseFunctions(source, props); + + if (options == null && + !(isObject(source) && (methodNames.length || !props.length))) { + options = source; + source = object; + object = this; methodNames = baseFunctions(source, keys(source)); } - var chain = true, - index = -1, - isFunc = isFunction(object), - length = methodNames.length; - - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - while (++index < length) { - var methodName = methodNames[index], - func = source[methodName]; + var chain = (isObject(options) && 'chain' in options) ? options.chain : true, + isFunc = isFunction(object); + arrayEach(methodNames, function(methodName) { + var func = source[methodName]; object[methodName] = func; if (isFunc) { - object.prototype[methodName] = (function(func) { - return function() { - var chainAll = this.__chain__; - if (chain || chainAll) { - var result = object(this.__wrapped__), - actions = result.__actions__ = arrayCopy(this.__actions__); - - actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); - result.__chain__ = chainAll; - return result; - } - return func.apply(object, arrayPush([this.value()], arguments)); - }; - }(func)); + object.prototype[methodName] = function() { + var chainAll = this.__chain__; + if (chain || chainAll) { + var result = object(this.__wrapped__), + actions = result.__actions__ = copyArray(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); + result.__chain__ = chainAll; + return result; + } + return func.apply(object, arrayPush([this.value()], arguments)); + }; } - } + }); + return object; } @@ -45744,14 +49632,16 @@ return jQuery; * * @static * @memberOf _ - * @category Utility + * @category Util * @returns {Function} Returns the `lodash` function. * @example * * var lodash = _.noConflict(); */ function noConflict() { - root._ = oldDash; + if (root._ === this) { + root._ = oldDash; + } return this; } @@ -45761,7 +49651,7 @@ return jQuery; * * @static * @memberOf _ - * @category Utility + * @category Util * @example * * var object = { 'user': 'fred' }; @@ -45774,12 +49664,99 @@ return jQuery; } /** - * Creates a function that returns the property value at `path` on a - * given object. + * Creates a function that returns its nth argument. + * + * @static + * @memberOf _ + * @category Util + * @param {number} [n=0] The index of the argument to return. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.nthArg(1); + * + * func('a', 'b', 'c'); + * // => 'b' + */ + function nthArg(n) { + n = toInteger(n); + return function() { + return arguments[n]; + }; + } + + /** + * Creates a function that invokes `iteratees` with the arguments provided + * to the created function and returns their results. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} iteratees The iteratees to invoke. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.over(Math.max, Math.min); + * + * func(1, 2, 3, 4); + * // => [4, 1] + */ + var over = createOver(arrayMap); + + /** + * Creates a function that checks if **all** of the `predicates` return + * truthy when invoked with the arguments provided to the created function. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} predicates The predicates to check. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.overEvery(Boolean, isFinite); + * + * func('1'); + * // => true + * + * func(null); + * // => false + * + * func(NaN); + * // => false + */ + var overEvery = createOver(arrayEvery); + + /** + * Creates a function that checks if **any** of the `predicates` return + * truthy when invoked with the arguments provided to the created function. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} predicates The predicates to check. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.overSome(Boolean, isFinite); + * + * func('1'); + * // => true + * + * func(null); + * // => true + * + * func(NaN); + * // => false + */ + var overSome = createOver(arraySome); + + /** + * Creates a function that returns the value at `path` of a given object. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new function. * @example @@ -45792,7 +49769,7 @@ return jQuery; * _.map(objects, _.property('a.b.c')); * // => [2, 1] * - * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); + * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); * // => [1, 2] */ function property(path) { @@ -45801,11 +49778,11 @@ return jQuery; /** * The opposite of `_.property`; this method creates a function that returns - * the property value at a given path on `object`. + * the value at a given path of `object`. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {Object} object The object to query. * @returns {Function} Returns the new function. * @example @@ -45821,19 +49798,22 @@ return jQuery; */ function propertyOf(object) { return function(path) { - return baseGet(object, toPath(path), path + ''); + return object == null ? undefined : baseGet(object, path); }; } /** * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to, but not including, `end`. If `end` is not specified it is - * set to `start` with `start` then set to `0`. If `end` is less than `start` - * a zero-length range is created unless a negative `step` is specified. + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. * * @static * @memberOf _ - * @category Utility + * @category Util * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. * @param {number} [step=1] The value to increment or decrement by. @@ -45843,6 +49823,9 @@ return jQuery; * _.range(4); * // => [0, 1, 2, 3] * + * _.range(-4); + * // => [0, -1, -2, -3] + * * _.range(1, 5); * // => [1, 2, 3, 4] * @@ -45858,88 +49841,116 @@ return jQuery; * _.range(0); * // => [] */ - function range(start, end, step) { - if (step && isIterateeCall(start, end, step)) { - end = step = undefined; - } - start = +start || 0; - step = step == null ? 1 : (+step || 0); - - if (end == null) { - end = start; - start = 0; - } else { - end = +end || 0; - } - // Use `Array(length)` so engines like Chakra and V8 avoid slower modes. - // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); + var range = createRange(); - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } + /** + * This method is like `_.range` except that it populates values in + * descending order. + * + * @static + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the new array of numbers. + * @example + * + * _.rangeRight(4); + * // => [3, 2, 1, 0] + * + * _.rangeRight(-4); + * // => [-3, -2, -1, 0] + * + * _.rangeRight(1, 5); + * // => [4, 3, 2, 1] + * + * _.rangeRight(0, 20, 5); + * // => [15, 10, 5, 0] + * + * _.rangeRight(0, -4, -1); + * // => [-3, -2, -1, 0] + * + * _.rangeRight(1, 4, 0); + * // => [1, 1, 1] + * + * _.rangeRight(0); + * // => [] + */ + var rangeRight = createRange(true); /** - * Invokes the iteratee function `n` times, returning an array of the results - * of each invocation. The `iteratee` is bound to `thisArg` and invoked with - * one argument; (index). + * Invokes the iteratee `n` times, returning an array of the results of + * each invocation. The iteratee is invoked with one argument; (index). * * @static * @memberOf _ - * @category Utility + * @category Util * @param {number} n The number of times to invoke `iteratee`. * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns the array of results. * @example * - * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false)); - * // => [3, 6, 4] - * - * _.times(3, function(n) { - * mage.castSpell(n); - * }); - * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2` + * _.times(3, String); + * // => ['0', '1', '2'] * - * _.times(3, function(n) { - * this.cast(n); - * }, mage); - * // => also invokes `mage.castSpell(n)` three times + * _.times(4, _.constant(true)); + * // => [true, true, true, true] */ - function times(n, iteratee, thisArg) { - n = nativeFloor(n); - - // Exit early to avoid a JSC JIT bug in Safari 8 - // where `Array(0)` is treated as `Array(1)`. - if (n < 1 || !nativeIsFinite(n)) { + function times(n, iteratee) { + n = toInteger(n); + if (n < 1 || n > MAX_SAFE_INTEGER) { return []; } - var index = -1, - result = Array(nativeMin(n, MAX_ARRAY_LENGTH)); + var index = MAX_ARRAY_LENGTH, + length = nativeMin(n, MAX_ARRAY_LENGTH); + + iteratee = baseCastFunction(iteratee); + n -= MAX_ARRAY_LENGTH; - iteratee = bindCallback(iteratee, thisArg, 1); + var result = baseTimes(length, iteratee); while (++index < n) { - if (index < MAX_ARRAY_LENGTH) { - result[index] = iteratee(index); - } else { - iteratee(index); - } + iteratee(index); } return result; } /** - * Generates a unique ID. If `prefix` is provided the ID is appended to it. + * Converts `value` to a property path array. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value The value to convert. + * @returns {Array} Returns the new property path array. + * @example + * + * _.toPath('a.b.c'); + * // => ['a', 'b', 'c'] + * + * _.toPath('a[0].b.c'); + * // => ['a', '0', 'b', 'c'] + * + * var path = ['a', 'b', 'c'], + * newPath = _.toPath(path); + * + * console.log(newPath); + * // => ['a', 'b', 'c'] + * + * console.log(path === newPath); + * // => false + */ + function toPath(value) { + return isArray(value) ? arrayMap(value, String) : stringToPath(value); + } + + /** + * Generates a unique ID. If `prefix` is given the ID is appended to it. * * @static * @memberOf _ - * @category Utility - * @param {string} [prefix] The value to prefix the ID with. + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. * @returns {string} Returns the unique ID. * @example * @@ -45951,7 +49962,7 @@ return jQuery; */ function uniqueId(prefix) { var id = ++idCounter; - return baseToString(prefix) + id; + return toString(prefix) + id; } /*------------------------------------------------------------------------*/ @@ -45962,25 +49973,35 @@ return jQuery; * @static * @memberOf _ * @category Math - * @param {number} augend The first number to add. - * @param {number} addend The second number to add. - * @returns {number} Returns the sum. + * @param {number} augend The first number in an addition. + * @param {number} addend The second number in an addition. + * @returns {number} Returns the total. * @example * * _.add(6, 4); * // => 10 */ function add(augend, addend) { - return (+augend || 0) + (+addend || 0); + var result; + if (augend === undefined && addend === undefined) { + return 0; + } + if (augend !== undefined) { + result = augend; + } + if (addend !== undefined) { + result = result === undefined ? addend : (result + addend); + } + return result; } /** - * Calculates `n` rounded up to `precision`. + * Computes `number` rounded up to `precision`. * * @static * @memberOf _ * @category Math - * @param {number} n The number to round up. + * @param {number} number The number to round up. * @param {number} [precision=0] The precision to round up to. * @returns {number} Returns the rounded up number. * @example @@ -45997,12 +50018,12 @@ return jQuery; var ceil = createRound('ceil'); /** - * Calculates `n` rounded down to `precision`. + * Computes `number` rounded down to `precision`. * * @static * @memberOf _ * @category Math - * @param {number} n The number to round down. + * @param {number} number The number to round down. * @param {number} [precision=0] The precision to round down to. * @returns {number} Returns the rounded down number. * @example @@ -46019,29 +50040,13 @@ return jQuery; var floor = createRound('floor'); /** - * Gets the maximum value of `collection`. If `collection` is empty or falsey - * `-Infinity` is returned. If an iteratee function is provided it is invoked - * for each value in `collection` to generate the criterion by which the value - * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Computes the maximum value of `array`. If `array` is empty or falsey + * `undefined` is returned. * * @static * @memberOf _ * @category Math - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array} array The array to iterate over. * @returns {*} Returns the maximum value. * @example * @@ -46049,48 +50054,67 @@ return jQuery; * // => 8 * * _.max([]); - * // => -Infinity + * // => undefined + */ + function max(array) { + return (array && array.length) + ? baseExtremum(array, identity, gt) + : undefined; + } + + /** + * This method is like `_.max` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the maximum value. + * @example * - * _.max(users, function(chr) { - * return chr.age; - * }); - * // => { 'user': 'fred', 'age': 40 } + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.maxBy(objects, function(o) { return o.n; }); + * // => { 'n': 2 } * - * // using the `_.property` callback shorthand - * _.max(users, 'age'); - * // => { 'user': 'fred', 'age': 40 } + * // The `_.property` iteratee shorthand. + * _.maxBy(objects, 'n'); + * // => { 'n': 2 } */ - var max = createExtremum(gt, NEGATIVE_INFINITY); + function maxBy(array, iteratee) { + return (array && array.length) + ? baseExtremum(array, getIteratee(iteratee), gt) + : undefined; + } /** - * Gets the minimum value of `collection`. If `collection` is empty or falsey - * `Infinity` is returned. If an iteratee function is provided it is invoked - * for each value in `collection` to generate the criterion by which the value - * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index, collection). + * Computes the mean of the values in `array`. * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {number} Returns the mean. + * @example * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.mean([4, 2, 8, 6]); + * // => 5 + */ + function mean(array) { + return sum(array) / (array ? array.length : 0); + } + + /** + * Computes the minimum value of `array`. If `array` is empty or falsey + * `undefined` is returned. * * @static * @memberOf _ * @category Math - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array} array The array to iterate over. * @returns {*} Returns the minimum value. * @example * @@ -46098,31 +50122,49 @@ return jQuery; * // => 2 * * _.min([]); - * // => Infinity + * // => undefined + */ + function min(array) { + return (array && array.length) + ? baseExtremum(array, identity, lt) + : undefined; + } + + /** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example * - * _.min(users, function(chr) { - * return chr.age; - * }); - * // => { 'user': 'barney', 'age': 36 } + * var objects = [{ 'n': 1 }, { 'n': 2 }]; * - * // using the `_.property` callback shorthand - * _.min(users, 'age'); - * // => { 'user': 'barney', 'age': 36 } + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } */ - var min = createExtremum(lt, POSITIVE_INFINITY); + function minBy(array, iteratee) { + return (array && array.length) + ? baseExtremum(array, getIteratee(iteratee), lt) + : undefined; + } /** - * Calculates `n` rounded to `precision`. + * Computes `number` rounded to `precision`. * * @static * @memberOf _ * @category Math - * @param {number} n The number to round. + * @param {number} number The number to round. * @param {number} [precision=0] The precision to round to. * @returns {number} Returns the rounded number. * @example @@ -46139,45 +50181,78 @@ return jQuery; var round = createRound('round'); /** - * Gets the sum of the values in `collection`. + * Subtract two numbers. + * + * @static + * @memberOf _ + * @category Math + * @param {number} minuend The first number in a subtraction. + * @param {number} subtrahend The second number in a subtraction. + * @returns {number} Returns the difference. + * @example + * + * _.subtract(6, 4); + * // => 2 + */ + function subtract(minuend, subtrahend) { + var result; + if (minuend === undefined && subtrahend === undefined) { + return 0; + } + if (minuend !== undefined) { + result = minuend; + } + if (subtrahend !== undefined) { + result = result === undefined ? subtrahend : (result - subtrahend); + } + return result; + } + + /** + * Computes the sum of the values in `array`. * * @static * @memberOf _ * @category Math - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. + * @param {Array} array The array to iterate over. * @returns {number} Returns the sum. * @example * - * _.sum([4, 6]); - * // => 10 + * _.sum([4, 2, 8, 6]); + * // => 20 + */ + function sum(array) { + return (array && array.length) + ? baseSum(array, identity) + : 0; + } + + /** + * This method is like `_.sum` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the value to be summed. + * The iteratee is invoked with one argument: (value). * - * _.sum({ 'a': 4, 'b': 6 }); - * // => 10 + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the sum. + * @example * - * var objects = [ - * { 'n': 4 }, - * { 'n': 6 } - * ]; + * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; * - * _.sum(objects, function(object) { - * return object.n; - * }); - * // => 10 + * _.sumBy(objects, function(o) { return o.n; }); + * // => 20 * - * // using the `_.property` callback shorthand - * _.sum(objects, 'n'); - * // => 10 + * // The `_.property` iteratee shorthand. + * _.sumBy(objects, 'n'); + * // => 20 */ - function sum(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - iteratee = getCallback(iteratee, thisArg, 3); - return iteratee.length == 1 - ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee) - : baseSum(collection, iteratee); + function sumBy(array, iteratee) { + return (array && array.length) + ? baseSum(array, getIteratee(iteratee)) + : 0; } /*------------------------------------------------------------------------*/ @@ -46191,15 +50266,26 @@ return jQuery; LazyWrapper.prototype = baseCreate(baseLodash.prototype); LazyWrapper.prototype.constructor = LazyWrapper; - // Add functions to the `Map` cache. + // Avoid inheriting from `Object.prototype` when possible. + Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; + + // Add functions to the `MapCache`. + MapCache.prototype.clear = mapClear; MapCache.prototype['delete'] = mapDelete; MapCache.prototype.get = mapGet; MapCache.prototype.has = mapHas; MapCache.prototype.set = mapSet; - // Add functions to the `Set` cache. + // Add functions to the `SetCache`. SetCache.prototype.push = cachePush; + // Add functions to the `Stack` cache. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + // Assign cache to `_.memoize`. memoize.Cache = MapCache; @@ -46207,15 +50293,21 @@ return jQuery; lodash.after = after; lodash.ary = ary; lodash.assign = assign; + lodash.assignIn = assignIn; + lodash.assignInWith = assignInWith; + lodash.assignWith = assignWith; lodash.at = at; lodash.before = before; lodash.bind = bind; lodash.bindAll = bindAll; lodash.bindKey = bindKey; - lodash.callback = callback; + lodash.castArray = castArray; lodash.chain = chain; lodash.chunk = chunk; lodash.compact = compact; + lodash.concat = concat; + lodash.cond = cond; + lodash.conforms = conforms; lodash.constant = constant; lodash.countBy = countBy; lodash.create = create; @@ -46227,29 +50319,34 @@ return jQuery; lodash.defer = defer; lodash.delay = delay; lodash.difference = difference; + lodash.differenceBy = differenceBy; + lodash.differenceWith = differenceWith; lodash.drop = drop; lodash.dropRight = dropRight; lodash.dropRightWhile = dropRightWhile; lodash.dropWhile = dropWhile; lodash.fill = fill; lodash.filter = filter; + lodash.flatMap = flatMap; lodash.flatten = flatten; lodash.flattenDeep = flattenDeep; + lodash.flattenDepth = flattenDepth; + lodash.flip = flip; lodash.flow = flow; lodash.flowRight = flowRight; - lodash.forEach = forEach; - lodash.forEachRight = forEachRight; - lodash.forIn = forIn; - lodash.forInRight = forInRight; - lodash.forOwn = forOwn; - lodash.forOwnRight = forOwnRight; + lodash.fromPairs = fromPairs; lodash.functions = functions; + lodash.functionsIn = functionsIn; lodash.groupBy = groupBy; - lodash.indexBy = indexBy; lodash.initial = initial; lodash.intersection = intersection; + lodash.intersectionBy = intersectionBy; + lodash.intersectionWith = intersectionWith; lodash.invert = invert; - lodash.invoke = invoke; + lodash.invertBy = invertBy; + lodash.invokeMap = invokeMap; + lodash.iteratee = iteratee; + lodash.keyBy = keyBy; lodash.keys = keys; lodash.keysIn = keysIn; lodash.map = map; @@ -46259,36 +50356,49 @@ return jQuery; lodash.matchesProperty = matchesProperty; lodash.memoize = memoize; lodash.merge = merge; + lodash.mergeWith = mergeWith; lodash.method = method; lodash.methodOf = methodOf; lodash.mixin = mixin; - lodash.modArgs = modArgs; lodash.negate = negate; + lodash.nthArg = nthArg; lodash.omit = omit; + lodash.omitBy = omitBy; lodash.once = once; - lodash.pairs = pairs; + lodash.orderBy = orderBy; + lodash.over = over; + lodash.overArgs = overArgs; + lodash.overEvery = overEvery; + lodash.overSome = overSome; lodash.partial = partial; lodash.partialRight = partialRight; lodash.partition = partition; lodash.pick = pick; - lodash.pluck = pluck; + lodash.pickBy = pickBy; lodash.property = property; lodash.propertyOf = propertyOf; lodash.pull = pull; + lodash.pullAll = pullAll; + lodash.pullAllBy = pullAllBy; lodash.pullAt = pullAt; lodash.range = range; + lodash.rangeRight = rangeRight; lodash.rearg = rearg; lodash.reject = reject; lodash.remove = remove; lodash.rest = rest; - lodash.restParam = restParam; + lodash.reverse = reverse; + lodash.sampleSize = sampleSize; lodash.set = set; + lodash.setWith = setWith; lodash.shuffle = shuffle; lodash.slice = slice; lodash.sortBy = sortBy; - lodash.sortByAll = sortByAll; - lodash.sortByOrder = sortByOrder; + lodash.sortedUniq = sortedUniq; + lodash.sortedUniqBy = sortedUniqBy; + lodash.split = split; lodash.spread = spread; + lodash.tail = tail; lodash.take = take; lodash.takeRight = takeRight; lodash.takeRightWhile = takeRightWhile; @@ -46296,37 +50406,38 @@ return jQuery; lodash.tap = tap; lodash.throttle = throttle; lodash.thru = thru; - lodash.times = times; lodash.toArray = toArray; + lodash.toPairs = toPairs; + lodash.toPairsIn = toPairsIn; + lodash.toPath = toPath; lodash.toPlainObject = toPlainObject; lodash.transform = transform; + lodash.unary = unary; lodash.union = union; + lodash.unionBy = unionBy; + lodash.unionWith = unionWith; lodash.uniq = uniq; + lodash.uniqBy = uniqBy; + lodash.uniqWith = uniqWith; + lodash.unset = unset; lodash.unzip = unzip; lodash.unzipWith = unzipWith; lodash.values = values; lodash.valuesIn = valuesIn; - lodash.where = where; lodash.without = without; + lodash.words = words; lodash.wrap = wrap; lodash.xor = xor; + lodash.xorBy = xorBy; + lodash.xorWith = xorWith; lodash.zip = zip; lodash.zipObject = zipObject; + lodash.zipObjectDeep = zipObjectDeep; lodash.zipWith = zipWith; // Add aliases. - lodash.backflow = flowRight; - lodash.collect = map; - lodash.compose = flowRight; - lodash.each = forEach; - lodash.eachRight = forEachRight; - lodash.extend = assign; - lodash.iteratee = callback; - lodash.methods = functions; - lodash.object = zipObject; - lodash.select = filter; - lodash.tail = rest; - lodash.unique = uniq; + lodash.extend = assignIn; + lodash.extendWith = assignInWith; // Add functions to `lodash.prototype`. mixin(lodash, lodash); @@ -46339,10 +50450,14 @@ return jQuery; lodash.camelCase = camelCase; lodash.capitalize = capitalize; lodash.ceil = ceil; + lodash.clamp = clamp; lodash.clone = clone; lodash.cloneDeep = cloneDeep; + lodash.cloneDeepWith = cloneDeepWith; + lodash.cloneWith = cloneWith; lodash.deburr = deburr; lodash.endsWith = endsWith; + lodash.eq = eq; lodash.escape = escape; lodash.escapeRegExp = escapeRegExp; lodash.every = every; @@ -46352,111 +50467,136 @@ return jQuery; lodash.findLast = findLast; lodash.findLastIndex = findLastIndex; lodash.findLastKey = findLastKey; - lodash.findWhere = findWhere; - lodash.first = first; lodash.floor = floor; + lodash.forEach = forEach; + lodash.forEachRight = forEachRight; + lodash.forIn = forIn; + lodash.forInRight = forInRight; + lodash.forOwn = forOwn; + lodash.forOwnRight = forOwnRight; lodash.get = get; lodash.gt = gt; lodash.gte = gte; lodash.has = has; + lodash.hasIn = hasIn; + lodash.head = head; lodash.identity = identity; lodash.includes = includes; lodash.indexOf = indexOf; lodash.inRange = inRange; + lodash.invoke = invoke; lodash.isArguments = isArguments; lodash.isArray = isArray; + lodash.isArrayBuffer = isArrayBuffer; + lodash.isArrayLike = isArrayLike; + lodash.isArrayLikeObject = isArrayLikeObject; lodash.isBoolean = isBoolean; + lodash.isBuffer = isBuffer; lodash.isDate = isDate; lodash.isElement = isElement; lodash.isEmpty = isEmpty; lodash.isEqual = isEqual; + lodash.isEqualWith = isEqualWith; lodash.isError = isError; lodash.isFinite = isFinite; lodash.isFunction = isFunction; + lodash.isInteger = isInteger; + lodash.isLength = isLength; + lodash.isMap = isMap; lodash.isMatch = isMatch; + lodash.isMatchWith = isMatchWith; lodash.isNaN = isNaN; lodash.isNative = isNative; + lodash.isNil = isNil; lodash.isNull = isNull; lodash.isNumber = isNumber; lodash.isObject = isObject; + lodash.isObjectLike = isObjectLike; lodash.isPlainObject = isPlainObject; lodash.isRegExp = isRegExp; + lodash.isSafeInteger = isSafeInteger; + lodash.isSet = isSet; lodash.isString = isString; + lodash.isSymbol = isSymbol; lodash.isTypedArray = isTypedArray; lodash.isUndefined = isUndefined; + lodash.isWeakMap = isWeakMap; + lodash.isWeakSet = isWeakSet; + lodash.join = join; lodash.kebabCase = kebabCase; lodash.last = last; lodash.lastIndexOf = lastIndexOf; + lodash.lowerCase = lowerCase; + lodash.lowerFirst = lowerFirst; lodash.lt = lt; lodash.lte = lte; lodash.max = max; + lodash.maxBy = maxBy; + lodash.mean = mean; lodash.min = min; + lodash.minBy = minBy; lodash.noConflict = noConflict; lodash.noop = noop; lodash.now = now; lodash.pad = pad; - lodash.padLeft = padLeft; - lodash.padRight = padRight; + lodash.padEnd = padEnd; + lodash.padStart = padStart; lodash.parseInt = parseInt; lodash.random = random; lodash.reduce = reduce; lodash.reduceRight = reduceRight; lodash.repeat = repeat; + lodash.replace = replace; lodash.result = result; lodash.round = round; lodash.runInContext = runInContext; + lodash.sample = sample; lodash.size = size; lodash.snakeCase = snakeCase; lodash.some = some; lodash.sortedIndex = sortedIndex; + lodash.sortedIndexBy = sortedIndexBy; + lodash.sortedIndexOf = sortedIndexOf; lodash.sortedLastIndex = sortedLastIndex; + lodash.sortedLastIndexBy = sortedLastIndexBy; + lodash.sortedLastIndexOf = sortedLastIndexOf; lodash.startCase = startCase; lodash.startsWith = startsWith; + lodash.subtract = subtract; lodash.sum = sum; + lodash.sumBy = sumBy; lodash.template = template; + lodash.times = times; + lodash.toInteger = toInteger; + lodash.toLength = toLength; + lodash.toLower = toLower; + lodash.toNumber = toNumber; + lodash.toSafeInteger = toSafeInteger; + lodash.toString = toString; + lodash.toUpper = toUpper; lodash.trim = trim; - lodash.trimLeft = trimLeft; - lodash.trimRight = trimRight; - lodash.trunc = trunc; + lodash.trimEnd = trimEnd; + lodash.trimStart = trimStart; + lodash.truncate = truncate; lodash.unescape = unescape; lodash.uniqueId = uniqueId; - lodash.words = words; + lodash.upperCase = upperCase; + lodash.upperFirst = upperFirst; // Add aliases. - lodash.all = every; - lodash.any = some; - lodash.contains = includes; - lodash.eq = isEqual; - lodash.detect = find; - lodash.foldl = reduce; - lodash.foldr = reduceRight; - lodash.head = first; - lodash.include = includes; - lodash.inject = reduce; + lodash.each = forEach; + lodash.eachRight = forEachRight; + lodash.first = head; mixin(lodash, (function() { var source = {}; baseForOwn(lodash, function(func, methodName) { - if (!lodash.prototype[methodName]) { + if (!hasOwnProperty.call(lodash.prototype, methodName)) { source[methodName] = func; } }); return source; - }()), false); - - /*------------------------------------------------------------------------*/ - - // Add functions capable of returning wrapped and unwrapped values when chaining. - lodash.sample = sample; - - lodash.prototype.sample = function(n) { - if (!this.__chain__ && n == null) { - return sample(this.value()); - } - return this.thru(function(value) { - return sample(value, n); - }); - }; + }()), { 'chain': false }); /*------------------------------------------------------------------------*/ @@ -46465,7 +50605,7 @@ return jQuery; * * @static * @memberOf _ - * @type string + * @type {string} */ lodash.VERSION = VERSION; @@ -46481,13 +50621,16 @@ return jQuery; if (filtered && !index) { return new LazyWrapper(this); } - n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0); + n = n === undefined ? 1 : nativeMax(toInteger(n), 0); var result = this.clone(); if (filtered) { - result.__takeCount__ = nativeMin(result.__takeCount__, n); + result.__takeCount__ = nativeMin(n, result.__takeCount__); } else { - result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); + result.__views__.push({ + 'size': nativeMin(n, MAX_ARRAY_LENGTH), + 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') + }); } return result; }; @@ -46500,18 +50643,21 @@ return jQuery; // Add `LazyWrapper` methods that accept an `iteratee` value. arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { var type = index + 1, - isFilter = type != LAZY_MAP_FLAG; + isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG; - LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { + LazyWrapper.prototype[methodName] = function(iteratee) { var result = this.clone(); - result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type }); + result.__iteratees__.push({ + 'iteratee': getIteratee(iteratee, 3), + 'type': type + }); result.__filtered__ = result.__filtered__ || isFilter; return result; }; }); - // Add `LazyWrapper` methods for `_.first` and `_.last`. - arrayEach(['first', 'last'], function(methodName, index) { + // Add `LazyWrapper` methods for `_.head` and `_.last`. + arrayEach(['head', 'last'], function(methodName, index) { var takeName = 'take' + (index ? 'Right' : ''); LazyWrapper.prototype[methodName] = function() { @@ -46519,8 +50665,8 @@ return jQuery; }; }); - // Add `LazyWrapper` methods for `_.initial` and `_.rest`. - arrayEach(['initial', 'rest'], function(methodName, index) { + // Add `LazyWrapper` methods for `_.initial` and `_.tail`. + arrayEach(['initial', 'tail'], function(methodName, index) { var dropName = 'drop' + (index ? '' : 'Right'); LazyWrapper.prototype[methodName] = function() { @@ -46528,29 +50674,36 @@ return jQuery; }; }); - // Add `LazyWrapper` methods for `_.pluck` and `_.where`. - arrayEach(['pluck', 'where'], function(methodName, index) { - var operationName = index ? 'filter' : 'map', - createCallback = index ? baseMatches : property; - - LazyWrapper.prototype[methodName] = function(value) { - return this[operationName](createCallback(value)); - }; - }); - LazyWrapper.prototype.compact = function() { return this.filter(identity); }; - LazyWrapper.prototype.reject = function(predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 1); + LazyWrapper.prototype.find = function(predicate) { + return this.filter(predicate).head(); + }; + + LazyWrapper.prototype.findLast = function(predicate) { + return this.reverse().find(predicate); + }; + + LazyWrapper.prototype.invokeMap = rest(function(path, args) { + if (typeof path == 'function') { + return new LazyWrapper(this); + } + return this.map(function(value) { + return baseInvoke(value, path, args); + }); + }); + + LazyWrapper.prototype.reject = function(predicate) { + predicate = getIteratee(predicate, 3); return this.filter(function(value) { return !predicate(value); }); }; LazyWrapper.prototype.slice = function(start, end) { - start = start == null ? 0 : (+start || 0); + start = toInteger(start); var result = this; if (result.__filtered__ && (start > 0 || end < 0)) { @@ -46562,74 +50715,70 @@ return jQuery; result = result.drop(start); } if (end !== undefined) { - end = (+end || 0); + end = toInteger(end); result = end < 0 ? result.dropRight(-end) : result.take(end - start); } return result; }; - LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) { - return this.reverse().takeWhile(predicate, thisArg).reverse(); + LazyWrapper.prototype.takeRightWhile = function(predicate) { + return this.reverse().takeWhile(predicate).reverse(); }; LazyWrapper.prototype.toArray = function() { - return this.take(POSITIVE_INFINITY); + return this.take(MAX_ARRAY_LENGTH); }; // Add `LazyWrapper` methods to `lodash.prototype`. baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), - retUnwrapped = /^(?:first|last)$/.test(methodName), - lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName]; + var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), + isTaker = /^(?:head|last)$/.test(methodName), + lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName], + retUnwrapped = isTaker || /^find/.test(methodName); if (!lodashFunc) { return; } lodash.prototype[methodName] = function() { - var args = retUnwrapped ? [1] : arguments, - chainAll = this.__chain__, - value = this.__wrapped__, - isHybrid = !!this.__actions__.length, + var value = this.__wrapped__, + args = isTaker ? [1] : arguments, isLazy = value instanceof LazyWrapper, iteratee = args[0], useLazy = isLazy || isArray(value); + var interceptor = function(value) { + var result = lodashFunc.apply(lodash, arrayPush([value], args)); + return (isTaker && chainAll) ? result[0] : result; + }; + if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { // Avoid lazy use if the iteratee has a "length" value other than `1`. isLazy = useLazy = false; } - var interceptor = function(value) { - return (retUnwrapped && chainAll) - ? lodashFunc(value, 1)[0] - : lodashFunc.apply(undefined, arrayPush([value], args)); - }; - - var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined }, + var chainAll = this.__chain__, + isHybrid = !!this.__actions__.length, + isUnwrapped = retUnwrapped && !chainAll, onlyLazy = isLazy && !isHybrid; - if (retUnwrapped && !chainAll) { - if (onlyLazy) { - value = value.clone(); - value.__actions__.push(action); - return func.call(value); - } - return lodashFunc.call(undefined, this.value())[0]; - } if (!retUnwrapped && useLazy) { value = onlyLazy ? value : new LazyWrapper(this); var result = func.apply(value, args); - result.__actions__.push(action); + result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); return new LodashWrapper(result, chainAll); } - return this.thru(interceptor); + if (isUnwrapped && onlyLazy) { + return func.apply(this, args); + } + result = this.thru(interceptor); + return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result; }; }); // Add `Array` and `String` methods to `lodash.prototype`. - arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { - var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName], + arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = arrayProto[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', - retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName); + retUnwrapped = /^(?:pop|shift)$/.test(methodName); lodash.prototype[methodName] = function() { var args = arguments; @@ -46646,14 +50795,17 @@ return jQuery; baseForOwn(LazyWrapper.prototype, function(func, methodName) { var lodashFunc = lodash[methodName]; if (lodashFunc) { - var key = lodashFunc.name, + var key = (lodashFunc.name + ''), names = realNames[key] || (realNames[key] = []); names.push({ 'name': methodName, 'func': lodashFunc }); } }); - realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; + realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ + 'name': 'wrapper', + 'func': undefined + }]; // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; @@ -46661,20 +50813,18 @@ return jQuery; LazyWrapper.prototype.value = lazyValue; // Add chaining functions to the `lodash` wrapper. + lodash.prototype.at = wrapperAt; lodash.prototype.chain = wrapperChain; lodash.prototype.commit = wrapperCommit; - lodash.prototype.concat = wrapperConcat; + lodash.prototype.flatMap = wrapperFlatMap; + lodash.prototype.next = wrapperNext; lodash.prototype.plant = wrapperPlant; lodash.prototype.reverse = wrapperReverse; - lodash.prototype.toString = wrapperToString; - lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; - - // Add function aliases to the `lodash` wrapper. - lodash.prototype.collect = lodash.prototype.map; - lodash.prototype.head = lodash.prototype.first; - lodash.prototype.select = lodash.prototype.filter; - lodash.prototype.tail = lodash.prototype.rest; + lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; + if (iteratorSymbol) { + lodash.prototype[iteratorSymbol] = wrapperToIterator; + } return lodash; } @@ -46683,14 +50833,13 @@ return jQuery; // Export lodash. var _ = runInContext(); + // Expose lodash on the free variable `window` or `self` when available. This + // prevents errors in cases where lodash is loaded by a script tag in the presence + // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details. + (freeWindow || freeSelf || {})._ = _; + // Some AMD build optimizers like r.js check for condition patterns like the following: if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose lodash to the global object when an AMD loader is present to avoid - // errors in cases where lodash is loaded by a script tag and not intended - // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for - // more details. - root._ = _; - // Define as an anonymous module so, through path mapping, it can be // referenced as the "underscore" module. define(function() { @@ -46699,62 +50848,184 @@ return jQuery; } // Check for `exports` after `define` in case a build optimizer adds an `exports` object. else if (freeExports && freeModule) { - // Export for Node.js or RingoJS. + // Export for Node.js. if (moduleExports) { (freeModule.exports = _)._ = _; } - // Export for Rhino with CommonJS support. - else { - freeExports._ = _; - } + // Export for CommonJS support. + freeExports._ = _; } else { - // Export for a browser or Rhino. + // Export to the global object. root._ = _; } }.call(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],"react-router":[function(require,module,exports){ +},{}],"react-dom":[function(require,module,exports){ +'use strict'; + +module.exports = require('react/lib/ReactDOM'); + +},{"react/lib/ReactDOM":98}],"react-router":[function(require,module,exports){ +/* components */ 'use strict'; -exports.DefaultRoute = require('./components/DefaultRoute'); -exports.Link = require('./components/Link'); -exports.NotFoundRoute = require('./components/NotFoundRoute'); -exports.Redirect = require('./components/Redirect'); -exports.Route = require('./components/Route'); -exports.ActiveHandler = require('./components/RouteHandler'); -exports.RouteHandler = exports.ActiveHandler; - -exports.HashLocation = require('./locations/HashLocation'); -exports.HistoryLocation = require('./locations/HistoryLocation'); -exports.RefreshLocation = require('./locations/RefreshLocation'); -exports.StaticLocation = require('./locations/StaticLocation'); -exports.TestLocation = require('./locations/TestLocation'); - -exports.ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior'); -exports.ScrollToTopBehavior = require('./behaviors/ScrollToTopBehavior'); - -exports.History = require('./History'); -exports.Navigation = require('./Navigation'); -exports.State = require('./State'); - -exports.createRoute = require('./Route').createRoute; -exports.createDefaultRoute = require('./Route').createDefaultRoute; -exports.createNotFoundRoute = require('./Route').createNotFoundRoute; -exports.createRedirect = require('./Route').createRedirect; -exports.createRoutesFromReactChildren = require('./createRoutesFromReactChildren'); - -exports.create = require('./createRouter'); -exports.run = require('./runRouter'); -},{"./History":5,"./Navigation":7,"./Route":11,"./State":13,"./behaviors/ImitateBrowserBehavior":16,"./behaviors/ScrollToTopBehavior":17,"./components/DefaultRoute":19,"./components/Link":20,"./components/NotFoundRoute":21,"./components/Redirect":22,"./components/Route":23,"./components/RouteHandler":24,"./createRouter":25,"./createRoutesFromReactChildren":26,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./locations/TestLocation":33,"./runRouter":34}],"react/addons":[function(require,module,exports){ +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _Router2 = require('./Router'); + +var _Router3 = _interopRequireDefault(_Router2); + +exports.Router = _Router3['default']; + +var _Link2 = require('./Link'); + +var _Link3 = _interopRequireDefault(_Link2); + +exports.Link = _Link3['default']; + +var _IndexLink2 = require('./IndexLink'); + +var _IndexLink3 = _interopRequireDefault(_IndexLink2); + +exports.IndexLink = _IndexLink3['default']; + +/* components (configuration) */ + +var _IndexRedirect2 = require('./IndexRedirect'); + +var _IndexRedirect3 = _interopRequireDefault(_IndexRedirect2); + +exports.IndexRedirect = _IndexRedirect3['default']; + +var _IndexRoute2 = require('./IndexRoute'); + +var _IndexRoute3 = _interopRequireDefault(_IndexRoute2); + +exports.IndexRoute = _IndexRoute3['default']; + +var _Redirect2 = require('./Redirect'); + +var _Redirect3 = _interopRequireDefault(_Redirect2); + +exports.Redirect = _Redirect3['default']; + +var _Route2 = require('./Route'); + +var _Route3 = _interopRequireDefault(_Route2); + +exports.Route = _Route3['default']; + +/* mixins */ + +var _History2 = require('./History'); + +var _History3 = _interopRequireDefault(_History2); + +exports.History = _History3['default']; + +var _Lifecycle2 = require('./Lifecycle'); + +var _Lifecycle3 = _interopRequireDefault(_Lifecycle2); + +exports.Lifecycle = _Lifecycle3['default']; + +var _RouteContext2 = require('./RouteContext'); + +var _RouteContext3 = _interopRequireDefault(_RouteContext2); + +exports.RouteContext = _RouteContext3['default']; + +/* utils */ + +var _useRoutes2 = require('./useRoutes'); + +var _useRoutes3 = _interopRequireDefault(_useRoutes2); + +exports.useRoutes = _useRoutes3['default']; + +var _RouteUtils = require('./RouteUtils'); + +exports.createRoutes = _RouteUtils.createRoutes; + +var _RouterContext2 = require('./RouterContext'); + +var _RouterContext3 = _interopRequireDefault(_RouterContext2); + +exports.RouterContext = _RouterContext3['default']; + +var _RoutingContext2 = require('./RoutingContext'); + +var _RoutingContext3 = _interopRequireDefault(_RoutingContext2); + +exports.RoutingContext = _RoutingContext3['default']; + +var _PropTypes2 = require('./PropTypes'); + +var _PropTypes3 = _interopRequireDefault(_PropTypes2); + +exports.PropTypes = _PropTypes3['default']; + +var _match2 = require('./match'); + +var _match3 = _interopRequireDefault(_match2); + +exports.match = _match3['default']; + +var _useRouterHistory2 = require('./useRouterHistory'); + +var _useRouterHistory3 = _interopRequireDefault(_useRouterHistory2); + +exports.useRouterHistory = _useRouterHistory3['default']; + +var _PatternUtils = require('./PatternUtils'); + +exports.formatPattern = _PatternUtils.formatPattern; + +/* histories */ + +var _browserHistory2 = require('./browserHistory'); + +var _browserHistory3 = _interopRequireDefault(_browserHistory2); + +exports.browserHistory = _browserHistory3['default']; + +var _hashHistory2 = require('./hashHistory'); + +var _hashHistory3 = _interopRequireDefault(_hashHistory2); + +exports.hashHistory = _hashHistory3['default']; + +var _createMemoryHistory2 = require('./createMemoryHistory'); + +var _createMemoryHistory3 = _interopRequireDefault(_createMemoryHistory2); + +exports.createMemoryHistory = _createMemoryHistory3['default']; +},{"./History":5,"./IndexLink":6,"./IndexRedirect":7,"./IndexRoute":8,"./Lifecycle":9,"./Link":10,"./PatternUtils":11,"./PropTypes":12,"./Redirect":13,"./Route":14,"./RouteContext":15,"./RouteUtils":16,"./Router":17,"./RouterContext":18,"./RoutingContext":20,"./browserHistory":22,"./createMemoryHistory":24,"./hashHistory":30,"./match":32,"./useRouterHistory":35,"./useRoutes":36}],"react/addons":[function(require,module,exports){ +'use strict'; + +var warning = require('fbjs/lib/warning'); +warning( + false, + // Require examples in this string must be split to prevent React's + // build tools from mistaking them for real requires. + // Otherwise the build tools will attempt to build a 'react-addons-{addon}' module. + 'require' + "('react/addons') is deprecated. " + + 'Access using require' + "('react-addons-{addon}') instead." +); + module.exports = require('./lib/ReactWithAddons'); -},{"./lib/ReactWithAddons":141}],"react":[function(require,module,exports){ +},{"./lib/ReactWithAddons":156,"fbjs/lib/warning":232}],"react":[function(require,module,exports){ +'use strict'; + module.exports = require('./lib/React'); -},{"./lib/React":71}]},{},[]) +},{"./lib/React":84}]},{},[]) //# sourceMappingURL=vendor.js.map diff --git a/mitmproxy/web/templates/index.html b/mitmproxy/web/templates/index.html index 5f2c6d5e..165d7d3d 100644 --- a/mitmproxy/web/templates/index.html +++ b/mitmproxy/web/templates/index.html @@ -10,5 +10,6 @@ <script src="/static/app.js"></script> </head> <body> +<div id="mitmproxy"></div> </body> </html>
\ No newline at end of file diff --git a/web/.babelrc b/web/.babelrc new file mode 100644 index 00000000..facd1809 --- /dev/null +++ b/web/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015", "react"] +}
\ No newline at end of file diff --git a/web/.bowerrc b/web/.bowerrc deleted file mode 100644 index 5e6701af..00000000 --- a/web/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory" : "bower_components" -}
\ No newline at end of file diff --git a/web/.eslintrc b/web/.eslintrc deleted file mode 100644 index df187739..00000000 --- a/web/.eslintrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "ecmaFeatures": { - "jsx": true - }, - "env": { - "es6": true - } -}
\ No newline at end of file diff --git a/web/.eslintrc.yml b/web/.eslintrc.yml new file mode 100644 index 00000000..319fa67c --- /dev/null +++ b/web/.eslintrc.yml @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + } +}
\ No newline at end of file diff --git a/web/gulpfile.js b/web/gulpfile.js index 83893c91..58f74098 100644 --- a/web/gulpfile.js +++ b/web/gulpfile.js @@ -7,8 +7,6 @@ var conf = require('./conf.js'); var babelify = require('babelify'); var browserify = require('browserify'); var gulp = require("gulp"); -var concat = require('gulp-concat'); -var connect = require('gulp-connect'); var eslint = require('gulp-eslint'); var less = require("gulp-less"); var livereload = require("gulp-livereload"); @@ -16,18 +14,13 @@ var minifyCSS = require('gulp-minify-css'); var notify = require("gulp-notify"); var peg = require("gulp-peg"); var plumber = require("gulp-plumber"); -var react = require("gulp-react"); var rename = require("gulp-rename"); -var replace = require('gulp-replace'); var sourcemaps = require('gulp-sourcemaps'); var gutil = require("gulp-util"); var _ = require('lodash'); -var map = require("map-stream"); -var reactify = require('reactify'); var uglifyify = require('uglifyify'); var buffer = require('vinyl-buffer'); var source = require('vinyl-source-stream'); -var transform = require('vinyl-transform'); var watchify = require('watchify'); var vendor_packages = _.difference( @@ -116,6 +109,7 @@ function buildScript(bundler, filename, dev) { // listen for an update and run rebundle bundler.on('update', rebundle); bundler.on('log', gutil.log); + bundler.on('error', gutil.log); // run it once the first time buildScript is called return rebundle(); @@ -150,7 +144,7 @@ function app_stream(dev) { for (var vp of vendor_packages) { bundler.external(vp); } - bundler = bundler.transform(babelify).transform(reactify); + bundler = bundler.transform(babelify); return buildScript(bundler, "app.js", dev); } gulp.task('scripts-app-dev', function () { diff --git a/web/package.json b/web/package.json index 5bcbdd87..a1b42d01 100644 --- a/web/package.json +++ b/web/package.json @@ -15,41 +15,36 @@ "testDirectoryName": "tests" }, "dependencies": { - "bootstrap": "^3.3.4", + "bootstrap": "^3.3.6", "flux": "^2.1.1", - "jquery": "^2.1.4", - "lodash": "^3.10.1", - "react": "^0.13.3", - "react-router": "^0.13.2" + "jquery": "^2.2.1", + "lodash": "^4.5.1", + "react": "^0.14.7", + "react-dom": "^0.14.7", + "react-router": "^2.0.0" }, "devDependencies": { - "babelify": "^6.3.0", - "browserify": "^11.2.0", - "eslint": "^1.5.1", - "gulp": "^3.9.0", - "gulp-concat": "^2.6.0", - "gulp-connect": "^2.2.0", - "gulp-eslint": "^1.0.0", - "gulp-jshint": "^1.11.2", - "gulp-less": "^3.0.3", + "babel-core": "^6.5.2", + "babel-preset-es2015": "^6.5.0", + "babel-preset-react": "^6.5.0", + "babelify": "^7.2.0", + "browserify": "^13.0.0", + "eslint": "^2.2.0", + "gulp": "^3.9.1", + "gulp-eslint": "^2.0.0", + "gulp-less": "^3.0.5", "gulp-livereload": "^3.8.1", - "gulp-minify-css": "^1.2.1", + "gulp-minify-css": "^1.2.4", "gulp-notify": "^2.2.0", - "gulp-peg": "^0.1.2", - "gulp-plumber": "^1.0.1", - "gulp-react": "^3.0.1", + "gulp-peg": "^0.2.0", + "gulp-plumber": "^1.1.0", "gulp-rename": "^1.2.2", - "gulp-replace": "^0.5.4", "gulp-sourcemaps": "^1.6.0", - "gulp-uglify": "^1.4.1", - "gulp-util": "^3.0.6", - "lodash": "^3.10.1", - "map-stream": "0.0.6", - "reactify": "^1.1.1", + "gulp-util": "^3.0.7", + "lodash": "^4.5.1", "uglifyify": "^3.0.1", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", - "vinyl-transform": "^1.0.0", - "watchify": "^3.4.0" + "watchify": "^3.7.0" } } diff --git a/web/src/css/layout.less b/web/src/css/layout.less index 1075d6c9..ed4adb69 100644 --- a/web/src/css/layout.less +++ b/web/src/css/layout.less @@ -1,4 +1,4 @@ -html, body, #container { +html, body, #container, #mitmproxy { height: 100%; margin: 0; overflow: hidden; diff --git a/web/src/js/app.js b/web/src/js/app.js index 9fb868b8..e21fa499 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -1,9 +1,9 @@ -var React = require("react"); -var ReactRouter = require("react-router"); -var $ = require("jquery"); -var Connection = require("./connection"); -var proxyapp = require("./components/proxyapp.js"); -var EventLogActions = require("./actions.js").EventLogActions; +import React from "react" +import { render } from 'react-dom' +import $ from "jquery" +import Connection from "./connection" +import {app} from "./components/proxyapp.js" +import { EventLogActions } from "./actions.js" $(function () { window.ws = new Connection("/updates"); @@ -12,8 +12,6 @@ $(function () { EventLogActions.add_event(msg); }; - ReactRouter.run(proxyapp.routes, function (Handler, state) { - React.render(<Handler/>, document.body); - }); + render(app, document.getElementById("mitmproxy")); }); diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js index 965ae9a7..03b2ef8c 100644 --- a/web/src/js/components/common.js +++ b/web/src/js/components/common.js @@ -1,11 +1,12 @@ var React = require("react"); +var ReactDOM = require("react-dom"); var ReactRouter = require("react-router"); var _ = require("lodash"); // http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) -var AutoScrollMixin = { +export var AutoScrollMixin = { componentWillUpdate: function () { - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); this._shouldScrollBottom = ( node.scrollTop !== 0 && node.scrollTop + node.clientHeight === node.scrollHeight @@ -13,23 +14,23 @@ var AutoScrollMixin = { }, componentDidUpdate: function () { if (this._shouldScrollBottom) { - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); node.scrollTop = node.scrollHeight; } }, }; -var StickyHeadMixin = { +export var StickyHeadMixin = { adjustHead: function () { // Abusing CSS transforms to set the element // referenced as head into some kind of position:sticky. - var head = this.refs.head.getDOMNode(); - head.style.transform = "translate(0," + this.getDOMNode().scrollTop + "px)"; + var head = this.refs.head; + head.style.transform = "translate(0," + ReactDOM.findDOMNode(this).scrollTop + "px)"; } }; -var SettingsState = { +export var SettingsState = { contextTypes: { settingsStore: React.PropTypes.object.isRequired }, @@ -52,58 +53,62 @@ var SettingsState = { }; -var ChildFocus = { +export var ChildFocus = { contextTypes: { returnFocus: React.PropTypes.func }, returnFocus: function(){ - React.findDOMNode(this).blur(); + ReactDOM.findDOMNode(this).blur(); window.getSelection().removeAllRanges(); this.context.returnFocus(); } }; -var Navigation = _.extend({}, ReactRouter.Navigation, { +export var Navigation = { + contextTypes: { + routerFoo: React.PropTypes.object, + router: React.PropTypes.object.isRequired + }, setQuery: function (dict) { - var q = this.context.router.getCurrentQuery(); + var q = this.context.routerFoo.location.query; for (var i in dict) { if (dict.hasOwnProperty(i)) { q[i] = dict[i] || undefined; //falsey values shall be removed. } } - this.replaceWith(this.context.router.getCurrentPath(), this.context.router.getCurrentParams(), q); + this.replaceWith(undefined, q); }, - replaceWith: function (routeNameOrPath, params, query) { - if (routeNameOrPath === undefined) { - routeNameOrPath = this.context.router.getCurrentPath(); - } - if (params === undefined) { - params = this.context.router.getCurrentParams(); + replaceWith: function (pathname, query) { + if (pathname === undefined) { + pathname = this.context.routerFoo.location.pathname; } if (query === undefined) { - query = this.context.router.getCurrentQuery(); + query = this.context.routerFoo.query; } - - this.context.router.replaceWith(routeNameOrPath, params, query); + console.log({ pathname, query }); + this.context.router.replace({ pathname, query }); } -}); +}; // react-router is fairly good at changing its API regularly. // We keep the old method for now - if it should turn out that their changes are permanent, // we may remove this mixin and access react-router directly again. -var RouterState = _.extend({}, ReactRouter.State, { +export var RouterState = { + contextTypes: { + routerFoo: React.PropTypes.object, + }, getQuery: function () { // For whatever reason, react-router always returns the same object, which makes comparing // the current props with nextProps impossible. As a workaround, we just clone the query object. - return _.clone(this.context.router.getCurrentQuery()); + return _.clone(this.context.routerFoo.location.query); }, getParams: function () { - return _.clone(this.context.router.getCurrentParams()); + return _.clone(this.context.routerFoo.params); } -}); +}; -var Splitter = React.createClass({ +export var Splitter = React.createClass({ getDefaultProps: function () { return { axis: "x" @@ -127,7 +132,7 @@ var Splitter = React.createClass({ window.addEventListener("dragend", this.onDragEnd); }, onDragEnd: function () { - this.getDOMNode().style.transform = ""; + ReactDOM.findDOMNode(this).style.transform = ""; window.removeEventListener("dragend", this.onDragEnd); window.removeEventListener("mouseup", this.onMouseUp); window.removeEventListener("mousemove", this.onMouseMove); @@ -135,7 +140,7 @@ var Splitter = React.createClass({ onMouseUp: function (e) { this.onDragEnd(); - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); var prev = node.previousElementSibling; var next = node.nextElementSibling; @@ -163,7 +168,7 @@ var Splitter = React.createClass({ } else { dY = e.pageY - this.state.startY; } - this.getDOMNode().style.transform = "translate(" + dX + "px," + dY + "px)"; + ReactDOM.findDOMNode(this).style.transform = "translate(" + dX + "px," + dY + "px)"; }, onResize: function () { // Trigger a global resize event. This notifies components that employ virtual scrolling @@ -176,7 +181,7 @@ var Splitter = React.createClass({ if (!this.state.applied) { return; } - var node = this.getDOMNode(); + var node = ReactDOM.findDOMNode(this); var prev = node.previousElementSibling; var next = node.nextElementSibling; @@ -206,14 +211,4 @@ var Splitter = React.createClass({ </div> ); } -}); - -module.exports = { - ChildFocus: ChildFocus, - RouterState: RouterState, - Navigation: Navigation, - StickyHeadMixin: StickyHeadMixin, - AutoScrollMixin: AutoScrollMixin, - Splitter: Splitter, - SettingsState: SettingsState -};
\ No newline at end of file +});
\ No newline at end of file diff --git a/web/src/js/components/editor.js b/web/src/js/components/editor.js index f2d44566..62c5310c 100644 --- a/web/src/js/components/editor.js +++ b/web/src/js/components/editor.js @@ -1,4 +1,5 @@ var React = require("react"); +var ReactDOM = require('react-dom'); var common = require("./common.js"); var utils = require("../utils.js"); @@ -98,12 +99,12 @@ var EditorBase = React.createClass({ range = document.caretRangeFromPoint(e.clientX, e.clientY); } else { range = document.createRange(); - range.selectNodeContents(React.findDOMNode(this)); + range.selectNodeContents(ReactDOM.findDOMNode(this)); } this._ignore_events = true; this.setState({editable: true}, function () { - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); node.blur(); node.focus(); this._ignore_events = false; @@ -117,7 +118,7 @@ var EditorBase = React.createClass({ // a stop would cause a blur as a side-effect. // but a blur event must trigger a stop as well. // to fix this, make stop = blur and do the actual stop in the onBlur handler. - React.findDOMNode(this).blur(); + ReactDOM.findDOMNode(this).blur(); this.props.onStop && this.props.onStop(); }, _stop: function (e) { @@ -126,14 +127,14 @@ var EditorBase = React.createClass({ } console.log("_stop", _.extend({}, e)); window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); var content = this.props.nodeToContent(node); this.setState({editable: false}); this.props.onDone(content); this.props.onBlur && this.props.onBlur(e); }, reset: function () { - React.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); + ReactDOM.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); }, onKeyDown: function (e) { e.stopPropagation(); @@ -154,7 +155,7 @@ var EditorBase = React.createClass({ } }, onInput: function () { - var node = React.findDOMNode(this); + var node = ReactDOM.findDOMNode(this); var content = this.props.nodeToContent(node); this.props.onInput && this.props.onInput(content); } @@ -228,7 +229,7 @@ var ValueEditor = React.createClass({ />; }, focus: function () { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, onStop: function () { this.returnFocus(); diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js index fea7b247..9dcd2c38 100644 --- a/web/src/js/components/eventlog.js +++ b/web/src/js/components/eventlog.js @@ -1,7 +1,7 @@ var React = require("react"); var common = require("./common.js"); var Query = require("../actions.js").Query; -var VirtualScrollMixin = require("./virtualscroll.js"); +import { VirtualScrollMixin } from "./virtualscroll.js" var views = require("../store/view.js"); var _ = require("lodash"); diff --git a/web/src/js/components/flowtable.js b/web/src/js/components/flowtable.js index 609034f6..b27ed30d 100644 --- a/web/src/js/components/flowtable.js +++ b/web/src/js/components/flowtable.js @@ -1,9 +1,10 @@ var React = require("react"); +var ReactDOM = require('react-dom'); var common = require("./common.js"); var utils = require("../utils.js"); var _ = require("lodash"); -var VirtualScrollMixin = require("./virtualscroll.js"); +import { VirtualScrollMixin } from "./virtualscroll.js" var flowtable_columns = require("./flowtable-columns.js"); var FlowRow = React.createClass({ @@ -143,7 +144,7 @@ var FlowTable = React.createClass({ scrollIntoView: function (flow) { this.scrollRowIntoView( this.context.view.index(flow), - this.refs.body.getDOMNode().offsetTop + ReactDOM.findDOMNode(this.refs.body).offsetTop ); }, renderRow: function (flow) { diff --git a/web/src/js/components/flowview/index.js b/web/src/js/components/flowview/index.js index 739a46dc..91b17dd2 100644 --- a/web/src/js/components/flowview/index.js +++ b/web/src/js/components/flowview/index.js @@ -40,13 +40,7 @@ var FlowView = React.createClass({ this.selectTab(tabs[nextIndex]); }, selectTab: function (panel) { - this.replaceWith( - "flow", - { - flowId: this.getParams().flowId, - detailTab: panel - } - ); + this.replaceWith(`/flows/${this.getParams().flowId}/${panel}`); }, getActive: function(){ return this.getParams().detailTab; @@ -93,7 +87,7 @@ var FlowView = React.createClass({ var tabs = this.getTabs(flow); var active = this.getActive(); - if (!_.contains(tabs, active)) { + if (tabs.indexOf(active) < 0) { if (active === "response" && flow.error) { active = "error"; } else if (active === "error" && flow.response) { diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index 7ac95d85..c11ee46f 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -1,4 +1,5 @@ var React = require("react"); +var ReactDOM = require('react-dom'); var _ = require("lodash"); var common = require("../common.js"); @@ -98,7 +99,7 @@ var HeaderEditor = React.createClass({ return <ValueEditor ref="input" {...this.props} onKeyDown={this.onKeyDown} inline/>; }, focus: function () { - this.getDOMNode().focus(); + ReactDOM.findDOMNode(this).focus(); }, onKeyDown: function (e) { switch (e.keyCode) { diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 998a41df..f2cc3fc5 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -1,4 +1,5 @@ var React = require("react"); +var ReactDOM = require('react-dom'); var $ = require("jquery"); var Filt = require("../filt/filt.js"); @@ -76,26 +77,24 @@ var FilterInput = React.createClass({ }, isValid: function (filt) { try { - Filt.parse(filt || this.state.value); + var str = filt || this.state.value; + if(str){ + Filt.parse(filt || this.state.value); + } return true; } catch (e) { return false; } }, getDesc: function () { - var desc; - try { - desc = Filt.parse(this.state.value).desc; - } catch (e) { - desc = "" + e; - } - if (desc !== "true") { - return desc; - } else { - return ( - <FilterDocs/> - ); + if(this.state.value) { + try { + return Filt.parse(this.state.value).desc; + } catch (e) { + return "" + e; + } } + return <FilterDocs/>; }, onFocus: function () { this.setState({focus: true}); @@ -118,11 +117,11 @@ var FilterInput = React.createClass({ e.stopPropagation(); }, blur: function () { - this.refs.input.getDOMNode().blur(); + ReactDOM.findDOMNode(this.refs.input).blur(); this.returnFocus(); }, select: function () { - this.refs.input.getDOMNode().select(); + ReactDOM.findDOMNode(this.refs.input).select(); }, render: function () { var isValid = this.isValid(); diff --git a/web/src/js/components/mainview.js b/web/src/js/components/mainview.js index 9ff51dfa..86666e39 100644 --- a/web/src/js/components/mainview.js +++ b/web/src/js/components/mainview.js @@ -42,7 +42,8 @@ var MainView = React.createClass({ }, getViewFilt: function () { try { - var filt = Filt.parse(this.getQuery()[Query.SEARCH] || ""); + var filtStr = this.getQuery()[Query.SEARCH]; + var filt = filtStr ? Filt.parse(filtStr) : function(){return true}; var highlightStr = this.getQuery()[Query.HIGHLIGHT]; var highlight = highlightStr ? Filt.parse(highlightStr) : false; } catch (e) { @@ -90,16 +91,11 @@ var MainView = React.createClass({ }, selectFlow: function (flow) { if (flow) { - this.replaceWith( - "flow", - { - flowId: flow.id, - detailTab: this.getParams().detailTab || "request" - } - ); + var tab = this.getParams().detailTab || "request"; + this.replaceWith(`/flows/${flow.id}/${tab}`); this.refs.flowTable.scrollIntoView(flow); } else { - this.replaceWith("flows", {}); + this.replaceWith("/flows"); } }, selectFlowRelative: function (shift) { diff --git a/web/src/js/components/prompt.js b/web/src/js/components/prompt.js index 121a1170..9695bd94 100644 --- a/web/src/js/components/prompt.js +++ b/web/src/js/components/prompt.js @@ -1,4 +1,5 @@ var React = require("react"); +var ReactDOM = require('react-dom'); var _ = require("lodash"); var utils = require("../utils.js"); @@ -12,7 +13,7 @@ var Prompt = React.createClass({ prompt: React.PropTypes.string }, componentDidMount: function () { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, onKeyDown: function (e) { e.stopPropagation(); diff --git a/web/src/js/components/proxyapp.js b/web/src/js/components/proxyapp.js index e766d6e6..9c2d8714 100644 --- a/web/src/js/components/proxyapp.js +++ b/web/src/js/components/proxyapp.js @@ -1,4 +1,5 @@ var React = require("react"); +var ReactDOM = require("react-dom"); var ReactRouter = require("react-router"); var _ = require("lodash"); @@ -27,6 +28,7 @@ var ProxyAppMain = React.createClass({ flowStore: React.PropTypes.object.isRequired, eventStore: React.PropTypes.object.isRequired, returnFocus: React.PropTypes.func.isRequired, + routerFoo: React.PropTypes.object, }, componentDidMount: function () { this.focus(); @@ -37,6 +39,10 @@ var ProxyAppMain = React.createClass({ flowStore: this.state.flowStore, eventStore: this.state.eventStore, returnFocus: this.focus, + routerFoo: { + location: this.props.location, + params: this.props.params + } }; }, getInitialState: function () { @@ -53,10 +59,10 @@ var ProxyAppMain = React.createClass({ }; }, focus: function () { - React.findDOMNode(this).focus(); + ReactDOM.findDOMNode(this).focus(); }, getMainComponent: function () { - return this.refs.view.refs.__routeHandler__; + return this.refs.view; }, onKeydown: function (e) { @@ -88,7 +94,7 @@ var ProxyAppMain = React.createClass({ }, render: function () { var eventlog; - if (this.getQuery()[Query.SHOW_EVENTLOG]) { + if (this.props.location.query[Query.SHOW_EVENTLOG]) { eventlog = [ <common.Splitter key="splitter" axis="y"/>, <EventLog key="eventlog"/> @@ -96,10 +102,14 @@ var ProxyAppMain = React.createClass({ } else { eventlog = null; } + var children = React.cloneElement( + this.props.children, + { ref: "view", query: this.props.location.query } + ); return ( <div id="container" tabIndex="0" onKeyDown={this.onKeydown}> <header.Header ref="header"/> - <RouteHandler ref="view" query={this.getQuery()}/> + {children} {eventlog} <Footer/> </div> @@ -108,22 +118,15 @@ var ProxyAppMain = React.createClass({ }); -var Route = ReactRouter.Route; -var RouteHandler = ReactRouter.RouteHandler; -var Redirect = ReactRouter.Redirect; -var DefaultRoute = ReactRouter.DefaultRoute; -var NotFoundRoute = ReactRouter.NotFoundRoute; - +import { Route, Router, hashHistory, Redirect} from "react-router"; -var routes = ( - <Route path="/" handler={ProxyAppMain}> - <Route name="flows" path="flows" handler={MainView}/> - <Route name="flow" path="flows/:flowId/:detailTab" handler={MainView}/> - <Route name="reports" handler={Reports}/> - <Redirect path="/" to="flows" /> +export var app = ( +<Router history={hashHistory}> + <Redirect from="/" to="/flows" /> + <Route path="/" component={ProxyAppMain}> + <Route path="flows" component={MainView}/> + <Route path="flows/:flowId/:detailTab" component={MainView}/> + <Route path="reports" component={Reports}/> </Route> -); - -module.exports = { - routes: routes -};
\ No newline at end of file +</Router> +);
\ No newline at end of file diff --git a/web/src/js/components/virtualscroll.js b/web/src/js/components/virtualscroll.js index 956e1a0b..f462fdcc 100644 --- a/web/src/js/components/virtualscroll.js +++ b/web/src/js/components/virtualscroll.js @@ -1,6 +1,7 @@ -var React = require("react"); +import React from "react"; +import ReactDOM from "react-dom"; -var VirtualScrollMixin = { +export var VirtualScrollMixin = { getInitialState: function () { return { start: 0, @@ -43,7 +44,7 @@ var VirtualScrollMixin = { window.removeEventListener('resize', this.onScroll); }, onScroll: function () { - var viewport = this.getDOMNode(); + var viewport = ReactDOM.findDOMNode(this); var top = viewport.scrollTop; var height = viewport.offsetHeight; var start = Math.floor(top / this.props.rowHeight); @@ -69,7 +70,7 @@ var VirtualScrollMixin = { var row_top = (index * this.props.rowHeight) + head_height; var row_bottom = row_top + this.props.rowHeight; - var viewport = this.getDOMNode(); + var viewport = ReactDOM.findDOMNode(this); var viewport_top = viewport.scrollTop; var viewport_bottom = viewport_top + viewport.offsetHeight; @@ -81,5 +82,3 @@ var VirtualScrollMixin = { } }, }; - -module.exports = VirtualScrollMixin;
\ No newline at end of file diff --git a/web/src/js/filt/filt.js b/web/src/js/filt/filt.js index 45b42f3a..6a0bbab7 100644 --- a/web/src/js/filt/filt.js +++ b/web/src/js/filt/filt.js @@ -1,8 +1,10 @@ module.exports = (function() { + "use strict"; + /* - * Generated by PEG.js 0.8.0. + * Generated by PEG.js 0.9.0. * - * http://pegjs.majda.cz/ + * http://pegjs.org/ */ function peg$subclass(child, parent) { @@ -11,21 +13,23 @@ module.exports = (function() { child.prototype = new ctor(); } - function SyntaxError(message, expected, found, offset, line, column) { + function peg$SyntaxError(message, expected, found, location) { this.message = message; this.expected = expected; this.found = found; - this.offset = offset; - this.line = line; - this.column = column; - + this.location = location; this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError); + } } - peg$subclass(SyntaxError, Error); + peg$subclass(peg$SyntaxError, Error); - function parse(input) { + function peg$parse(input) { var options = arguments.length > 1 ? arguments[1] : {}, + parser = this, peg$FAILED = {}, @@ -33,117 +37,111 @@ module.exports = (function() { peg$startRuleFunction = peg$parsestart, peg$c0 = { type: "other", description: "filter expression" }, - peg$c1 = peg$FAILED, - peg$c2 = function(orExpr) { return orExpr; }, - peg$c3 = [], - peg$c4 = function() {return trueFilter; }, - peg$c5 = { type: "other", description: "whitespace" }, - peg$c6 = /^[ \t\n\r]/, - peg$c7 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, - peg$c8 = { type: "other", description: "control character" }, - peg$c9 = /^[|&!()~"]/, - peg$c10 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, - peg$c11 = { type: "other", description: "optional whitespace" }, - peg$c12 = "|", - peg$c13 = { type: "literal", value: "|", description: "\"|\"" }, - peg$c14 = function(first, second) { return or(first, second); }, - peg$c15 = "&", - peg$c16 = { type: "literal", value: "&", description: "\"&\"" }, - peg$c17 = function(first, second) { return and(first, second); }, - peg$c18 = "!", - peg$c19 = { type: "literal", value: "!", description: "\"!\"" }, - peg$c20 = function(expr) { return not(expr); }, - peg$c21 = "(", - peg$c22 = { type: "literal", value: "(", description: "\"(\"" }, - peg$c23 = ")", - peg$c24 = { type: "literal", value: ")", description: "\")\"" }, - peg$c25 = function(expr) { return binding(expr); }, - peg$c26 = "~a", - peg$c27 = { type: "literal", value: "~a", description: "\"~a\"" }, - peg$c28 = function() { return assetFilter; }, - peg$c29 = "~e", - peg$c30 = { type: "literal", value: "~e", description: "\"~e\"" }, - peg$c31 = function() { return errorFilter; }, - peg$c32 = "~q", - peg$c33 = { type: "literal", value: "~q", description: "\"~q\"" }, - peg$c34 = function() { return noResponseFilter; }, - peg$c35 = "~s", - peg$c36 = { type: "literal", value: "~s", description: "\"~s\"" }, - peg$c37 = function() { return responseFilter; }, - peg$c38 = "true", - peg$c39 = { type: "literal", value: "true", description: "\"true\"" }, - peg$c40 = function() { return trueFilter; }, - peg$c41 = "false", - peg$c42 = { type: "literal", value: "false", description: "\"false\"" }, - peg$c43 = function() { return falseFilter; }, - peg$c44 = "~c", - peg$c45 = { type: "literal", value: "~c", description: "\"~c\"" }, - peg$c46 = function(s) { return responseCode(s); }, - peg$c47 = "~d", - peg$c48 = { type: "literal", value: "~d", description: "\"~d\"" }, - peg$c49 = function(s) { return domain(s); }, - peg$c50 = "~h", - peg$c51 = { type: "literal", value: "~h", description: "\"~h\"" }, - peg$c52 = function(s) { return header(s); }, - peg$c53 = "~hq", - peg$c54 = { type: "literal", value: "~hq", description: "\"~hq\"" }, - peg$c55 = function(s) { return requestHeader(s); }, - peg$c56 = "~hs", - peg$c57 = { type: "literal", value: "~hs", description: "\"~hs\"" }, - peg$c58 = function(s) { return responseHeader(s); }, - peg$c59 = "~m", - peg$c60 = { type: "literal", value: "~m", description: "\"~m\"" }, - peg$c61 = function(s) { return method(s); }, - peg$c62 = "~t", - peg$c63 = { type: "literal", value: "~t", description: "\"~t\"" }, - peg$c64 = function(s) { return contentType(s); }, - peg$c65 = "~tq", - peg$c66 = { type: "literal", value: "~tq", description: "\"~tq\"" }, - peg$c67 = function(s) { return requestContentType(s); }, - peg$c68 = "~ts", - peg$c69 = { type: "literal", value: "~ts", description: "\"~ts\"" }, - peg$c70 = function(s) { return responseContentType(s); }, - peg$c71 = "~u", - peg$c72 = { type: "literal", value: "~u", description: "\"~u\"" }, - peg$c73 = function(s) { return url(s); }, - peg$c74 = { type: "other", description: "integer" }, - peg$c75 = null, - peg$c76 = /^['"]/, - peg$c77 = { type: "class", value: "['\"]", description: "['\"]" }, - peg$c78 = /^[0-9]/, - peg$c79 = { type: "class", value: "[0-9]", description: "[0-9]" }, - peg$c80 = function(digits) { return parseInt(digits.join(""), 10); }, - peg$c81 = { type: "other", description: "string" }, - peg$c82 = "\"", - peg$c83 = { type: "literal", value: "\"", description: "\"\\\"\"" }, - peg$c84 = function(chars) { return chars.join(""); }, - peg$c85 = "'", - peg$c86 = { type: "literal", value: "'", description: "\"'\"" }, - peg$c87 = void 0, - peg$c88 = /^["\\]/, - peg$c89 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, - peg$c90 = { type: "any", description: "any character" }, - peg$c91 = function(char) { return char; }, - peg$c92 = "\\", - peg$c93 = { type: "literal", value: "\\", description: "\"\\\\\"" }, - peg$c94 = /^['\\]/, - peg$c95 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, - peg$c96 = /^['"\\]/, - peg$c97 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, - peg$c98 = "n", - peg$c99 = { type: "literal", value: "n", description: "\"n\"" }, - peg$c100 = function() { return "\n"; }, - peg$c101 = "r", - peg$c102 = { type: "literal", value: "r", description: "\"r\"" }, - peg$c103 = function() { return "\r"; }, - peg$c104 = "t", - peg$c105 = { type: "literal", value: "t", description: "\"t\"" }, - peg$c106 = function() { return "\t"; }, + peg$c1 = function(orExpr) { return orExpr; }, + peg$c2 = { type: "other", description: "whitespace" }, + peg$c3 = /^[ \t\n\r]/, + peg$c4 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, + peg$c5 = { type: "other", description: "control character" }, + peg$c6 = /^[|&!()~"]/, + peg$c7 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, + peg$c8 = { type: "other", description: "optional whitespace" }, + peg$c9 = "|", + peg$c10 = { type: "literal", value: "|", description: "\"|\"" }, + peg$c11 = function(first, second) { return or(first, second); }, + peg$c12 = "&", + peg$c13 = { type: "literal", value: "&", description: "\"&\"" }, + peg$c14 = function(first, second) { return and(first, second); }, + peg$c15 = "!", + peg$c16 = { type: "literal", value: "!", description: "\"!\"" }, + peg$c17 = function(expr) { return not(expr); }, + peg$c18 = "(", + peg$c19 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c20 = ")", + peg$c21 = { type: "literal", value: ")", description: "\")\"" }, + peg$c22 = function(expr) { return binding(expr); }, + peg$c23 = "~a", + peg$c24 = { type: "literal", value: "~a", description: "\"~a\"" }, + peg$c25 = function() { return assetFilter; }, + peg$c26 = "~e", + peg$c27 = { type: "literal", value: "~e", description: "\"~e\"" }, + peg$c28 = function() { return errorFilter; }, + peg$c29 = "~q", + peg$c30 = { type: "literal", value: "~q", description: "\"~q\"" }, + peg$c31 = function() { return noResponseFilter; }, + peg$c32 = "~s", + peg$c33 = { type: "literal", value: "~s", description: "\"~s\"" }, + peg$c34 = function() { return responseFilter; }, + peg$c35 = "true", + peg$c36 = { type: "literal", value: "true", description: "\"true\"" }, + peg$c37 = function() { return trueFilter; }, + peg$c38 = "false", + peg$c39 = { type: "literal", value: "false", description: "\"false\"" }, + peg$c40 = function() { return falseFilter; }, + peg$c41 = "~c", + peg$c42 = { type: "literal", value: "~c", description: "\"~c\"" }, + peg$c43 = function(s) { return responseCode(s); }, + peg$c44 = "~d", + peg$c45 = { type: "literal", value: "~d", description: "\"~d\"" }, + peg$c46 = function(s) { return domain(s); }, + peg$c47 = "~h", + peg$c48 = { type: "literal", value: "~h", description: "\"~h\"" }, + peg$c49 = function(s) { return header(s); }, + peg$c50 = "~hq", + peg$c51 = { type: "literal", value: "~hq", description: "\"~hq\"" }, + peg$c52 = function(s) { return requestHeader(s); }, + peg$c53 = "~hs", + peg$c54 = { type: "literal", value: "~hs", description: "\"~hs\"" }, + peg$c55 = function(s) { return responseHeader(s); }, + peg$c56 = "~m", + peg$c57 = { type: "literal", value: "~m", description: "\"~m\"" }, + peg$c58 = function(s) { return method(s); }, + peg$c59 = "~t", + peg$c60 = { type: "literal", value: "~t", description: "\"~t\"" }, + peg$c61 = function(s) { return contentType(s); }, + peg$c62 = "~tq", + peg$c63 = { type: "literal", value: "~tq", description: "\"~tq\"" }, + peg$c64 = function(s) { return requestContentType(s); }, + peg$c65 = "~ts", + peg$c66 = { type: "literal", value: "~ts", description: "\"~ts\"" }, + peg$c67 = function(s) { return responseContentType(s); }, + peg$c68 = "~u", + peg$c69 = { type: "literal", value: "~u", description: "\"~u\"" }, + peg$c70 = function(s) { return url(s); }, + peg$c71 = { type: "other", description: "integer" }, + peg$c72 = /^['"]/, + peg$c73 = { type: "class", value: "['\"]", description: "['\"]" }, + peg$c74 = /^[0-9]/, + peg$c75 = { type: "class", value: "[0-9]", description: "[0-9]" }, + peg$c76 = function(digits) { return parseInt(digits.join(""), 10); }, + peg$c77 = { type: "other", description: "string" }, + peg$c78 = "\"", + peg$c79 = { type: "literal", value: "\"", description: "\"\\\"\"" }, + peg$c80 = function(chars) { return chars.join(""); }, + peg$c81 = "'", + peg$c82 = { type: "literal", value: "'", description: "\"'\"" }, + peg$c83 = /^["\\]/, + peg$c84 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, + peg$c85 = { type: "any", description: "any character" }, + peg$c86 = function(char) { return char; }, + peg$c87 = "\\", + peg$c88 = { type: "literal", value: "\\", description: "\"\\\\\"" }, + peg$c89 = /^['\\]/, + peg$c90 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, + peg$c91 = /^['"\\]/, + peg$c92 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, + peg$c93 = "n", + peg$c94 = { type: "literal", value: "n", description: "\"n\"" }, + peg$c95 = function() { return "\n"; }, + peg$c96 = "r", + peg$c97 = { type: "literal", value: "r", description: "\"r\"" }, + peg$c98 = function() { return "\r"; }, + peg$c99 = "t", + peg$c100 = { type: "literal", value: "t", description: "\"t\"" }, + peg$c101 = function() { return "\t"; }, peg$currPos = 0, - peg$reportedPos = 0, - peg$cachedPos = 0, - peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$savedPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, @@ -159,38 +157,51 @@ module.exports = (function() { } function text() { - return input.substring(peg$reportedPos, peg$currPos); + return input.substring(peg$savedPos, peg$currPos); } - function offset() { - return peg$reportedPos; - } - - function line() { - return peg$computePosDetails(peg$reportedPos).line; - } - - function column() { - return peg$computePosDetails(peg$reportedPos).column; + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); } function expected(description) { throw peg$buildException( null, [{ type: "other", description: description }], - peg$reportedPos + input.substring(peg$savedPos, peg$currPos), + peg$computeLocation(peg$savedPos, peg$currPos) ); } function error(message) { - throw peg$buildException(message, null, peg$reportedPos); + throw peg$buildException( + message, + null, + input.substring(peg$savedPos, peg$currPos), + peg$computeLocation(peg$savedPos, peg$currPos) + ); } function peg$computePosDetails(pos) { - function advance(details, startPos, endPos) { - var p, ch; + var details = peg$posDetailsCache[pos], + p, ch; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } - for (p = startPos; p < endPos; p++) { + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column, + seenCR: details.seenCR + }; + + while (p < pos) { ch = input.charAt(p); if (ch === "\n") { if (!details.seenCR) { details.line++; } @@ -204,19 +215,31 @@ module.exports = (function() { details.column++; details.seenCR = false; } - } - } - if (peg$cachedPos !== pos) { - if (peg$cachedPos > pos) { - peg$cachedPos = 0; - peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + p++; } - advance(peg$cachedPosDetails, peg$cachedPos, pos); - peg$cachedPos = pos; + + peg$posDetailsCache[pos] = details; + return details; } + } - return peg$cachedPosDetails; + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; } function peg$fail(expected) { @@ -230,7 +253,7 @@ module.exports = (function() { peg$maxFailExpected.push(expected); } - function peg$buildException(message, expected, pos) { + function peg$buildException(message, expected, found, location) { function cleanupExpected(expected) { var i = 1; @@ -267,8 +290,8 @@ module.exports = (function() { .replace(/\r/g, '\\r') .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) - .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) - .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); + .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) + .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); } var expectedDescs = new Array(expected.length), @@ -289,20 +312,15 @@ module.exports = (function() { return "Expected " + expectedDesc + " but " + foundDesc + " found."; } - var posDetails = peg$computePosDetails(pos), - found = pos < input.length ? input.charAt(pos) : null; - if (expected !== null) { cleanupExpected(expected); } - return new SyntaxError( + return new peg$SyntaxError( message !== null ? message : buildMessage(expected, found), expected, found, - pos, - posDetails.line, - posDetails.column + location ); } @@ -317,29 +335,20 @@ module.exports = (function() { if (s2 !== peg$FAILED) { s3 = peg$parse__(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c2(s2); + peg$savedPos = s0; + s1 = peg$c1(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = []; - if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c4(); - } - s0 = s1; + s0 = peg$FAILED; } peg$silentFails--; if (s0 === peg$FAILED) { @@ -354,17 +363,17 @@ module.exports = (function() { var s0, s1; peg$silentFails++; - if (peg$c6.test(input.charAt(peg$currPos))) { + if (peg$c3.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c7); } + if (peg$silentFails === 0) { peg$fail(peg$c4); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c5); } + if (peg$silentFails === 0) { peg$fail(peg$c2); } } return s0; @@ -374,17 +383,17 @@ module.exports = (function() { var s0, s1; peg$silentFails++; - if (peg$c9.test(input.charAt(peg$currPos))) { + if (peg$c6.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c10); } + if (peg$silentFails === 0) { peg$fail(peg$c7); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c8); } + if (peg$silentFails === 0) { peg$fail(peg$c5); } } return s0; @@ -403,7 +412,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c11); } + if (peg$silentFails === 0) { peg$fail(peg$c8); } } return s0; @@ -418,39 +427,39 @@ module.exports = (function() { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c12; + s3 = peg$c9; peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c13); } + if (peg$silentFails === 0) { peg$fail(peg$c10); } } if (s3 !== peg$FAILED) { s4 = peg$parse__(); if (s4 !== peg$FAILED) { s5 = peg$parseOrExpr(); if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c14(s1, s5); + peg$savedPos = s0; + s1 = peg$c11(s1, s5); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseAndExpr(); @@ -468,39 +477,39 @@ module.exports = (function() { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 38) { - s3 = peg$c15; + s3 = peg$c12; peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c16); } + if (peg$silentFails === 0) { peg$fail(peg$c13); } } if (s3 !== peg$FAILED) { s4 = peg$parse__(); if (s4 !== peg$FAILED) { s5 = peg$parseAndExpr(); if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c17(s1, s5); + peg$savedPos = s0; + s1 = peg$c14(s1, s5); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; @@ -514,25 +523,25 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseAndExpr(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c17(s1, s3); + peg$savedPos = s0; + s1 = peg$c14(s1, s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseNotExpr(); @@ -547,31 +556,31 @@ module.exports = (function() { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c18; + s1 = peg$c15; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c19); } + if (peg$silentFails === 0) { peg$fail(peg$c16); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { s3 = peg$parseNotExpr(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c20(s3); + peg$savedPos = s0; + s1 = peg$c17(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseBindingExpr(); @@ -585,11 +594,11 @@ module.exports = (function() { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c21; + s1 = peg$c18; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c22); } + if (peg$silentFails === 0) { peg$fail(peg$c19); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); @@ -599,35 +608,35 @@ module.exports = (function() { s4 = peg$parse__(); if (s4 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c23; + s5 = peg$c20; peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c24); } + if (peg$silentFails === 0) { peg$fail(peg$c21); } } if (s5 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c25(s3); + peg$savedPos = s0; + s1 = peg$c22(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$parseExpr(); @@ -653,58 +662,58 @@ module.exports = (function() { s0 = peg$parseBooleanLiteral(); if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c26) { - s1 = peg$c26; + if (input.substr(peg$currPos, 2) === peg$c23) { + s1 = peg$c23; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c27); } + if (peg$silentFails === 0) { peg$fail(peg$c24); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c28(); + peg$savedPos = s0; + s1 = peg$c25(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c29) { - s1 = peg$c29; + if (input.substr(peg$currPos, 2) === peg$c26) { + s1 = peg$c26; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c30); } + if (peg$silentFails === 0) { peg$fail(peg$c27); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c31(); + peg$savedPos = s0; + s1 = peg$c28(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c32) { - s1 = peg$c32; + if (input.substr(peg$currPos, 2) === peg$c29) { + s1 = peg$c29; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c33); } + if (peg$silentFails === 0) { peg$fail(peg$c30); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c34(); + peg$savedPos = s0; + s1 = peg$c31(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c35) { - s1 = peg$c35; + if (input.substr(peg$currPos, 2) === peg$c32) { + s1 = peg$c32; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c36); } + if (peg$silentFails === 0) { peg$fail(peg$c33); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c37(); + peg$savedPos = s0; + s1 = peg$c34(); } s0 = s1; } @@ -719,30 +728,30 @@ module.exports = (function() { var s0, s1; s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c38) { - s1 = peg$c38; + if (input.substr(peg$currPos, 4) === peg$c35) { + s1 = peg$c35; peg$currPos += 4; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c39); } + if (peg$silentFails === 0) { peg$fail(peg$c36); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c40(); + peg$savedPos = s0; + s1 = peg$c37(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c41) { - s1 = peg$c41; + if (input.substr(peg$currPos, 5) === peg$c38) { + s1 = peg$c38; peg$currPos += 5; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c42); } + if (peg$silentFails === 0) { peg$fail(peg$c39); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c43(); + peg$savedPos = s0; + s1 = peg$c40(); } s0 = s1; } @@ -754,12 +763,12 @@ module.exports = (function() { var s0, s1, s2, s3; s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c44) { - s1 = peg$c44; + if (input.substr(peg$currPos, 2) === peg$c41) { + s1 = peg$c41; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c45); } + if (peg$silentFails === 0) { peg$fail(peg$c42); } } if (s1 !== peg$FAILED) { s2 = []; @@ -770,34 +779,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseIntegerLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c46(s3); + peg$savedPos = s0; + s1 = peg$c43(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c47) { - s1 = peg$c47; + if (input.substr(peg$currPos, 2) === peg$c44) { + s1 = peg$c44; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c48); } + if (peg$silentFails === 0) { peg$fail(peg$c45); } } if (s1 !== peg$FAILED) { s2 = []; @@ -808,34 +817,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c49(s3); + peg$savedPos = s0; + s1 = peg$c46(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c50) { - s1 = peg$c50; + if (input.substr(peg$currPos, 2) === peg$c47) { + s1 = peg$c47; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c51); } + if (peg$silentFails === 0) { peg$fail(peg$c48); } } if (s1 !== peg$FAILED) { s2 = []; @@ -846,34 +855,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c52(s3); + peg$savedPos = s0; + s1 = peg$c49(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c53) { - s1 = peg$c53; + if (input.substr(peg$currPos, 3) === peg$c50) { + s1 = peg$c50; peg$currPos += 3; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c54); } + if (peg$silentFails === 0) { peg$fail(peg$c51); } } if (s1 !== peg$FAILED) { s2 = []; @@ -884,34 +893,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c55(s3); + peg$savedPos = s0; + s1 = peg$c52(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c56) { - s1 = peg$c56; + if (input.substr(peg$currPos, 3) === peg$c53) { + s1 = peg$c53; peg$currPos += 3; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c57); } + if (peg$silentFails === 0) { peg$fail(peg$c54); } } if (s1 !== peg$FAILED) { s2 = []; @@ -922,34 +931,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c58(s3); + peg$savedPos = s0; + s1 = peg$c55(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c59) { - s1 = peg$c59; + if (input.substr(peg$currPos, 2) === peg$c56) { + s1 = peg$c56; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c60); } + if (peg$silentFails === 0) { peg$fail(peg$c57); } } if (s1 !== peg$FAILED) { s2 = []; @@ -960,34 +969,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c61(s3); + peg$savedPos = s0; + s1 = peg$c58(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c62) { - s1 = peg$c62; + if (input.substr(peg$currPos, 2) === peg$c59) { + s1 = peg$c59; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c63); } + if (peg$silentFails === 0) { peg$fail(peg$c60); } } if (s1 !== peg$FAILED) { s2 = []; @@ -998,34 +1007,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c64(s3); + peg$savedPos = s0; + s1 = peg$c61(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c65) { - s1 = peg$c65; + if (input.substr(peg$currPos, 3) === peg$c62) { + s1 = peg$c62; peg$currPos += 3; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c66); } + if (peg$silentFails === 0) { peg$fail(peg$c63); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1036,34 +1045,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c67(s3); + peg$savedPos = s0; + s1 = peg$c64(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c68) { - s1 = peg$c68; + if (input.substr(peg$currPos, 3) === peg$c65) { + s1 = peg$c65; peg$currPos += 3; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c69); } + if (peg$silentFails === 0) { peg$fail(peg$c66); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1074,34 +1083,34 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c70(s3); + peg$savedPos = s0; + s1 = peg$c67(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c71) { - s1 = peg$c71; + if (input.substr(peg$currPos, 2) === peg$c68) { + s1 = peg$c68; peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c72); } + if (peg$silentFails === 0) { peg$fail(peg$c69); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1112,32 +1121,32 @@ module.exports = (function() { s3 = peg$parsews(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c73(s3); + peg$savedPos = s0; + s1 = peg$c70(s3); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = peg$parseStringLiteral(); if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c73(s1); + peg$savedPos = s0; + s1 = peg$c70(s1); } s0 = s1; } @@ -1159,70 +1168,70 @@ module.exports = (function() { peg$silentFails++; s0 = peg$currPos; - if (peg$c76.test(input.charAt(peg$currPos))) { + if (peg$c72.test(input.charAt(peg$currPos))) { s1 = input.charAt(peg$currPos); peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c77); } + if (peg$silentFails === 0) { peg$fail(peg$c73); } } if (s1 === peg$FAILED) { - s1 = peg$c75; + s1 = null; } if (s1 !== peg$FAILED) { s2 = []; - if (peg$c78.test(input.charAt(peg$currPos))) { + if (peg$c74.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c79); } + if (peg$silentFails === 0) { peg$fail(peg$c75); } } if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); - if (peg$c78.test(input.charAt(peg$currPos))) { + if (peg$c74.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c79); } + if (peg$silentFails === 0) { peg$fail(peg$c75); } } } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { - if (peg$c76.test(input.charAt(peg$currPos))) { + if (peg$c72.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c77); } + if (peg$silentFails === 0) { peg$fail(peg$c73); } } if (s3 === peg$FAILED) { - s3 = peg$c75; + s3 = null; } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c80(s2); + peg$savedPos = s0; + s1 = peg$c76(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c74); } + if (peg$silentFails === 0) { peg$fail(peg$c71); } } return s0; @@ -1234,11 +1243,11 @@ module.exports = (function() { peg$silentFails++; s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c82; + s1 = peg$c78; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c79); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1249,36 +1258,36 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c82; + s3 = peg$c78; peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c79); } } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c85; + s1 = peg$c81; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c86); } + if (peg$silentFails === 0) { peg$fail(peg$c82); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1289,27 +1298,27 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c85; + s3 = peg$c81; peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c86); } + if (peg$silentFails === 0) { peg$fail(peg$c82); } } if (s3 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; @@ -1318,10 +1327,10 @@ module.exports = (function() { s2 = peg$parsecc(); peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { s2 = []; @@ -1332,26 +1341,26 @@ module.exports = (function() { s3 = peg$parseUnquotedStringChar(); } } else { - s2 = peg$c1; + s2 = peg$FAILED; } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c84(s2); + peg$savedPos = s0; + s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c81); } + if (peg$silentFails === 0) { peg$fail(peg$c77); } } return s0; @@ -1363,19 +1372,19 @@ module.exports = (function() { s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; - if (peg$c88.test(input.charAt(peg$currPos))) { + if (peg$c83.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c89); } + if (peg$silentFails === 0) { peg$fail(peg$c84); } } peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -1383,42 +1392,42 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c90); } + if (peg$silentFails === 0) { peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c92; + s1 = peg$c87; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c93); } + if (peg$silentFails === 0) { peg$fail(peg$c88); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } @@ -1431,19 +1440,19 @@ module.exports = (function() { s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; - if (peg$c94.test(input.charAt(peg$currPos))) { + if (peg$c89.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c95); } + if (peg$silentFails === 0) { peg$fail(peg$c90); } } peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -1451,42 +1460,42 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c90); } + if (peg$silentFails === 0) { peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c92; + s1 = peg$c87; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c93); } + if (peg$silentFails === 0) { peg$fail(peg$c88); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } @@ -1502,10 +1511,10 @@ module.exports = (function() { s2 = peg$parsews(); peg$silentFails--; if (s2 === peg$FAILED) { - s1 = peg$c87; + s1 = void 0; } else { peg$currPos = s1; - s1 = peg$c1; + s1 = peg$FAILED; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { @@ -1513,19 +1522,19 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c90); } + if (peg$silentFails === 0) { peg$fail(peg$c85); } } if (s2 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c91(s2); + peg$savedPos = s0; + s1 = peg$c86(s2); s0 = s1; } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } } else { peg$currPos = s0; - s0 = peg$c1; + s0 = peg$FAILED; } return s0; @@ -1534,53 +1543,53 @@ module.exports = (function() { function peg$parseEscapeSequence() { var s0, s1; - if (peg$c96.test(input.charAt(peg$currPos))) { + if (peg$c91.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c97); } + if (peg$silentFails === 0) { peg$fail(peg$c92); } } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 110) { - s1 = peg$c98; + s1 = peg$c93; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c99); } + if (peg$silentFails === 0) { peg$fail(peg$c94); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c100(); + peg$savedPos = s0; + s1 = peg$c95(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 114) { - s1 = peg$c101; + s1 = peg$c96; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c102); } + if (peg$silentFails === 0) { peg$fail(peg$c97); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c103(); + peg$savedPos = s0; + s1 = peg$c98(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 116) { - s1 = peg$c104; + s1 = peg$c99; peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c105); } + if (peg$silentFails === 0) { peg$fail(peg$c100); } } if (s1 !== peg$FAILED) { - peg$reportedPos = s0; - s1 = peg$c106(); + peg$savedPos = s0; + s1 = peg$c101(); } s0 = s1; } @@ -1763,12 +1772,19 @@ module.exports = (function() { peg$fail({ type: "end", description: "end of input" }); } - throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + throw peg$buildException( + null, + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); } } return { - SyntaxError: SyntaxError, - parse: parse + SyntaxError: peg$SyntaxError, + parse: peg$parse }; })();
\ No newline at end of file diff --git a/web/src/js/filt/filt.peg b/web/src/js/filt/filt.peg index 6f9bdac6..ccaaa072 100644 --- a/web/src/js/filt/filt.peg +++ b/web/src/js/filt/filt.peg @@ -166,7 +166,6 @@ function url(regex){ start "filter expression" = __ orExpr:OrExpr __ { return orExpr; } - / {return trueFilter; } ws "whitespace" = [ \t\n\r] cc "control character" = [|&!()~"] diff --git a/web/src/templates/index.html b/web/src/templates/index.html index 5f2c6d5e..165d7d3d 100644 --- a/web/src/templates/index.html +++ b/web/src/templates/index.html @@ -10,5 +10,6 @@ <script src="/static/app.js"></script> </head> <body> +<div id="mitmproxy"></div> </body> </html>
\ No newline at end of file |