UNPKG

react-truncate-markup

Version:
1,402 lines (1,195 loc) 95.4 kB
/*! * react-truncate-markup v5.1.2 * Apache-2.0 Licensed */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react")); else if(typeof define === 'function' && define.amd) define(["react"], factory); else if(typeof exports === 'object') exports["ReactTruncateMarkup"] = factory(require("react")); else root["ReactTruncateMarkup"] = factory(root["React"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_6__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 4); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ function makeEmptyFunction(arg) { return function () { return arg; }; } /** * This function accepts and discards inputs; it has no side effects. This is * primarily useful idiomatically for overridable function endpoints which * always need to be callable, since JS lacks a null-call idiom ala Cocoa. */ var emptyFunction = function emptyFunction() {}; emptyFunction.thatReturns = makeEmptyFunction; emptyFunction.thatReturnsFalse = makeEmptyFunction(false); emptyFunction.thatReturnsTrue = makeEmptyFunction(true); emptyFunction.thatReturnsNull = makeEmptyFunction(null); emptyFunction.thatReturnsThis = function () { return this; }; emptyFunction.thatReturnsArgument = function (arg) { return arg; }; module.exports = emptyFunction; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ /** * Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */ var validateFormat = function validateFormat(format) {}; if (true) { validateFormat = function validateFormat(format) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } }; } function invariant(condition, format, a, b, c, d, e, f) { validateFormat(format); if (!condition) { var error; if (format === undefined) { error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); } else { var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error(format.replace(/%s/g, function () { return args[argIndex++]; })); error.name = 'Invariant Violation'; } error.framesToPop = 1; // we don't care about invariant's own frame throw error; } } module.exports = invariant; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ var emptyFunction = __webpack_require__(0); /** * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var warning = emptyFunction; if (true) { var printWarning = function printWarning(format) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var argIndex = 0; var message = 'Warning: ' + format.replace(/%s/g, function () { return args[argIndex++]; }); if (typeof console !== 'undefined') { console.error(message); } try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} }; warning = function warning(condition, format) { if (format === undefined) { throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); } if (format.indexOf('Failed Composite propType: ') === 0) { return; // Ignore CompositeComponent proptype check. } if (!condition) { for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { args[_key2 - 2] = arguments[_key2]; } printWarning.apply(undefined, [format].concat(args)); } }; } module.exports = warning; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; module.exports = ReactPropTypesSecret; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(5); /***/ }), /* 5 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TruncateMarkup; }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(6); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_memoize_one__ = __webpack_require__(7); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_prop_types__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_prop_types__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_line_height__ = __webpack_require__(12); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_line_height___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_line_height__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_resize_observer_polyfill__ = __webpack_require__(14); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__tokenize_rules__ = __webpack_require__(16); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__atom__ = __webpack_require__(17); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _class, _temp, _initialiseProps; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 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 SPLIT = { LEFT: true, RIGHT: false }; var toString = function toString(node) { var string = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; if (!node) { return string; } else if (typeof node === 'string') { return string + node; } else if (Object(__WEBPACK_IMPORTED_MODULE_6__atom__["c" /* isAtomComponent */])(node)) { return string + __WEBPACK_IMPORTED_MODULE_6__atom__["a" /* ATOM_STRING_ID */]; } var children = Array.isArray(node) ? node : node.props.children || ''; return string + __WEBPACK_IMPORTED_MODULE_0_react___default.a.Children.map(children, function (child) { return toString(child); }).join(''); }; var cloneWithChildren = function cloneWithChildren(node, children, isRootEl, level) { var getDisplayStyle = function getDisplayStyle() { if (isRootEl) { return { // root element cannot be an inline element because of the line calculation display: (node.props.style || {}).display || 'block' }; } else if (level === 2) { return { // level 2 elements (direct children of the root element) need to be inline because of the ellipsis. // if level 2 element was a block element, ellipsis would get rendered on a new line, breaking the max number of lines display: (node.props.style || {}).display || 'inline-block' }; } else return {}; }; return _extends({}, node, { props: _extends({}, node.props, { style: _extends({}, node.props.style, getDisplayStyle()), children: children }) }); }; var validateTree = function validateTree(node) { if (node == null || ['string', 'number'].includes(typeof node === 'undefined' ? 'undefined' : _typeof(node)) || Object(__WEBPACK_IMPORTED_MODULE_6__atom__["c" /* isAtomComponent */])(node)) { return true; } else if (typeof node.type === 'function') { if (true) { /* eslint-disable no-console */ console.error('ReactTruncateMarkup tried to render <' + node.type.name + ' />, but truncating React components is not supported, the full content is rendered instead. Only DOM elements are supported. Alternatively, you can take advantage of the <TruncateMarkup.Atom /> component (see more in the docs https://github.com/patrik-piskay/react-truncate-markup/blob/master/README.md#truncatemarkupatom-).'); /* eslint-enable */ } return false; } if (node.props && node.props.children) { return __WEBPACK_IMPORTED_MODULE_0_react___default.a.Children.toArray(node.props.children).reduce(function (isValid, child) { return isValid && validateTree(child); }, true); } return true; }; var TruncateMarkup = (_temp = _class = function (_React$Component) { _inherits(TruncateMarkup, _React$Component); function TruncateMarkup(props) { _classCallCheck(this, TruncateMarkup); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _initialiseProps.call(_this); _this.state = { text: _this.childrenWithRefMemo(_this.props.children) }; return _this; } TruncateMarkup.prototype.componentDidMount = function componentDidMount() { if (!this.isValid) { return; } // get the computed line-height of the parent element // it'll be used for determining whether the text fits the container or not this.lineHeight = this.props.lineHeight || __WEBPACK_IMPORTED_MODULE_3_line_height___default()(this.el); this.truncate(); }; TruncateMarkup.prototype.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) { var _this2 = this; this.shouldTruncate = false; this.latestThatFits = null; this.setState({ text: this.childrenWithRefMemo(nextProps.children) }, function () { if (!_this2.isValid) { return; } _this2.lineHeight = nextProps.lineHeight || __WEBPACK_IMPORTED_MODULE_3_line_height___default()(_this2.el); _this2.shouldTruncate = true; _this2.truncate(); }); }; TruncateMarkup.prototype.componentDidUpdate = function componentDidUpdate() { if (this.shouldTruncate === false || this.isValid === false) { return; } if (this.endFound) { // we've found the end where we cannot split the text further // that means we've already found the max subtree that fits the container // so we are rendering that if (this.latestThatFits !== null && this.state.text !== this.latestThatFits) { /* eslint-disable react/no-did-update-set-state */ this.setState({ text: this.latestThatFits }); return; /* eslint-enable */ } this.onTruncate( /* wasTruncated */true); return; } if (this.splitDirectionSeq.length) { if (this.fits()) { this.latestThatFits = this.state.text; // we've found a subtree that fits the container // but we need to check if we didn't cut too much of it off // so we are changing the last splitting decision from splitting and going left // to splitting and going right this.splitDirectionSeq.splice(this.splitDirectionSeq.length - 1, 1, SPLIT.RIGHT, SPLIT.LEFT); } else { this.splitDirectionSeq.push(SPLIT.LEFT); } this.tryToFit(this.origText, this.splitDirectionSeq); } }; TruncateMarkup.prototype.componentWillUnmount = function componentWillUnmount() { this.lineHeight = null; this.latestThatFits = null; this.splitDirectionSeq = []; }; TruncateMarkup.prototype.truncate = function truncate() { if (this.fits()) { // the whole text fits on the first try, no need to do anything else this.shouldTruncate = false; this.onTruncate( /* wasTruncated */false); return; } this.truncateOriginalText(); }; TruncateMarkup.prototype.childrenElementWithRef = function childrenElementWithRef(children) { var child = __WEBPACK_IMPORTED_MODULE_0_react___default.a.Children.only(children); return __WEBPACK_IMPORTED_MODULE_0_react___default.a.cloneElement(child, { ref: this.setRef, style: _extends({ wordWrap: 'break-word' }, child.props.style) }); }; TruncateMarkup.prototype.truncateOriginalText = function truncateOriginalText() { this.endFound = false; this.splitDirectionSeq = [SPLIT.LEFT]; this.wasLastCharTested = false; this.tryToFit(this.origText, this.splitDirectionSeq); }; /** * Splits rootEl based on instructions and updates React's state with the returned element * After React rerenders the new text, we'll check if the new text fits in componentDidUpdate * @param {ReactElement} rootEl - the original children element * @param {Array} splitDirections - list of SPLIT.RIGHT/LEFT instructions */ TruncateMarkup.prototype.tryToFit = function tryToFit(rootEl, splitDirections) { if (!rootEl.props.children) { // no markup in container return; } var newRootEl = this.split(rootEl, splitDirections, /* isRootEl */true); var ellipsis = typeof this.props.ellipsis === 'function' ? this.props.ellipsis(newRootEl) : this.props.ellipsis; ellipsis = (typeof ellipsis === 'undefined' ? 'undefined' : _typeof(ellipsis)) === 'object' ? __WEBPACK_IMPORTED_MODULE_0_react___default.a.cloneElement(ellipsis, { key: 'ellipsis' }) : ellipsis; var newChildren = newRootEl.props.children; var newChildrenWithEllipsis = [].concat(newChildren, ellipsis); // edge case tradeoff EC#1 - on initial render it doesn't fit in the requested number of lines (1) so it starts truncating // - because of truncating and the ellipsis position, div#lvl2 will have display set to 'inline-block', // causing the whole body to fit in 1 line again // - if that happens, ellipsis is not needed anymore as the whole body is rendered // - NOTE this could be fixed by checking for this exact case and handling it separately so it renders <div>foo {ellipsis}</div> // // Example: // <TruncateMarkup lines={1}> // <div> // foo // <div id="lvl2">bar</div> // </div> // </TruncateMarkup> var shouldRenderEllipsis = toString(newChildren) !== this.toStringMemo(this.props.children); this.setState({ text: _extends({}, newRootEl, { props: _extends({}, newRootEl.props, { children: shouldRenderEllipsis ? newChildrenWithEllipsis : newChildren }) }) }); }; /** * Splits JSX node based on its type * @param {null|string|Array|Object} node - JSX node * @param {Array} splitDirections - list of SPLIT.RIGHT/LEFT instructions * @return {null|string|Array|Object} - split JSX node */ TruncateMarkup.prototype.split = function split(node, splitDirections) { var isRoot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var level = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; if (!node || Object(__WEBPACK_IMPORTED_MODULE_6__atom__["c" /* isAtomComponent */])(node)) { this.endFound = true; return node; } else if (typeof node === 'string') { return this.splitString(node, splitDirections, level); } else if (Array.isArray(node)) { return this.splitArray(node, splitDirections, level); } var newChildren = this.split(node.props.children, splitDirections, /* isRoot */false, level + 1); return cloneWithChildren(node, newChildren, isRoot, level); }; TruncateMarkup.prototype.splitString = function splitString(string) { var splitDirections = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var level = arguments[2]; if (!splitDirections.length) { return string; } if (splitDirections.length && this.policy.isAtomic(string)) { // allow for an extra render test with the current character included // in most cases this variation was already tested, but some edge cases require this check // NOTE could be removed once EC#1 is taken care of if (!this.wasLastCharTested) { this.wasLastCharTested = true; } else { // we are trying to split further but we have nowhere to go now // that means we've already found the max subtree that fits the container this.endFound = true; } return string; } if (this.policy.tokenizeString) { var wordsArray = this.splitArray(this.policy.tokenizeString(string), splitDirections, level); // in order to preserve the input structure return wordsArray.join(''); } var splitDirection = splitDirections[0], restSplitDirections = splitDirections.slice(1); var pivotIndex = Math.ceil(string.length / 2); var beforeString = string.substring(0, pivotIndex); if (splitDirection === SPLIT.LEFT) { return this.splitString(beforeString, restSplitDirections, level); } var afterString = string.substring(pivotIndex); return beforeString + this.splitString(afterString, restSplitDirections, level); }; TruncateMarkup.prototype.splitArray = function splitArray(array) { var splitDirections = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var level = arguments[2]; if (!splitDirections.length) { return array; } if (array.length === 1) { return [this.split(array[0], splitDirections, /* isRoot */false, level)]; } var splitDirection = splitDirections[0], restSplitDirections = splitDirections.slice(1); var pivotIndex = Math.ceil(array.length / 2); var beforeArray = array.slice(0, pivotIndex); if (splitDirection === SPLIT.LEFT) { return this.splitArray(beforeArray, restSplitDirections, level); } var afterArray = array.slice(pivotIndex); return beforeArray.concat(this.splitArray(afterArray, restSplitDirections, level)); }; TruncateMarkup.prototype.fits = function fits() { var maxLines = this.props.lines; var _el$getBoundingClient = this.el.getBoundingClientRect(), height = _el$getBoundingClient.height; var computedLines = Math.round(height / parseFloat(this.lineHeight)); return maxLines >= computedLines; }; TruncateMarkup.prototype.render = function render() { return this.state.text; }; _createClass(TruncateMarkup, [{ key: 'isValid', get: function get() { return this.validateTreeMemo(this.props.children); } }, { key: 'origText', get: function get() { return this.childrenWithRefMemo(this.props.children); } }, { key: 'policy', get: function get() { return __WEBPACK_IMPORTED_MODULE_5__tokenize_rules__["a" /* default */][this.props.tokenize] || __WEBPACK_IMPORTED_MODULE_5__tokenize_rules__["a" /* default */].characters; } }]); return TruncateMarkup; }(__WEBPACK_IMPORTED_MODULE_0_react___default.a.Component), _class.Atom = __WEBPACK_IMPORTED_MODULE_6__atom__["b" /* Atom */], _class.propTypes = { children: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.element.isRequired, lines: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.number, ellipsis: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.oneOfType([__WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.element, __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.func]), lineHeight: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.oneOfType([__WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.string, __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.number]), onTruncate: __WEBPACK_IMPORTED_MODULE_2_prop_types___default.a.func, // eslint-disable-next-line onAfterTruncate: function onAfterTruncate(props, propName, componentName) { if (props[propName]) { return new Error(componentName + ': Setting `onAfterTruncate` prop is deprecated, use `onTruncate` instead.'); } }, tokenize: function tokenize(props, propName, componentName) { var tokenizeValue = props[propName]; if (typeof tokenizeValue !== 'undefined') { if (!__WEBPACK_IMPORTED_MODULE_5__tokenize_rules__["a" /* default */][tokenizeValue]) { /* eslint-disable no-console */ return new Error(componentName + ': Unknown option for prop \'tokenize\': \'' + tokenizeValue + '\'. Option \'characters\' will be used instead.'); /* eslint-enable */ } } } }, _class.defaultProps = { lines: 1, ellipsis: '...', lineHeight: '', onTruncate: function onTruncate() {}, tokenize: 'characters' }, _initialiseProps = function _initialiseProps() { var _this3 = this; this.lineHeight = null; this.splitDirectionSeq = []; this.shouldTruncate = true; this.wasLastCharTested = false; this.endFound = false; this.latestThatFits = null; this.onTruncateCalled = false; this.toStringMemo = Object(__WEBPACK_IMPORTED_MODULE_1_memoize_one__["a" /* default */])(toString); this.childrenWithRefMemo = Object(__WEBPACK_IMPORTED_MODULE_1_memoize_one__["a" /* default */])(this.childrenElementWithRef); this.validateTreeMemo = Object(__WEBPACK_IMPORTED_MODULE_1_memoize_one__["a" /* default */])(validateTree); this.onTruncate = function (wasTruncated) { if (!_this3.onTruncateCalled) { _this3.onTruncateCalled = true; _this3.props.onTruncate(wasTruncated); } }; this.handleResize = function (el, prevResizeObserver) { // clean up previous observer if (prevResizeObserver) { prevResizeObserver.disconnect(); } // unmounting or just unsetting the element to be replaced with a new one later if (!el) return null; /* Wrapper element resize handing */ var initialRender = true; var resizeCallback = function resizeCallback() { if (initialRender) { // ResizeObserer cb is called on initial render too so we are skipping here initialRender = false; } else { // wrapper element has been resized, recalculating with the original text _this3.shouldTruncate = false; _this3.latestThatFits = null; _this3.setState({ text: _this3.origText }, function () { _this3.shouldTruncate = true; _this3.onTruncateCalled = false; _this3.truncate(); }); } }; var resizeObserver = prevResizeObserver || new __WEBPACK_IMPORTED_MODULE_4_resize_observer_polyfill__["a" /* default */](resizeCallback); resizeObserver.observe(el); return resizeObserver; }; this.setRef = function (el) { var isNewEl = _this3.el !== el; _this3.el = el; // whenever we obtain a new element, attach resize handler if (isNewEl) { _this3.resizeObserver = _this3.handleResize(el, _this3.resizeObserver); } }; }, _temp); /***/ }), /* 6 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_6__; /***/ }), /* 7 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; function areInputsEqual(newInputs, lastInputs) { if (newInputs.length !== lastInputs.length) { return false; } for (var i = 0; i < newInputs.length; i++) { if (newInputs[i] !== lastInputs[i]) { return false; } } return true; } function memoizeOne(resultFn, isEqual) { if (isEqual === void 0) { isEqual = areInputsEqual; } var lastThis; var lastArgs = []; var lastResult; var calledOnce = false; function memoized() { var newArgs = []; for (var _i = 0; _i < arguments.length; _i++) { newArgs[_i] = arguments[_i]; } if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) { return lastResult; } lastResult = resultFn.apply(this, newArgs); calledOnce = true; lastThis = this; lastArgs = newArgs; return lastResult; } return memoized; } /* harmony default export */ __webpack_exports__["a"] = (memoizeOne); /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ if (true) { var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) || 0xeac7; var isValidElement = function(object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; }; // By explicitly using `prop-types` you are opting into new development behavior. // http://fb.me/prop-types-in-prod var throwOnDirectAccess = true; module.exports = __webpack_require__(9)(isValidElement, throwOnDirectAccess); } else { // By explicitly using `prop-types` you are opting into new production behavior. // http://fb.me/prop-types-in-prod module.exports = require('./factoryWithThrowingShims')(); } /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var emptyFunction = __webpack_require__(0); var invariant = __webpack_require__(1); var warning = __webpack_require__(2); var assign = __webpack_require__(10); var ReactPropTypesSecret = __webpack_require__(3); var checkPropTypes = __webpack_require__(11); module.exports = function(isValidElement, throwOnDirectAccess) { /* global Symbol */ var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. /** * Returns the iterator method function contained on the iterable object. * * Be sure to invoke the function with the iterable as context: * * var iteratorFn = getIteratorFn(myIterable); * if (iteratorFn) { * var iterator = iteratorFn.call(myIterable); * ... * } * * @param {?object} maybeIterable * @return {?function} */ function getIteratorFn(maybeIterable) { var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); if (typeof iteratorFn === 'function') { return iteratorFn; } } /** * Collection of methods that allow declaration and validation of props that are * supplied to React components. Example usage: * * var Props = require('ReactPropTypes'); * var MyArticle = React.createClass({ * propTypes: { * // An optional string prop named "description". * description: Props.string, * * // A required enum prop named "category". * category: Props.oneOf(['News','Photos']).isRequired, * * // A prop named "dialog" that requires an instance of Dialog. * dialog: Props.instanceOf(Dialog).isRequired * }, * render: function() { ... } * }); * * A more formal specification of how these methods are used: * * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) * decl := ReactPropTypes.{type}(.isRequired)? * * Each and every declaration produces a function with the same signature. This * allows the creation of custom validation functions. For example: * * var MyLink = React.createClass({ * propTypes: { * // An optional string or URI prop named "href". * href: function(props, propName, componentName) { * var propValue = props[propName]; * if (propValue != null && typeof propValue !== 'string' && * !(propValue instanceof URI)) { * return new Error( * 'Expected a string or an URI for ' + propName + ' in ' + * componentName * ); * } * } * }, * render: function() {...} * }); * * @internal */ var ANONYMOUS = '<<anonymous>>'; // Important! // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. var ReactPropTypes = { array: createPrimitiveTypeChecker('array'), bool: createPrimitiveTypeChecker('boolean'), func: createPrimitiveTypeChecker('function'), number: createPrimitiveTypeChecker('number'), object: createPrimitiveTypeChecker('object'), string: createPrimitiveTypeChecker('string'), symbol: createPrimitiveTypeChecker('symbol'), any: createAnyTypeChecker(), arrayOf: createArrayOfTypeChecker, element: createElementTypeChecker(), instanceOf: createInstanceTypeChecker, node: createNodeChecker(), objectOf: createObjectOfTypeChecker, oneOf: createEnumTypeChecker, oneOfType: createUnionTypeChecker, shape: createShapeTypeChecker, exact: createStrictShapeTypeChecker, }; /** * inlined Object.is polyfill to avoid requiring consumers ship their own * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is */ /*eslint-disable no-self-compare*/ function is(x, y) { // SameValue algorithm if (x === y) { // Steps 1-5, 7-10 // Steps 6.b-6.e: +0 != -0 return x !== 0 || 1 / x === 1 / y; } else { // Step 6.a: NaN == NaN return x !== x && y !== y; } } /*eslint-enable no-self-compare*/ /** * We use an Error-like object for backward compatibility as people may call * PropTypes directly and inspect their output. However, we don't use real * Errors anymore. We don't inspect their stack anyway, and creating them * is prohibitively expensive if they are created too often, such as what * happens in oneOfType() for any type before the one that matched. */ function PropTypeError(message) { this.message = message; this.stack = ''; } // Make `instanceof Error` still work for returned errors. PropTypeError.prototype = Error.prototype; function createChainableTypeChecker(validate) { if (true) { var manualPropTypeCallCache = {}; var manualPropTypeWarningCount = 0; } function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { componentName = componentName || ANONYMOUS; propFullName = propFullName || propName; if (secret !== ReactPropTypesSecret) { if (throwOnDirectAccess) { // New behavior only for users of `prop-types` package invariant( false, 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use `PropTypes.checkPropTypes()` to call them. ' + 'Read more at http://fb.me/use-check-prop-types' ); } else if ("development" !== 'production' && typeof console !== 'undefined') { // Old behavior for people using React.PropTypes var cacheKey = componentName + ':' + propName; if ( !manualPropTypeCallCache[cacheKey] && // Avoid spamming the console because they are often not actionable except for lib authors manualPropTypeWarningCount < 3 ) { warning( false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will throw in the standalone `prop-types` package. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName ); manualPropTypeCallCache[cacheKey] = true; manualPropTypeWarningCount++; } } } if (props[propName] == null) { if (isRequired) { if (props[propName] === null) { return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); } return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); } return null; } else { return validate(props, propName, componentName, location, propFullName); } } var chainedCheckType = checkType.bind(null, false); chainedCheckType.isRequired = checkType.bind(null, true); return chainedCheckType; } function createPrimitiveTypeChecker(expectedType) { function validate(props, propName, componentName, location, propFullName, secret) { var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== expectedType) { // `propValue` being instance of, say, date/regexp, pass the 'object' // check, but we can offer a more precise error message here rather than // 'of type `object`'. var preciseType = getPreciseType(propValue); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); } return null; } return createChainableTypeChecker(validate); } function createAnyTypeChecker() { return createChainableTypeChecker(emptyFunction.thatReturnsNull); } function createArrayOfTypeChecker(typeChecker) { function validate(props, propName, componentName, location, propFullName) { if (typeof typeChecker !== 'function') { return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); } var propValue = props[propName]; if (!Array.isArray(propValue)) { var propType = getPropType(propValue); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); } for (var i = 0; i < propValue.length; i++) { var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); if (error instanceof Error) { return error; } } return null; } return createChainableTypeChecker(validate); } function createElementTypeChecker() { function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; if (!isValidElement(propValue)) { var propType = getPropType(propValue); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); } return null; } return createChainableTypeChecker(validate); } function createInstanceTypeChecker(expectedClass) { function validate(props, propName, componentName, location, propFullName) { if (!(props[propName] instanceof expectedClass)) { var expectedClassName = expectedClass.name || ANONYMOUS; var actualClassName = getClassName(props[propName]); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); } return null; } return createChainableTypeChecker(validate); } function createEnumTypeChecker(expectedValues) { if (!Array.isArray(expectedValues)) { true ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; return emptyFunction.thatReturnsNull; } function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; for (var i = 0; i < expectedValues.length; i++) { if (is(propValue, expectedValues[i])) { return null; } } var valuesString = JSON.stringify(expectedValues); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); } return createChainableTypeChecker(validate); } function createObjectOfTypeChecker(typeChecker) { function validate(props, propName, componentName, location, propFullName) { if (typeof typeChecker !== 'function') { return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); } var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== 'object') { return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); } for (var key in propValue) { if (propValue.hasOwnProperty(key)) { var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); if (error instanceof Error) { return error; } } } return null; } return createChainableTypeChecker(validate); } function createUnionTypeChecker(arrayOfTypeCheckers) { if (!Array.isArray(arrayOfTypeCheckers)) { true ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; return emptyFunction.thatReturnsNull; } for (var i = 0; i < arrayOfTypeCheckers.length; i++) { var checker = arrayOfTypeCheckers[i]; if (typeof checker !== 'function') { warning( false, 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + 'received %s at index %s.', getPostfixForTypeWarning(checker), i ); return emptyFunction.thatReturnsNull; } } function validate(props, propName, componentName, location, propFullName) { for (var i = 0; i < arrayOfTypeCheckers.length; i++) { var checker = arrayOfTypeCheckers[i]; if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { return null; } } return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); } return createChainableTypeChecker(validate); } function createNodeChecker() { function validate(props, propName, componentName, location, propFullName) { if (!isNode(props[propName])) { return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); } return null; } return createChainableTypeChecker(validate); } function createShapeTypeChecker(shapeTypes) { function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== 'object') { return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); } for (var key in shapeTypes) { var checker = shapeTypes[key]; if (!checker) { continue; } var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); if (error) { return error; } } return null; } return createChainableTypeChecker(validate); } function createStrictShapeTypeChecker(shapeTypes) { function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== 'object') { return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); } // We need to check all keys in case some are required but missing from // props. var allKeys = assign({}, props[propName], shapeTypes); for (var key in allKeys) { var checker = shapeTypes[key]; if (!checker) { return new PropTypeError( 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') ); } var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); if (error) { return error; } } return null; } return createChainableTypeChecker(validate); } function isNode(propValue) { switch (typeof propValue) { case 'number': case 'string': case 'undefined': return true; case 'boolean': return !propValue; case 'object': if (Array.isArray(propValue)) { return propValue.every(isNode); } if (propValue === null || isValidElement(propValue)) { return true; } var iteratorFn = getIteratorFn(propValue); if (iteratorFn) { var iterator = iteratorFn.call(propValue); var step; if (iteratorFn !== propValue.entries) { while (!(step = iterator.next()).done) { if (!isNode(step.value)) { return false; } } } else { // Iterator will provide entry [k,v] tuples rather than values. while (!(step = iterator.next()).done) { var entry = step.value; if (entry) { if (!isNode(entry[1])) { return false; } } } } } else { return false; } return true; default: return false; } } function isSymbol(propType, propValue) { // Native Symbol. if (propType === 'symbol') { return true; } // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' if (propValue['@@toStringTag'] === 'Symbol') { return true; } // Fallback for non-spec compliant Symbols which are polyfilled. if (typeof Symbol === 'function' && propValue instanceof Symbol) { return true; } return false; } // Equivalent of `typeof` but with special handling for array and regexp. function getPropType(propValue) { var propType = typeof propValue; if (Array.isArray(propValue)) { return 'array'; } if (propValue instanceof RegExp) { // Old webkits (at least until Android 4.0) return 'function' rather than // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ // passes PropTypes.object. return 'object'; } if (isSymbol(propType, propValue)) { return 'symbol'; } return propType; } // This handles more types than `getPropType`. Only used for error messages. // See `createPrimitiveTypeChecker`. function getPreciseType(propValue) { if (typeof propValue === 'undefined' || propValue === null) { return '' + propValue; } var propType = getPropType(propValue); if (propType === 'object') { if (propValue instanceof Date) { return 'date'; } else if (propValue instanceof RegExp) { return 'regexp'; } } return propType; } // Returns a string that is postfixed to a warning about an invalid type. // For example, "undefined" or "of type array" function getPostfixForTypeWarning(value) { var type = getPreciseType(value); switch (type) { case 'array': case 'object': return 'an ' + type; case 'boolean': case 'date': case 'regexp': return 'a ' + type; default: return type; } } // Returns class name of the object, if any. function getClassName(propValue) { if (!propValue.constructor || !propValue.constructor.name) { return