diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..475bc4f --- /dev/null +++ b/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": ["env", "react", "es2017", "stage-0"], + "plugins": [ + "transform-object-rest-spread", + ["babel-plugin-styled-components", { + "displayName": true, + "ssr": true + }] + ] + } \ No newline at end of file diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..cf1ee2a --- /dev/null +++ b/.env.local @@ -0,0 +1 @@ +REACT_EDITOR=code \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 391030c..0000000 --- a/.eslintrc +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parser": "babel-eslint", - "env": { - "browser": true, - "node": true - }, - "plugins": [ - "react" - ], - "rules": { - "strict": [0], - "curly": [0], - "react/no-multi-comp": 1, - "no-alert": [0], - "no-unused-vars": [0], - "no-redeclare": [1], - "new-cap": [0], - "quotes": [2, "single"], - "eol-last": [0], - "no-mixed-requires": [0], - "camelcase": [0], - "consistent-return": [0], - "no-underscore-dangle": [0], - "comma-spacing": [0], - "key-spacing": [0], - "valid-jsdoc": [2], - "no-use-before-define": [0] - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..13380b7 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + "extends": "airbnb", + "rules": { + "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] + }, + "env": { + "browser": true + } +}; \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ccbba8b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +/yarn-error.log diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 8355339..0000000 --- a/.jshintrc +++ /dev/null @@ -1,25 +0,0 @@ -{ - "evil": true, - "smarttabs": true, - "strict": false, - "globalstrict": false, - "asi": false, - "browser": true, - "noarg": true, - "undef": true, - "eqeqeq": true, - "esnext": true, - "freeze": true, - "quotmark": "single", - "node": true, - "globals": { - "require": true, - "console": true, - "Raven": true, - "module": true, - "confirm": true, - "prompt": true, - "alert": true, - "mapboxgl": true - } -} diff --git a/.storybook/addons.js b/.storybook/addons.js new file mode 100644 index 0000000..6aed412 --- /dev/null +++ b/.storybook/addons.js @@ -0,0 +1,2 @@ +import '@storybook/addon-actions/register'; +import '@storybook/addon-links/register'; diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100644 index 0000000..a4de189 --- /dev/null +++ b/.storybook/config.js @@ -0,0 +1,10 @@ +import { configure } from '@storybook/react'; +import '@storybook/addon-console'; + +// automatically import all files ending in *.stories.js +const req = require.context('../stories', true, /.stories.js$/); +function loadStories() { + req.keys().forEach(filename => req(filename)); +} + +configure(loadStories, module); diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3b66410 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/ACCESS_TOKEN.js b/ACCESS_TOKEN.js new file mode 100644 index 0000000..b2d711d --- /dev/null +++ b/ACCESS_TOKEN.js @@ -0,0 +1 @@ +export default 'CHANGEME'; \ No newline at end of file diff --git a/README.md b/README.md index aaef72f..b49c17f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,15 @@ npm install @mapbox/react-geocoder A geocoder component using Mapbox. +## Storybook +To see options in Storybook run: +``` +yarn storybook +``` + +NOTE: You MUST put +`export default 'your-api-key';` in `ACCESS_TOKEN.js` for this to work. + ## api An `accessToken` is assumed to be a valid Mapbox accessToken. @@ -30,3 +39,11 @@ An `accessToken` is assumed to be a valid Mapbox accessToken. focusOnMount=optional bool, default true /> ``` + +# Building +Use Storybook to ensure everything looks right. Then + +``` +yarn build +``` + diff --git a/build/index.js b/build/index.js new file mode 100644 index 0000000..6afba8c --- /dev/null +++ b/build/index.js @@ -0,0 +1,424 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['exports', 'react', 'prop-types', './search', './styles', 'babel-polyfill'], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require('react'), require('prop-types'), require('./search'), require('./styles'), require('babel-polyfill')); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.react, global.propTypes, global.search, global.styles, global.babelPolyfill); + global.index = mod.exports; + } +})(this, function (exports, _react, _propTypes, _search, _styles) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var _search2 = _interopRequireDefault(_search); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + 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 _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + + var Geocoder = function (_Component) { + _inherits(Geocoder, _Component); + + function Geocoder() { + _classCallCheck(this, Geocoder); + + var _this = _possibleConstructorReturn(this, (Geocoder.__proto__ || Object.getPrototypeOf(Geocoder)).call(this)); + + _this.state = { + results: [], + focus: null, + loading: false, + searchTime: new Date(), + value: '' + }; + + _this.onInput = _this.onInput.bind(_this); + _this.onKeyDown = _this.onKeyDown.bind(_this); + _this.clickOption = _this.clickOption.bind(_this); + _this.onResult = _this.onResult.bind(_this); + _this.onChange = _this.onChange.bind(_this); + _this.onSelect = _this.onSelect.bind(_this); + return _this; + } + + _createClass(Geocoder, [{ + key: 'componentDidMount', + value: function componentDidMount() { + var focusOnMount = this.props.focusOnMount; + + if (focusOnMount) this.input.focus(); + } + }, { + key: 'onChange', + value: function onChange(_ref) { + var target = _ref.target; + + this.setState({ + value: target.value + }); + } + }, { + key: 'onInput', + value: function onInput(e) { + this.setState({ loading: true }); + var value = e.target.value; + + if (value === '') { + this.setState({ + results: [], + focus: null, + loading: false + }); + } else { + var _props = this.props, + endpoint = _props.endpoint, + source = _props.source, + accessToken = _props.accessToken, + proximity = _props.proximity, + bbox = _props.bbox, + types = _props.types; + + + (0, _search2.default)({ + endpoint: endpoint, + source: source, + accessToken: accessToken, + proximity: proximity, + bbox: bbox, + types: types, + query: value, + onResult: this.onResult + }); + } + } + }, { + key: 'onKeyDown', + value: function onKeyDown(e) { + var _state = this.state, + results = _state.results, + focus = _state.focus; + + switch (e.which) { + // up + case 38: + e.preventDefault(); + this.moveFocus(-1); + break; + // down + case 40: + this.moveFocus(1); + break; + // accept + case 13: + if (results.length > 0 && focus == null) { + this.clickOption(results[0], 0); + } + this.acceptFocus(); + break; + default: + break; + } + } + }, { + key: 'onResult', + value: function onResult(body, searchTime) { + var _state2 = this.state, + oldSearchTime = _state2.searchTime, + results = _state2.results; + var onSuggest = this.props.onSuggest; + + + // searchTime is compared with the last search to set the state + // to ensure that a slow xhr response does not scramble the + // sequence of autocomplete display. + if (body && body.features && oldSearchTime <= searchTime) { + this.setState({ + searchTime: searchTime, + loading: false, + results: body.features, + focus: null + }); + onSuggest(results); + } + } + }, { + key: 'onSelect', + value: function onSelect(place) { + var onSelect = this.props.onSelect; + + + this.setState({ + value: '', + results: [] + }); + + onSelect(place); + } + }, { + key: 'setInput', + value: function setInput(text) { + this.setState({ + value: text + }); + } + }, { + key: 'moveFocus', + value: function moveFocus(dir) { + var _state3 = this.state, + loading = _state3.loading, + focus = _state3.focus, + results = _state3.results; + + if (loading) return; + this.setState({ + focus: focus === null ? 0 : Math.max(0, Math.min(results.length - 1, focus + dir)) + }); + } + }, { + key: 'acceptFocus', + value: function acceptFocus() { + var _state4 = this.state, + focus = _state4.focus, + results = _state4.results; + var onSelect = this.props.onSelect; + + + if (focus !== null) { + this.onSelect(results[focus]); + } + } + }, { + key: 'clickOption', + value: function clickOption(place, listLocation) { + var onSelect = this.props.onSelect; + + + this.onSelect(place); + this.setState({ focus: listLocation }); + + // focus on the input after click to maintain key traversal + this.input.focus(); + return false; + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var _props2 = this.props, + inputClass = _props2.inputClass, + inputPlaceholder = _props2.inputPlaceholder, + inputPosition = _props2.inputPosition, + showLoader = _props2.showLoader, + resultsClass = _props2.resultsClass, + resultClass = _props2.resultClass, + resultFocusClass = _props2.resultFocusClass, + CustomResultList = _props2.ResultList, + CustomResult = _props2.Result, + CustomResultLink = _props2.ResultLink, + CustomInputWrapper = _props2.InputWrapper, + CustomSearchIcon = _props2.SeachIcon, + CustomInput = _props2.Input, + CustomWrapper = _props2.Wraapper; + var _state5 = this.state, + results = _state5.results, + loading = _state5.loading, + focus = _state5.focus, + value = _state5.value; + + + var Components = { + ResultList: CustomResultList || _styles.ResultList, + Result: CustomResult || _styles.Result, + ResultLink: CustomResultLink || _styles.ResultLink, + InputWrapper: CustomInputWrapper || _styles.InputWrapper, + SearchIcon: CustomSearchIcon || _styles.SearchIcon, + Input: CustomInput || _styles.Input, + Wrapper: CustomWrapper || _styles.Wrapper + }; + + var input = _react2.default.createElement( + Components.InputWrapper, + null, + _react2.default.createElement(Components.SearchIcon, null), + _react2.default.createElement(Components.Input, { + innerRef: function innerRef(ref) { + _this2.input = ref; + }, + className: inputClass, + onInput: this.onInput, + onKeyDown: this.onKeyDown, + onChange: this.onChange, + placeholder: inputPlaceholder, + type: 'text', + value: value + }) + ); + + return _react2.default.createElement( + Components.Wrapper, + null, + inputPosition === 'top' && input, + _react2.default.createElement( + Components.ResultList, + { className: '\n ' + (showLoader && loading ? 'loading' : '') + '\n ' + resultsClass + }, + results.length > 0 && results.map(function (result, i) { + return _react2.default.createElement( + Components.Result, + { key: result.id }, + _react2.default.createElement( + Components.ResultLink, + { + type: 'button', + onClick: function onClick() { + return _this2.clickOption(result, i); + }, + className: resultClass + ' ' + (i === focus ? resultFocusClass : ''), + key: result.id + }, + result.place_name + ) + ); + }) + ), + inputPosition === 'bottom' && input + ); + } + }]); + + return Geocoder; + }(_react.Component); + + exports.default = Geocoder; + + + Geocoder.propTypes = { + endpoint: _propTypes2.default.string, + source: _propTypes2.default.string, + accessToken: _propTypes2.default.string.isRequired, + + inputClass: _propTypes2.default.string, + resultClass: _propTypes2.default.string, + resultsClass: _propTypes2.default.string, + resultFocusClass: _propTypes2.default.string, + + ResultList: _propTypes2.default.element, + Result: _propTypes2.default.element, + ResultLink: _propTypes2.default.element, + InputWrapper: _propTypes2.default.element, + SeachIcon: _propTypes2.default.element, + Input: _propTypes2.default.element, + Wraapper: _propTypes2.default.element, + + showLoader: _propTypes2.default.bool, + focusOnMount: _propTypes2.default.bool, + + inputPosition: _propTypes2.default.string, + inputPlaceholder: _propTypes2.default.string, + + onSelect: _propTypes2.default.func.isRequired, + onSuggest: _propTypes2.default.func, + + proximity: _propTypes2.default.string, + bbox: _propTypes2.default.arrayOf(_propTypes2.default.number), + + types: _propTypes2.default.string + }; + + Geocoder.defaultProps = { + endpoint: 'https://api.tiles.mapbox.com', + + inputClass: '', + resultClass: '', + resultsClass: '', + resultFocusClass: 'strong', + + ResultList: null, + Result: null, + ResultLink: null, + InputWrapper: null, + SeachIcon: null, + Input: null, + Wraapper: null, + + inputPosition: 'top', + + inputPlaceholder: 'Search', + + showLoader: false, + + source: 'mapbox.places', + proximity: '', + + bbox: [], + types: '', + + onSuggest: function onSuggest() { + return null; + }, + focusOnMount: true + }; +}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/index.js.map b/build/index.js.map new file mode 100644 index 0000000..8c9ae03 --- /dev/null +++ b/build/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/index.jsx"],"names":["Geocoder","state","results","focus","loading","searchTime","Date","value","onInput","bind","onKeyDown","clickOption","onResult","onChange","onSelect","focusOnMount","props","input","target","setState","e","endpoint","source","accessToken","proximity","bbox","types","query","which","preventDefault","moveFocus","length","acceptFocus","body","oldSearchTime","onSuggest","features","place","text","dir","Math","max","min","listLocation","inputClass","inputPlaceholder","inputPosition","showLoader","resultsClass","resultClass","resultFocusClass","CustomResultList","ResultList","CustomResult","Result","CustomResultLink","ResultLink","CustomInputWrapper","InputWrapper","CustomSearchIcon","SeachIcon","CustomInput","Input","CustomWrapper","Wraapper","Components","SearchIcon","Wrapper","ref","map","result","i","id","place_name","Component","propTypes","PropTypes","string","isRequired","element","bool","func","arrayOf","number","defaultProps"],"mappings":"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","file":"index.js","sourcesContent":["import 'babel-polyfill';\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport search from './search';\n\nimport {\n Input,\n InputWrapper,\n SearchIcon,\n ResultList,\n Result,\n ResultLink,\n Wrapper,\n} from './styles';\n\nexport default class Geocoder extends Component {\n constructor() {\n super();\n\n this.state = {\n results: [],\n focus: null,\n loading: false,\n searchTime: new Date(),\n value: '',\n };\n\n this.onInput = this.onInput.bind(this);\n this.onKeyDown = this.onKeyDown.bind(this);\n this.clickOption = this.clickOption.bind(this);\n this.onResult = this.onResult.bind(this);\n this.onChange = this.onChange.bind(this);\n this.onSelect = this.onSelect.bind(this);\n }\n\n componentDidMount() {\n const { focusOnMount } = this.props;\n if (focusOnMount) this.input.focus();\n }\n\n onChange({ target }) {\n this.setState({\n value: target.value,\n });\n }\n\n onInput(e) {\n this.setState({ loading: true });\n const { value } = e.target;\n if (value === '') {\n this.setState({\n results: [],\n focus: null,\n loading: false,\n });\n } else {\n const {\n endpoint,\n source,\n accessToken,\n proximity,\n bbox,\n types,\n } = this.props;\n\n search({\n endpoint,\n source,\n accessToken,\n proximity,\n bbox,\n types,\n query: value,\n onResult: this.onResult,\n });\n }\n }\n\n onKeyDown(e) {\n const { results, focus } = this.state;\n switch (e.which) {\n // up\n case 38:\n e.preventDefault();\n this.moveFocus(-1);\n break;\n // down\n case 40:\n this.moveFocus(1);\n break;\n // accept\n case 13:\n if (results.length > 0 && focus == null) {\n this.clickOption(results[0], 0);\n }\n this.acceptFocus();\n break;\n default:\n break;\n }\n }\n\n onResult(body, searchTime) {\n const { searchTime: oldSearchTime, results } = this.state;\n const { onSuggest } = this.props;\n\n // searchTime is compared with the last search to set the state\n // to ensure that a slow xhr response does not scramble the\n // sequence of autocomplete display.\n if (body && body.features && oldSearchTime <= searchTime) {\n this.setState({\n searchTime,\n loading: false,\n results: body.features,\n focus: null,\n });\n onSuggest(results);\n }\n }\n\n onSelect(place) {\n const { onSelect } = this.props;\n\n this.setState({\n value: '',\n results: [],\n });\n\n onSelect(place);\n }\n\n setInput(text) {\n this.setState({\n value: text,\n });\n }\n\n moveFocus(dir) {\n const { loading, focus, results } = this.state;\n if (loading) return;\n this.setState({\n focus: focus === null\n ? 0 : Math.max(0,\n Math.min(\n results.length - 1,\n focus + dir,\n )),\n });\n }\n\n acceptFocus() {\n const { focus, results } = this.state;\n const { onSelect } = this.props;\n\n if (focus !== null) {\n this.onSelect(results[focus]);\n }\n }\n\n clickOption(place, listLocation) {\n const { onSelect } = this.props;\n\n this.onSelect(place);\n this.setState({ focus: listLocation });\n\n // focus on the input after click to maintain key traversal\n this.input.focus();\n return false;\n }\n\n render() {\n const {\n inputClass,\n inputPlaceholder,\n inputPosition,\n showLoader,\n resultsClass,\n resultClass,\n resultFocusClass,\n ResultList: CustomResultList,\n Result: CustomResult,\n ResultLink: CustomResultLink,\n InputWrapper: CustomInputWrapper,\n SeachIcon: CustomSearchIcon,\n Input: CustomInput,\n Wraapper: CustomWrapper,\n } = this.props;\n\n const {\n results,\n loading,\n focus,\n value,\n } = this.state;\n\n const Components = {\n ResultList: CustomResultList || ResultList,\n Result: CustomResult || Result,\n ResultLink: CustomResultLink || ResultLink,\n InputWrapper: CustomInputWrapper || InputWrapper,\n SearchIcon: CustomSearchIcon || SearchIcon,\n Input: CustomInput || Input,\n Wrapper: CustomWrapper || Wrapper,\n };\n\n const input = (\n \n \n { this.input = ref; }}\n className={inputClass}\n onInput={this.onInput}\n onKeyDown={this.onKeyDown}\n onChange={this.onChange}\n placeholder={inputPlaceholder}\n type=\"text\"\n value={value}\n />\n \n );\n\n return (\n \n {inputPosition === 'top' && input}\n \n {results.length > 0 && (\n results.map((result, i) => (\n \n this.clickOption(result, i)}\n className={`${resultClass} ${i === focus ? resultFocusClass : ''}`}\n key={result.id}\n >\n {result.place_name}\n \n \n ))\n )}\n \n {inputPosition === 'bottom' && input}\n \n );\n }\n}\n\nGeocoder.propTypes = {\n endpoint: PropTypes.string,\n source: PropTypes.string,\n accessToken: PropTypes.string.isRequired,\n\n inputClass: PropTypes.string,\n resultClass: PropTypes.string,\n resultsClass: PropTypes.string,\n resultFocusClass: PropTypes.string,\n\n ResultList: PropTypes.element,\n Result: PropTypes.element,\n ResultLink: PropTypes.element,\n InputWrapper: PropTypes.element,\n SeachIcon: PropTypes.element,\n Input: PropTypes.element,\n Wraapper: PropTypes.element,\n\n showLoader: PropTypes.bool,\n focusOnMount: PropTypes.bool,\n\n inputPosition: PropTypes.string,\n inputPlaceholder: PropTypes.string,\n\n onSelect: PropTypes.func.isRequired,\n onSuggest: PropTypes.func,\n\n proximity: PropTypes.string,\n bbox: PropTypes.arrayOf(PropTypes.number),\n\n types: PropTypes.string,\n};\n\nGeocoder.defaultProps = {\n endpoint: 'https://api.tiles.mapbox.com',\n\n inputClass: '',\n resultClass: '',\n resultsClass: '',\n resultFocusClass: 'strong',\n\n ResultList: null,\n Result: null,\n ResultLink: null,\n InputWrapper: null,\n SeachIcon: null,\n Input: null,\n Wraapper: null,\n\n inputPosition: 'top',\n\n inputPlaceholder: 'Search',\n\n showLoader: false,\n\n source: 'mapbox.places',\n proximity: '',\n\n bbox: [],\n types: '',\n\n onSuggest: () => null,\n focusOnMount: true,\n};\n"]} \ No newline at end of file diff --git a/build/search.js b/build/search.js new file mode 100644 index 0000000..6585fe3 --- /dev/null +++ b/build/search.js @@ -0,0 +1,97 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['exports', 'babel-polyfill'], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require('babel-polyfill')); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.babelPolyfill); + global.search = mod.exports; + } +})(this, function (exports) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _asyncToGenerator(fn) { + return function () { + var gen = fn.apply(this, arguments); + return new Promise(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + return Promise.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } + + return step("next"); + }); + }; + } + + exports.default = function () { + var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(_ref2) { + var endpoint = _ref2.endpoint, + source = _ref2.source, + accessToken = _ref2.accessToken, + _ref2$proximity = _ref2.proximity, + proximity = _ref2$proximity === undefined ? '' : _ref2$proximity, + _ref2$bbox = _ref2.bbox, + bbox = _ref2$bbox === undefined ? '' : _ref2$bbox, + _ref2$types = _ref2.types, + types = _ref2$types === undefined ? '' : _ref2$types, + query = _ref2.query, + onResult = _ref2.onResult; + var searchTime, uri, data; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + searchTime = new Date(); + uri = endpoint + '/geocoding/v5/' + source + '/' + encodeURIComponent(query) + '.json?access_token=' + accessToken + (proximity ? '&proximity=' + proximity : '') + (bbox ? '&bbox=' + bbox : '') + (types ? '&types=' + encodeURIComponent(types) : ''); + _context.next = 4; + return fetch(uri); + + case 4: + _context.next = 6; + return _context.sent.json(); + + case 6: + data = _context.sent; + + + onResult(data, searchTime); + + case 8: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function search(_x) { + return _ref.apply(this, arguments); + } + + return search; + }(); +}); +//# sourceMappingURL=search.js.map \ No newline at end of file diff --git a/build/search.js.map b/build/search.js.map new file mode 100644 index 0000000..bfc0533 --- /dev/null +++ b/build/search.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/search.js"],"names":["endpoint","source","accessToken","proximity","bbox","types","query","onResult","searchTime","Date","uri","encodeURIComponent","fetch","json","data","search"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAEe;AAAA,UACbA,QADa,SACbA,QADa;AAAA,UAEbC,MAFa,SAEbA,MAFa;AAAA,UAGbC,WAHa,SAGbA,WAHa;AAAA,kCAIbC,SAJa;AAAA,UAIbA,SAJa,mCAID,EAJC;AAAA,6BAKbC,IALa;AAAA,UAKbA,IALa,8BAKN,EALM;AAAA,8BAMbC,KANa;AAAA,UAMbA,KANa,+BAML,EANK;AAAA,UAObC,KAPa,SAObA,KAPa;AAAA,UAQbC,QARa,SAQbA,QARa;AAAA;AAAA;AAAA;AAAA;AAAA;AAUPC,wBAVO,GAUM,IAAIC,IAAJ,EAVN;AAWPC,iBAXO,GAWEV,QAXF,sBAYXC,MAZW,SAYDU,mBAAmBL,KAAnB,CAZC,2BAaSJ,WAbT,IAcVC,4BACeA,SADf,GAEC,EAhBS,KAiBVC,kBAAgBA,IAAhB,GAAyB,EAjBf,KAkBVC,oBACWM,mBAAmBN,KAAnB,CADX,GAEC,EApBS;AAAA;AAAA,qBAuBaO,MAAMF,GAAN,CAvBb;;AAAA;AAAA;AAAA,mCAuByBG,IAvBzB;;AAAA;AAuBPC,kBAvBO;;;AAyBbP,uBAASO,IAAT,EAAeN,UAAf;;AAzBa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,K;;aAAeO,M;;;;WAAAA,M","file":"search.js","sourcesContent":["import 'babel-polyfill';\n\nexport default async function search({\n endpoint,\n source,\n accessToken,\n proximity = '',\n bbox = '',\n types = '',\n query,\n onResult,\n}) {\n const searchTime = new Date();\n const uri = `${endpoint}/geocoding/v5/${\n source}/${encodeURIComponent(query)\n }.json?access_token=${accessToken\n }${proximity\n ? `&proximity=${proximity}`\n : ''\n }${bbox ? `&bbox=${bbox}` : ''\n }${types\n ? `&types=${encodeURIComponent(types)}`\n : ''\n }`;\n\n const data = await (await fetch(uri)).json();\n\n onResult(data, searchTime);\n}\n"]} \ No newline at end of file diff --git a/build/styles.js b/build/styles.js new file mode 100644 index 0000000..1d73416 --- /dev/null +++ b/build/styles.js @@ -0,0 +1,64 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['exports', 'styled-components', 'styled-icons/fa-solid'], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require('styled-components'), require('styled-icons/fa-solid')); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.styledComponents, global.faSolid); + global.styles = mod.exports; + } +})(this, function (exports, _styledComponents, _faSolid) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ResultLink = exports.Result = exports.ResultList = exports.SearchIcon = exports.InputWrapper = exports.Input = exports.Wrapper = undefined; + + var _styledComponents2 = _interopRequireDefault(_styledComponents); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + var Wrapper = exports.Wrapper = _styledComponents2.default.div.withConfig({ + displayName: 'styles__Wrapper', + componentId: 's1o8q90i-0' + })(['font-family:\'Helvetica Neue\',Arial,Helvetica,sans-serif;font-size:14px;width:100%;display:flex;flex-direction:column;align-items:stretch;']); + + var Input = exports.Input = _styledComponents2.default.input.withConfig({ + displayName: 'styles__Input', + componentId: 's1o8q90i-1' + })(['margin:0;color:rgba(0,0,0,.5);border:1px solid rgba(0,0,0,0.125);padding:10px 10px 10px 40px;border-radius:5px;border-bottom-left-radius:0;border-bottom-right-radius:0;width:100%;font-family:\'Helvetica Neue\',Arial,Helvetica,sans-serif;font-size:14px;']); + + var InputWrapper = exports.InputWrapper = _styledComponents2.default.div.withConfig({ + displayName: 'styles__InputWrapper', + componentId: 's1o8q90i-2' + })(['position:relative;']); + + var SearchIcon = exports.SearchIcon = (0, _styledComponents2.default)(_faSolid.Search).withConfig({ + displayName: 'styles__SearchIcon', + componentId: 's1o8q90i-3' + })(['position:absolute;width:15px;height:15px;left:10px;top:12px;']); + + var ResultList = exports.ResultList = _styledComponents2.default.ul.withConfig({ + displayName: 'styles__ResultList', + componentId: 's1o8q90i-4' + })(['background-color:#fff;list-style:none;margin:0;padding:0;width:100%;z-index:1000;overflow:hidden;text-overflow:ellipsis;']); + + var Result = exports.Result = _styledComponents2.default.li.withConfig({ + displayName: 'styles__Result', + componentId: 's1o8q90i-5' + })(['border:1px solid rgba(0,0,0,0.1);&:last-child{border-bottom-left-radius:10px;border-bottom-right-radius:10px;}']); + + var ResultLink = exports.ResultLink = _styledComponents2.default.button.withConfig({ + displayName: 'styles__ResultLink', + componentId: 's1o8q90i-6' + })(['text-align:left;font-family:\'Helvetica Neue\',Arial,Helvetica,sans-serif;font-size:14px;background:none;border:none;outline:inherit;width:100%;padding:10px;overflow:hidden;text-overflow:ellipsis;color:#404040;cursor:pointer;&:active{color:#202020;background-color:#eee;text-decoration:none;cursor:pointer;}']); +}); +//# sourceMappingURL=styles.js.map \ No newline at end of file diff --git a/build/styles.js.map b/build/styles.js.map new file mode 100644 index 0000000..e39b35b --- /dev/null +++ b/build/styles.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/styles.js"],"names":["Wrapper","styled","div","Input","input","InputWrapper","SearchIcon","Search","ResultList","ul","Result","li","ResultLink","button"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,QAAMA,4BAAUC,2BAAOC,GAAjB;AAAA;AAAA;AAAA,uJAAN;;AAUA,QAAMC,wBAAQF,2BAAOG,KAAf;AAAA;AAAA;AAAA,wQAAN;;AAeA,QAAMC,sCAAeJ,2BAAOC,GAAtB;AAAA;AAAA;AAAA,8BAAN;;AAIA,QAAMI,kCAAa,gCAAOC,eAAP,CAAb;AAAA;AAAA;AAAA,wEAAN;;AASA,QAAMC,kCAAaP,2BAAOQ,EAApB;AAAA;AAAA;AAAA,oIAAN;;AAWA,QAAMC,0BAAST,2BAAOU,EAAhB;AAAA;AAAA;AAAA,0HAAN;;AASA,QAAMC,kCAAaX,2BAAOY,MAApB;AAAA;AAAA;AAAA,+TAAN","file":"styles.js","sourcesContent":["import styled from 'styled-components';\nimport {\n Search,\n} from 'styled-icons/fa-solid';\n\nexport const Wrapper = styled.div`\n font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;\n font-size: 14px; \n width: 100%;\n\n display: flex;\n flex-direction: column;\n align-items: stretch;\n`;\n\nexport const Input = styled.input`\n margin: 0;\n color: rgba(0,0,0,.5);\n border: 1px solid rgba(0, 0, 0, 0.125);\n padding: 10px 10px 10px 40px;\n border-radius: 5px;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n\n width: 100%;\n\n font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;\n font-size: 14px;\n`;\n\nexport const InputWrapper = styled.div`\n position: relative;\n`;\n\nexport const SearchIcon = styled(Search)`\n position: absolute;\n width: 15px;\n height: 15px;\n \n left: 10px;\n top: 12px;\n`;\n\nexport const ResultList = styled.ul`\n background-color: #fff;\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n z-index: 1000;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const Result = styled.li`\n border: 1px solid rgba(0,0,0,0.1);\n\n &:last-child {\n border-bottom-left-radius: 10px;\n border-bottom-right-radius: 10px;\n }\n`;\n\nexport const ResultLink = styled.button`\n text-align: left;\n font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;\n font-size: 14px;\n background: none;\n border: none;\n outline: inherit;\n width: 100%;\n padding: 10px;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #404040;\n cursor: pointer;\n\n &:active {\n color: #202020;\n background-color: #eee;\n text-decoration: none;\n cursor: pointer;\n }\n`;\n"]} \ No newline at end of file diff --git a/example/bundle.js b/example/bundle.js deleted file mode 100644 index 9d4ba53..0000000 --- a/example/bundle.js +++ /dev/null @@ -1,20341 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && this.state.focus == null) { - this.clickOption(this.state.results[0], 0); - } - this.acceptFocus(); - break; - } - }, - onResult: function onResult(err, res, body, searchTime) { - // searchTime is compared with the last search to set the state - // to ensure that a slow xhr response does not scramble the - // sequence of autocomplete display. - if (!err && body && body.features && this.state.searchTime <= searchTime) { - this.setState({ - searchTime: searchTime, - loading: false, - results: body.features, - focus: null - }); - this.props.onSuggest(this.state.results); - } - }, - clickOption: function clickOption(place, listLocation) { - this.props.onSelect(place); - this.setState({ focus: listLocation }); - // focus on the input after click to maintain key traversal - ReactDOM.findDOMNode(this.refs.input).focus(); - return false; - }, - render: function render() { - var _this = this; - - var input = React.createElement('input', { - ref: 'input', - className: this.props.inputClass, - onInput: this.onInput, - onKeyDown: this.onKeyDown, - placeholder: this.props.inputPlaceholder, - type: 'text' }); - return React.createElement( - 'div', - null, - this.props.inputPosition === 'top' && input, - this.state.results.length > 0 && React.createElement( - 'ul', - { className: (this.props.showLoader && this.state.loading ? 'loading' : '') + ' ' + this.props.resultsClass }, - this.state.results.map(function (result, i) { - return React.createElement( - 'li', - { key: result.id }, - React.createElement( - 'a', - { href: '#', - onClick: _this.clickOption.bind(_this, result, i), - className: _this.props.resultClass + ' ' + (i === _this.state.focus ? _this.props.resultFocusClass : ''), - key: result.id }, - result.place_name - ) - ); - }) - ), - this.props.inputPosition === 'bottom' && input - ); - } -}); - -module.exports = Geocoder; - -},{"./search":167,"react":162,"react-dom":7}],3:[function(require,module,exports){ -var isFunction = require('is-function') - -module.exports = forEach - -var toString = Object.prototype.toString -var hasOwnProperty = Object.prototype.hasOwnProperty - -function forEach(list, iterator, context) { - if (!isFunction(iterator)) { - throw new TypeError('iterator must be a function') - } - - if (arguments.length < 3) { - context = this - } - - if (toString.call(list) === '[object Array]') - forEachArray(list, iterator, context) - else if (typeof list === 'string') - forEachString(list, iterator, context) - else - forEachObject(list, iterator, context) -} - -function forEachArray(array, iterator, context) { - for (var i = 0, len = array.length; i < len; i++) { - if (hasOwnProperty.call(array, i)) { - iterator.call(context, array[i], i, array) - } - } -} - -function forEachString(string, iterator, context) { - for (var i = 0, len = string.length; i < len; i++) { - // no such thing as a sparse string. - iterator.call(context, string.charAt(i), i, string) - } -} - -function forEachObject(object, iterator, context) { - for (var k in object) { - if (hasOwnProperty.call(object, k)) { - iterator.call(context, object[k], k, object) - } - } -} - -},{"is-function":5}],4:[function(require,module,exports){ -(function (global){ -if (typeof window !== "undefined") { - module.exports = window; -} else if (typeof global !== "undefined") { - module.exports = global; -} else if (typeof self !== "undefined"){ - module.exports = self; -} else { - module.exports = {}; -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],5:[function(require,module,exports){ -module.exports = isFunction - -var toString = Object.prototype.toString - -function isFunction (fn) { - var string = toString.call(fn) - return string === '[object Function]' || - (typeof fn === 'function' && string !== '[object RegExp]') || - (typeof window !== 'undefined' && - // IE8 and below - (fn === window.setTimeout || - fn === window.alert || - fn === window.confirm || - fn === window.prompt)) -}; - -},{}],6:[function(require,module,exports){ -var trim = require('trim') - , forEach = require('for-each') - , isArray = function(arg) { - return Object.prototype.toString.call(arg) === '[object Array]'; - } - -module.exports = function (headers) { - if (!headers) - return {} - - var result = {} - - forEach( - trim(headers).split('\n') - , function (row) { - var index = row.indexOf(':') - , key = trim(row.slice(0, index)).toLowerCase() - , value = trim(row.slice(index + 1)) - - if (typeof(result[key]) === 'undefined') { - result[key] = value - } else if (isArray(result[key])) { - result[key].push(value) - } else { - result[key] = [ result[key], value ] - } - } - ) - - return result -} -},{"for-each":3,"trim":163}],7:[function(require,module,exports){ -'use strict'; - -module.exports = require('react/lib/ReactDOM'); - -},{"react/lib/ReactDOM":47}],8:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule AutoFocusMixin - * @typechecks static-only - */ - -'use strict'; - -var focusNode = require("./focusNode"); - -var AutoFocusMixin = { - componentDidMount: function() { - if (this.props.autoFocus) { - focusNode(this.getDOMNode()); - } - } -}; - -module.exports = AutoFocusMixin; - -},{"./focusNode":126}],9:[function(require,module,exports){ -/** - * Copyright 2013-2015 Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule BeforeInputEventPlugin - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var FallbackCompositionState = require("./FallbackCompositionState"); -var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); -var SyntheticInputEvent = require("./SyntheticInputEvent"); - -var keyOf = require("./keyOf"); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var canUseCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); - -var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { - documentMode = document.documentMode; -} - -// Webkit offers a very useful `textInput` event that can be used to -// directly represent `beforeInput`. The IE `textinput` event is not as -// useful, so we don't use it. -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !documentMode && - !isPresto() -); - -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. Japanese ideographic -// spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ( - ExecutionEnvironment.canUseDOM && - ( - (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) - ) -); - -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); -} - -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); - -var topLevelTypes = EventConstants.topLevelTypes; - -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) - }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] - }, - compositionEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - } -}; - -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; - -/** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. - */ -function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); -} - - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case topLevelTypes.topCompositionStart: - return eventTypes.compositionStart; - case topLevelTypes.topCompositionEnd: - return eventTypes.compositionEnd; - case topLevelTypes.topCompositionUpdate: - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyUp: - // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); - case topLevelTypes.topKeyDown: - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); - case topLevelTypes.topKeyPress: - case topLevelTypes.topMouseDown: - case topLevelTypes.topBlur: - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Google Input Tools provides composition data via a CustomEvent, - * with the `data` property populated in the `detail` object. If this - * is available on the event object, use it. If not, this is a plain - * composition event and we have nothing special to extract. - * - * @param {object} nativeEvent - * @return {?string} - */ -function getDataFromCustomEvent(nativeEvent) { - var detail = nativeEvent.detail; - if (typeof detail === 'object' && 'data' in detail) { - return detail.data; - } - return null; -} - -// Track the current IME composition fallback object, if any. -var currentComposition = null; - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticCompositionEvent. - */ -function extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var eventType; - var fallbackData; - - if (canUseCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackCompositionStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } - - if (!eventType) { - return null; - } - - if (useFallbackCompositionData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = FallbackCompositionState.getPooled(topLevelTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - fallbackData = currentComposition.getData(); - } - } - } - - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); - - if (fallbackData) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = fallbackData; - } else { - var customData = getDataFromCustomEvent(nativeEvent); - if (customData !== null) { - event.data = customData; - } - } - - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The string corresponding to this `beforeInput` event. - */ -function getNativeBeforeInputChars(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topCompositionEnd: - return getDataFromCustomEvent(nativeEvent); - case topLevelTypes.topKeyPress: - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return null; - } - - hasSpaceKeypress = true; - return SPACEBAR_CHAR; - - case topLevelTypes.topTextInput: - // Record the characters to be added to the DOM. - var chars = nativeEvent.data; - - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return null; - } - - return chars; - - default: - // For other native event types, do nothing. - return null; - } -} - -/** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The fallback string for this `beforeInput` event. - */ -function getFallbackBeforeInputChars(topLevelType, nativeEvent) { - // If we are currently composing (IME) and using a fallback to do so, - // try to extract the composed characters from the fallback object. - if (currentComposition) { - if ( - topLevelType === topLevelTypes.topCompositionEnd || - isFallbackCompositionEnd(topLevelType, nativeEvent) - ) { - var chars = currentComposition.getData(); - FallbackCompositionState.release(currentComposition); - currentComposition = null; - return chars; - } - return null; - } - - switch (topLevelType) { - case topLevelTypes.topPaste: - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - return null; - case topLevelTypes.topKeyPress: - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - return String.fromCharCode(nativeEvent.which); - } - return null; - case topLevelTypes.topCompositionEnd: - return useFallbackCompositionData ? null : nativeEvent.data; - default: - return null; - } -} - -/** - * Extract a SyntheticInputEvent for `beforeInput`, based on either native - * `textInput` or fallback behavior. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {?object} A SyntheticInputEvent. - */ -function extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { - var chars; - - if (canUseTextInputEvent) { - chars = getNativeBeforeInputChars(topLevelType, nativeEvent); - } else { - chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); - } - - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return null; - } - - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); - - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. - */ -var BeforeInputEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) { - return [ - extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ), - extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) - ]; - } -}; - -module.exports = BeforeInputEventPlugin; - -},{"./EventConstants":21,"./EventPropagators":26,"./ExecutionEnvironment":27,"./FallbackCompositionState":28,"./SyntheticCompositionEvent":100,"./SyntheticInputEvent":104,"./keyOf":148}],10:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSProperty - */ - -'use strict'; - -/** - * CSS properties which accept numbers but are not in units of "px". - */ -var isUnitlessNumber = { - boxFlex: true, - boxFlexGroup: true, - columnCount: true, - flex: true, - flexGrow: true, - flexPositive: true, - flexShrink: true, - flexNegative: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related properties - fillOpacity: true, - strokeDashoffset: true, - strokeOpacity: true, - strokeWidth: true -}; - -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} - -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; - -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); - -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true - }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true - }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true - }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true - }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true - }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true - } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; - -},{}],11:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var CSSProperty = require("./CSSProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var camelizeStyleName = require("./camelizeStyleName"); -var dangerousStyleValue = require("./dangerousStyleValue"); -var hyphenateStyleName = require("./hyphenateStyleName"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); - -var processStyleName = memoizeStringOnly(function(styleName) { - return hyphenateStyleName(styleName); -}); - -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} - -if ("production" !== process.env.NODE_ENV) { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; - - // style values shouldn't contain a semicolon - var badStyleValueWithSemicolonPattern = /;\s*$/; - - var warnedStyleNames = {}; - var warnedStyleValues = {}; - - var warnHyphenatedStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); - }; - - var warnBadVendoredStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); - }; - - var warnStyleValueWithSemicolon = function(name, value) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } - - warnedStyleValues[value] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); - }; - - /** - * @param {string} name - * @param {*} value - */ - var warnValidStyle = function(name, value) { - if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name); - } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name); - } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value); - } - }; -} - -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @return {?string} - */ - createMarkupForStyles: function(styles) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if ("production" !== process.env.NODE_ENV) { - warnValidStyle(styleName, styleValue); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - */ - setValueForStyles: function(node, styles) { - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if ("production" !== process.env.NODE_ENV) { - warnValidStyle(styleName, styles[styleName]); - } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleName === 'float') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; - -}).call(this,require('_process')) -},{"./CSSProperty":10,"./ExecutionEnvironment":27,"./camelizeStyleName":115,"./dangerousStyleValue":120,"./hyphenateStyleName":140,"./memoizeStringOnly":150,"./warning":161,"_process":164}],12:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CallbackQueue - */ - -'use strict'; - -var PooledClass = require("./PooledClass"); - -var assign = require("./Object.assign"); -var invariant = require("./invariant"); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; -} - -assign(CallbackQueue.prototype, { - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); - }, - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - ("production" !== process.env.NODE_ENV ? invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ) : invariant(callbacks.length === contexts.length)); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } - }, - - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; - }, - - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } - -}); - -PooledClass.addPoolingTo(CallbackQueue); - -module.exports = CallbackQueue; - -}).call(this,require('_process')) -},{"./Object.assign":33,"./PooledClass":34,"./invariant":142,"_process":164}],13:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ChangeEventPlugin - */ - -'use strict'; - -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); - -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementID = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - (!('documentMode' in document) || document.documentMode > 8) - ); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} - -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); -} - -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} - -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; - } -} -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForChangeEventIE8(); - } -} - - -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - (!('documentMode' in document) || document.documentMode > 9) - ); -} - -/** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function() { - return activeElementValueProp.get.call(this); - }, - set: function(val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For old IE.) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); - - Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); -} - -/** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); - - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For old IE.) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topInput) { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return topLevelTargetID; - } -} - -// For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementID; - } - } -} - - -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); -} - -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { - if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(topLevelTarget)) { - if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; - } else { - getTargetIDFunc = getTargetIDForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; - } - - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } - -}; - -module.exports = ChangeEventPlugin; - -},{"./EventConstants":21,"./EventPluginHub":23,"./EventPropagators":26,"./ExecutionEnvironment":27,"./ReactUpdates":94,"./SyntheticEvent":102,"./isEventSupported":143,"./isTextInputElement":145,"./keyOf":148}],14:[function(require,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ClientReactRootIndex - * @typechecks - */ - -'use strict'; - -var nextReactRootIndex = 0; - -var ClientReactRootIndex = { - createReactRootIndex: function() { - return nextReactRootIndex++; - } -}; - -module.exports = ClientReactRootIndex; - -},{}],15:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMChildrenOperations - * @typechecks static-only - */ - -'use strict'; - -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); - -var setTextContent = require("./setTextContent"); -var invariant = require("./invariant"); - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -function insertChildAt(parentNode, childNode, index) { - // By exploiting arrays returning `undefined` for an undefined index, we can - // rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. However, using `undefined` is not allowed by all - // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - - updateTextContent: setTextContent, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array} updates List of update configurations. - * @param {array} markupList List of markup strings. - * @internal - */ - processUpdates: function(updates, markupList) { - var update; - // Mapping from parent IDs to initial child orderings. - var initialChildren = null; - // List of children that will be moved or removed. - var updatedChildren = null; - - for (var i = 0; i < updates.length; i++) { - update = updates[i]; - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { - var updatedIndex = update.fromIndex; - var updatedChild = update.parentNode.childNodes[updatedIndex]; - var parentID = update.parentID; - - ("production" !== process.env.NODE_ENV ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a when using tables, ' + - 'nesting tags like , , or , or using non-SVG elements ' + - 'in an parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } - - for (var k = 0; k < updates.length; k++) { - update = updates[k]; - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; - -}).call(this,require('_process')) -},{"./Danger":18,"./ReactMultiChildUpdateTypes":79,"./invariant":142,"./setTextContent":156,"_process":164}],16:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -'use strict'; - -var invariant = require("./invariant"); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; - - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; - -}).call(this,require('_process')) -},{"./invariant":142,"_process":164}],17:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = require("./DOMProperty"); - -var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser"); -var warning = require("./warning"); - -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); -} - -if ("production" !== process.env.NODE_ENV) { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; - - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return; - } - - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); - - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - ("production" !== process.env.NODE_ENV ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - - }; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - return null; - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { - this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } else { - var propName = DOMProperty.getPropertyName[name]; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { - node[propName] = defaultValue; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -}).call(this,require('_process')) -},{"./DOMProperty":16,"./quoteAttributeValueForBrowser":154,"./warning":161,"_process":164}],18:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Danger - * @typechecks static-only - */ - -/*jslint evil: true, sub: true */ - -'use strict'; - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); - -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; - -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} - -var Danger = { - - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array} markupList List of markup strings to render. - * @return {array} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - ("production" !== process.env.NODE_ENV ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; - - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - var resultIndex; - for (resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - - // Push the requested markup with an additional RESULT_INDEX_ATTR - // attribute. If the markup does not start with a < character, it - // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); - } - } - - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with -
, or , or using non-SVG elements ' + - 'in an parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } - - for (var k = 0; k < updates.length; k++) { - update = updates[k]; - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; - -}).call(this,require('_process')) -},{"./Danger":18,"./ReactMultiChildUpdateTypes":79,"./invariant":142,"./setTextContent":156,"_process":164}],16:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -'use strict'; - -var invariant = require("./invariant"); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; - - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; - -}).call(this,require('_process')) -},{"./invariant":142,"_process":164}],17:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMPropertyOperations - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = require("./DOMProperty"); - -var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser"); -var warning = require("./warning"); - -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); -} - -if ("production" !== process.env.NODE_ENV) { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; - - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return; - } - - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); - - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - ("production" !== process.env.NODE_ENV ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - - }; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - return null; - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { - this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } else { - var propName = DOMProperty.getPropertyName[name]; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { - node[propName] = defaultValue; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -}).call(this,require('_process')) -},{"./DOMProperty":16,"./quoteAttributeValueForBrowser":154,"./warning":161,"_process":164}],18:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Danger - * @typechecks static-only - */ - -/*jslint evil: true, sub: true */ - -'use strict'; - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); - -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; - -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} - -var Danger = { - - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array} markupList List of markup strings to render. - * @return {array} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - ("production" !== process.env.NODE_ENV ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; - - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - var resultIndex; - for (resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - - // Push the requested markup with an additional RESULT_INDEX_ATTR - // attribute. If the markup does not start with a < character, it - // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); - } - } - - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with -