Last active
April 25, 2016 16:23
-
-
Save ehzhang/362ca6d74a584a59ca6c to your computer and use it in GitHub Desktop.
test cellClassName fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* FixedDataTable v0.3.0 | |
* | |
* Copyright (c) 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. | |
*/ | |
(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["FixedDataTable"] = factory(require("react")); | |
else | |
root["FixedDataTable"] = factory(root["React"]); | |
})(this, function(__WEBPACK_EXTERNAL_MODULE_23__) { | |
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] = { | |
/******/ exports: {}, | |
/******/ id: moduleId, | |
/******/ loaded: false | |
/******/ }; | |
/******/ // Execute the module function | |
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
/******/ // Flag the module as loaded | |
/******/ module.loaded = 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; | |
/******/ // __webpack_public_path__ | |
/******/ __webpack_require__.p = ""; | |
/******/ // Load entry module and return exports | |
/******/ return __webpack_require__(0); | |
/******/ }) | |
/************************************************************************/ | |
/******/ ([ | |
/* 0 */ | |
/***/ function(module, exports, __webpack_require__) { | |
__webpack_require__(1); | |
__webpack_require__(5); | |
__webpack_require__(7); | |
__webpack_require__(9); | |
__webpack_require__(11); | |
__webpack_require__(13); | |
module.exports = __webpack_require__(15); | |
/***/ }, | |
/* 1 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 2 */, | |
/* 3 */, | |
/* 4 */, | |
/* 5 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 6 */, | |
/* 7 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 8 */, | |
/* 9 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 10 */, | |
/* 11 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 12 */, | |
/* 13 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 14 */, | |
/* 15 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableRoot | |
*/ | |
'use strict'; | |
var FixedDataTable = __webpack_require__(16); | |
var FixedDataTableColumn = __webpack_require__(25); | |
var FixedDataTableColumnGroup = __webpack_require__(24); | |
var FixedDataTableRoot = { | |
Column: FixedDataTableColumn, | |
ColumnGroup: FixedDataTableColumnGroup, | |
Table: FixedDataTable | |
}; | |
FixedDataTableRoot.version = '0.3.0'; | |
module.exports = FixedDataTableRoot; | |
/***/ }, | |
/* 16 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTable.react | |
* @typechecks | |
*/ | |
/* jslint bitwise: true */ | |
'use strict'; | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
var FixedDataTableHelper = __webpack_require__(20); | |
var Locale = __webpack_require__(21); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var ReactWheelHandler = __webpack_require__(42); | |
var Scrollbar = __webpack_require__(50); | |
var FixedDataTableBufferedRows = __webpack_require__(62); | |
var FixedDataTableColumnResizeHandle = __webpack_require__(76); | |
var FixedDataTableRow = __webpack_require__(66); | |
var FixedDataTableScrollHelper = __webpack_require__(17); | |
var FixedDataTableWidthHelper = __webpack_require__(77); | |
var cloneWithProps = __webpack_require__(26); | |
var cx = __webpack_require__(56); | |
var debounceCore = __webpack_require__(78); | |
var emptyFunction = __webpack_require__(43); | |
var invariant = __webpack_require__(61); | |
var shallowEqual = __webpack_require__(79); | |
var translateDOMPositionXY = __webpack_require__(57); | |
var PropTypes = React.PropTypes; | |
var ReactChildren = React.Children; | |
var renderToString = FixedDataTableHelper.renderToString; | |
var EMPTY_OBJECT = {}; | |
var BORDER_HEIGHT = 1; | |
/** | |
* Data grid component with fixed or scrollable header and columns. | |
* | |
* The layout of the data table is as follows: | |
* | |
* ``` | |
* +---------------------------------------------------+ | |
* | Fixed Column Group | Scrollable Column Group | | |
* | Header | Header | | |
* | | | | |
* +---------------------------------------------------+ | |
* | | | | |
* | Fixed Header Columns | Scrollable Header Columns | | |
* | | | | |
* +-----------------------+---------------------------+ | |
* | | | | |
* | Fixed Body Columns | Scrollable Body Columns | | |
* | | | | |
* +-----------------------+---------------------------+ | |
* | | | | |
* | Fixed Footer Columns | Scrollable Footer Columns | | |
* | | | | |
* +-----------------------+---------------------------+ | |
* ``` | |
* | |
* - Fixed Column Group Header: These are the headers for a group | |
* of columns if included in the table that do not scroll | |
* vertically or horizontally. | |
* | |
* - Scrollable Column Group Header: The header for a group of columns | |
* that do not move while scrolling vertically, but move horizontally | |
* with the horizontal scrolling. | |
* | |
* - Fixed Header Columns: The header columns that do not move while scrolling | |
* vertically or horizontally. | |
* | |
* - Scrollable Header Columns: The header columns that do not move | |
* while scrolling vertically, but move horizontally with the horizontal | |
* scrolling. | |
* | |
* - Fixed Body Columns: The body columns that do not move while scrolling | |
* horizontally, but move vertically with the vertical scrolling. | |
* | |
* - Scrollable Body Columns: The body columns that move while scrolling | |
* vertically or horizontally. | |
*/ | |
var FixedDataTable = React.createClass({ | |
displayName: 'FixedDataTable', | |
propTypes: { | |
/** | |
* Pixel width of table. If all columns do not fit, | |
* a horizontal scrollbar will appear. | |
*/ | |
width: PropTypes.number.isRequired, | |
/** | |
* Pixel height of table. If all rows do not fit, | |
* a vertical scrollbar will appear. | |
* | |
* Either `height` or `maxHeight` must be specified. | |
*/ | |
height: PropTypes.number, | |
/** | |
* Maximum pixel height of table. If all rows do not fit, | |
* a vertical scrollbar will appear. | |
* | |
* Either `height` or `maxHeight` must be specified. | |
*/ | |
maxHeight: PropTypes.number, | |
/** | |
* Pixel height of table's owner, this is used in a managed scrolling | |
* situation when you want to slide the table up from below the fold | |
* without having to constantly update the height on every scroll tick. | |
* Instead, vary this property on scroll. By using `ownerHeight`, we | |
* over-render the table while making sure the footer and horizontal | |
* scrollbar of the table are visible when the current space for the table | |
* in view is smaller than the final, over-flowing height of table. It | |
* allows us to avoid resizing and reflowing table when it is moving in the | |
* view. | |
* | |
* This is used if `ownerHeight < height` (or `maxHeight`). | |
*/ | |
ownerHeight: PropTypes.number, | |
overflowX: PropTypes.oneOf(['hidden', 'auto']), | |
overflowY: PropTypes.oneOf(['hidden', 'auto']), | |
/** | |
* Number of rows in the table. | |
*/ | |
rowsCount: PropTypes.number.isRequired, | |
/** | |
* Pixel height of rows unless `rowHeightGetter` is specified and returns | |
* different value. | |
*/ | |
rowHeight: PropTypes.number.isRequired, | |
/** | |
* If specified, `rowHeightGetter(index)` is called for each row and the | |
* returned value overrides `rowHeight` for particular row. | |
*/ | |
rowHeightGetter: PropTypes.func, | |
/** | |
* To get rows to display in table, `rowGetter(index)` | |
* is called. `rowGetter` should be smart enough to handle async | |
* fetching of data and return temporary objects | |
* while data is being fetched. | |
*/ | |
rowGetter: PropTypes.func.isRequired, | |
/** | |
* To get any additional CSS classes that should be added to a row, | |
* `rowClassNameGetter(index)` is called. | |
*/ | |
rowClassNameGetter: PropTypes.func, | |
/** | |
* Pixel height of the column group header. | |
*/ | |
groupHeaderHeight: PropTypes.number, | |
/** | |
* Pixel height of header. | |
*/ | |
headerHeight: PropTypes.number.isRequired, | |
/** | |
* Function that is called to get the data for the header row. | |
*/ | |
headerDataGetter: PropTypes.func, | |
/** | |
* Pixel height of footer. | |
*/ | |
footerHeight: PropTypes.number, | |
/** | |
* DEPRECATED - use footerDataGetter instead. | |
* Data that will be passed to footer cell renderers. | |
*/ | |
footerData: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), | |
/** | |
* Function that is called to get the data for the footer row. | |
*/ | |
footerDataGetter: PropTypes.func, | |
/** | |
* Value of horizontal scroll. | |
*/ | |
scrollLeft: PropTypes.number, | |
/** | |
* Index of column to scroll to. | |
*/ | |
scrollToColumn: PropTypes.number, | |
/** | |
* Value of vertical scroll. | |
*/ | |
scrollTop: PropTypes.number, | |
/** | |
* Index of row to scroll to. | |
*/ | |
scrollToRow: PropTypes.number, | |
/** | |
* Callback that is called when scrolling ends or stops with new horizontal | |
* and vertical scroll values. | |
*/ | |
onScrollEnd: PropTypes.func, | |
/** | |
* Callback that is called when `rowHeightGetter` returns a different height | |
* for a row than the `rowHeight` prop. This is necessary because initially | |
* table estimates heights of some parts of the content. | |
*/ | |
onContentHeightChange: PropTypes.func, | |
/** | |
* Callback that is called when a row is clicked. | |
*/ | |
onRowClick: PropTypes.func, | |
/** | |
* Callback that is called when a row is double clicked. | |
*/ | |
onRowDoubleClick: PropTypes.func, | |
/** | |
* Callback that is called when a mouse-down event happens on a row. | |
*/ | |
onRowMouseDown: PropTypes.func, | |
/** | |
* Callback that is called when a mouse-enter event happens on a row. | |
*/ | |
onRowMouseEnter: PropTypes.func, | |
/** | |
* Callback that is called when a mouse-leave event happens on a row. | |
*/ | |
onRowMouseLeave: PropTypes.func, | |
/** | |
* Callback that is called when resizer has been released | |
* and column needs to be updated. | |
* | |
* Required if the isResizable property is true on any column. | |
* | |
* ``` | |
* function( | |
* newColumnWidth: number, | |
* dataKey: string, | |
* ) | |
* ``` | |
*/ | |
onColumnResizeEndCallback: PropTypes.func, | |
/** | |
* Whether a column is currently being resized. | |
*/ | |
isColumnResizing: PropTypes.bool | |
}, | |
getDefaultProps: function getDefaultProps() /*object*/{ | |
return { | |
footerHeight: 0, | |
groupHeaderHeight: 0, | |
headerHeight: 0, | |
scrollLeft: 0, | |
scrollTop: 0 | |
}; | |
}, | |
getInitialState: function getInitialState() /*object*/{ | |
var props = this.props; | |
var viewportHeight = props.height - props.headerHeight - props.footerHeight - props.groupHeaderHeight; | |
this._scrollHelper = new FixedDataTableScrollHelper(props.rowsCount, props.rowHeight, viewportHeight, props.rowHeightGetter); | |
if (props.scrollTop) { | |
this._scrollHelper.scrollTo(props.scrollTop); | |
} | |
this._didScrollStop = debounceCore(this._didScrollStop, 160, this); | |
return this._calculateState(this.props); | |
}, | |
componentWillMount: function componentWillMount() { | |
var scrollToRow = this.props.scrollToRow; | |
if (scrollToRow !== undefined && scrollToRow !== null) { | |
this._rowToScrollTo = scrollToRow; | |
} | |
var scrollToColumn = this.props.scrollToColumn; | |
if (scrollToColumn !== undefined && scrollToColumn !== null) { | |
this._columnToScrollTo = scrollToColumn; | |
} | |
this._wheelHandler = new ReactWheelHandler(this._onWheel, this._shouldHandleWheelX, this._shouldHandleWheelY); | |
}, | |
_shouldHandleWheelX: function _shouldHandleWheelX( /*number*/delta) /*boolean*/{ | |
if (this.props.overflowX === 'hidden') { | |
return false; | |
} | |
delta = Math.round(delta); | |
if (delta === 0) { | |
return false; | |
} | |
return delta < 0 && this.state.scrollX > 0 || delta >= 0 && this.state.scrollX < this.state.maxScrollX; | |
}, | |
_shouldHandleWheelY: function _shouldHandleWheelY( /*number*/delta) /*boolean*/{ | |
if (this.props.overflowY === 'hidden' || delta === 0) { | |
return false; | |
} | |
delta = Math.round(delta); | |
if (delta === 0) { | |
return false; | |
} | |
return delta < 0 && this.state.scrollY > 0 || delta >= 0 && this.state.scrollY < this.state.maxScrollY; | |
}, | |
_reportContentHeight: function _reportContentHeight() { | |
var scrollContentHeight = this.state.scrollContentHeight; | |
var reservedHeight = this.state.reservedHeight; | |
var requiredHeight = scrollContentHeight + reservedHeight; | |
var contentHeight; | |
var useMaxHeight = this.props.height === undefined; | |
if (useMaxHeight && this.props.maxHeight > requiredHeight) { | |
contentHeight = requiredHeight; | |
} else if (this.state.height > requiredHeight && this.props.ownerHeight) { | |
contentHeight = Math.max(requiredHeight, this.props.ownerHeight); | |
} else { | |
contentHeight = this.state.height + this.state.maxScrollY; | |
} | |
if (contentHeight !== this._contentHeight && this.props.onContentHeightChange) { | |
this.props.onContentHeightChange(contentHeight); | |
} | |
this._contentHeight = contentHeight; | |
}, | |
componentDidMount: function componentDidMount() { | |
this._reportContentHeight(); | |
}, | |
componentWillReceiveProps: function componentWillReceiveProps( /*object*/nextProps) { | |
var scrollToRow = nextProps.scrollToRow; | |
if (scrollToRow !== undefined && scrollToRow !== null) { | |
this._rowToScrollTo = scrollToRow; | |
} | |
var scrollToColumn = nextProps.scrollToColumn; | |
if (scrollToColumn !== undefined && scrollToColumn !== null) { | |
this._columnToScrollTo = scrollToColumn; | |
} | |
var newOverflowX = nextProps.overflowX; | |
var newOverflowY = nextProps.overflowY; | |
if (newOverflowX !== this.props.overflowX || newOverflowY !== this.props.overflowY) { | |
this._wheelHandler = new ReactWheelHandler(this._onWheel, newOverflowX !== 'hidden', // Should handle horizontal scroll | |
newOverflowY !== 'hidden' // Should handle vertical scroll | |
); | |
} | |
this.setState(this._calculateState(nextProps, this.state)); | |
}, | |
componentDidUpdate: function componentDidUpdate() { | |
this._reportContentHeight(); | |
}, | |
render: function render() /*object*/{ | |
var state = this.state; | |
var props = this.props; | |
var groupHeader; | |
if (state.useGroupHeader) { | |
groupHeader = React.createElement(FixedDataTableRow, { | |
key: 'group_header', | |
className: cx('public/fixedDataTable/header'), | |
data: state.groupHeaderData, | |
width: state.width, | |
height: state.groupHeaderHeight, | |
index: 0, | |
zIndex: 1, | |
offsetTop: 0, | |
scrollLeft: state.scrollX, | |
fixedColumns: state.groupHeaderFixedColumns, | |
scrollableColumns: state.groupHeaderScrollableColumns | |
}); | |
} | |
var maxScrollY = this.state.maxScrollY; | |
var showScrollbarX = state.maxScrollX > 0 && state.overflowX !== 'hidden'; | |
var showScrollbarY = maxScrollY > 0 && state.overflowY !== 'hidden'; | |
var scrollbarXHeight = showScrollbarX ? Scrollbar.SIZE : 0; | |
var scrollbarYHeight = state.height - scrollbarXHeight - 2 * BORDER_HEIGHT; | |
var headerOffsetTop = state.useGroupHeader ? state.groupHeaderHeight : 0; | |
var bodyOffsetTop = headerOffsetTop + state.headerHeight; | |
var bottomSectionOffset = 0; | |
var footOffsetTop = props.maxHeight != null ? bodyOffsetTop + state.bodyHeight : scrollbarYHeight - props.footerHeight; | |
var rowsContainerHeight = footOffsetTop + state.footerHeight; | |
if (props.ownerHeight !== undefined && props.ownerHeight < state.height) { | |
bottomSectionOffset = props.ownerHeight - state.height; | |
footOffsetTop = Math.min(footOffsetTop, scrollbarYHeight + bottomSectionOffset - state.footerHeight); | |
scrollbarYHeight = props.ownerHeight - scrollbarXHeight; | |
} | |
var verticalScrollbar; | |
if (showScrollbarY) { | |
verticalScrollbar = React.createElement(Scrollbar, { | |
size: scrollbarYHeight, | |
contentSize: scrollbarYHeight + maxScrollY, | |
onScroll: this._onVerticalScroll, | |
position: state.scrollY | |
}); | |
} | |
var horizontalScrollbar; | |
if (showScrollbarX) { | |
var scrollbarYWidth = showScrollbarY ? Scrollbar.SIZE : 0; | |
var scrollbarXWidth = state.width - scrollbarYWidth; | |
horizontalScrollbar = React.createElement(HorizontalScrollbar, { | |
contentSize: scrollbarXWidth + state.maxScrollX, | |
offset: bottomSectionOffset, | |
onScroll: this._onHorizontalScroll, | |
position: state.scrollX, | |
size: scrollbarXWidth | |
}); | |
} | |
var dragKnob = React.createElement(FixedDataTableColumnResizeHandle, { | |
height: state.height, | |
initialWidth: state.columnResizingData.width || 0, | |
minWidth: state.columnResizingData.minWidth || 0, | |
maxWidth: state.columnResizingData.maxWidth || Number.MAX_VALUE, | |
visible: !!state.isColumnResizing, | |
leftOffset: state.columnResizingData.left || 0, | |
knobHeight: state.headerHeight, | |
initialEvent: state.columnResizingData.initialEvent, | |
onColumnResizeEnd: props.onColumnResizeEndCallback, | |
columnKey: state.columnResizingData.key | |
}); | |
var footer = null; | |
if (state.footerHeight) { | |
var footerData = props.footerDataGetter ? props.footerDataGetter() : props.footerData; | |
footer = React.createElement(FixedDataTableRow, { | |
key: 'footer', | |
className: cx('public/fixedDataTable/footer'), | |
data: footerData, | |
fixedColumns: state.footFixedColumns, | |
height: state.footerHeight, | |
index: -1, | |
zIndex: 1, | |
offsetTop: footOffsetTop, | |
scrollableColumns: state.footScrollableColumns, | |
scrollLeft: state.scrollX, | |
width: state.width | |
}); | |
} | |
var rows = this._renderRows(bodyOffsetTop); | |
var header = React.createElement(FixedDataTableRow, { | |
key: 'header', | |
className: cx('public/fixedDataTable/header'), | |
data: state.headData, | |
width: state.width, | |
height: state.headerHeight, | |
index: -1, | |
zIndex: 1, | |
offsetTop: headerOffsetTop, | |
scrollLeft: state.scrollX, | |
fixedColumns: state.headFixedColumns, | |
scrollableColumns: state.headScrollableColumns, | |
onColumnResize: this._onColumnResize | |
}); | |
var topShadow; | |
var bottomShadow; | |
if (state.scrollY) { | |
topShadow = React.createElement('div', { | |
className: cx('fixedDataTable/topShadow'), | |
style: { top: bodyOffsetTop } | |
}); | |
} | |
if (state.ownerHeight != null && state.ownerHeight < state.height && state.scrollContentHeight + state.reservedHeight > state.ownerHeight || state.scrollY < maxScrollY) { | |
bottomShadow = React.createElement('div', { | |
className: cx('fixedDataTable/bottomShadow'), | |
style: { top: footOffsetTop } | |
}); | |
} | |
return React.createElement( | |
'div', | |
{ | |
className: cx('public/fixedDataTable/main'), | |
onWheel: this._wheelHandler.onWheel, | |
style: { height: state.height, width: state.width } }, | |
React.createElement( | |
'div', | |
{ | |
className: cx('fixedDataTable/rowsContainer'), | |
style: { height: rowsContainerHeight, width: state.width } }, | |
dragKnob, | |
groupHeader, | |
header, | |
rows, | |
footer, | |
topShadow, | |
bottomShadow | |
), | |
verticalScrollbar, | |
horizontalScrollbar | |
); | |
}, | |
_renderRows: function _renderRows( /*number*/offsetTop) /*object*/{ | |
var state = this.state; | |
return React.createElement(FixedDataTableBufferedRows, { | |
defaultRowHeight: state.rowHeight, | |
firstRowIndex: state.firstRowIndex, | |
firstRowOffset: state.firstRowOffset, | |
fixedColumns: state.bodyFixedColumns, | |
height: state.bodyHeight, | |
offsetTop: offsetTop, | |
onRowClick: state.onRowClick, | |
onRowDoubleClick: state.onRowDoubleClick, | |
onRowMouseDown: state.onRowMouseDown, | |
onRowMouseEnter: state.onRowMouseEnter, | |
onRowMouseLeave: state.onRowMouseLeave, | |
rowClassNameGetter: state.rowClassNameGetter, | |
rowsCount: state.rowsCount, | |
rowGetter: state.rowGetter, | |
rowHeightGetter: state.rowHeightGetter, | |
scrollLeft: state.scrollX, | |
scrollableColumns: state.bodyScrollableColumns, | |
showLastRowBorder: true, | |
width: state.width, | |
rowPositionGetter: this._scrollHelper.getRowPosition | |
}); | |
}, | |
/** | |
* This is called when a cell that is in the header of a column has its | |
* resizer knob clicked on. It displays the resizer and puts in the correct | |
* location on the table. | |
*/ | |
_onColumnResize: function _onColumnResize( | |
/*number*/combinedWidth, | |
/*number*/leftOffset, | |
/*number*/cellWidth, | |
/*?number*/cellMinWidth, | |
/*?number*/cellMaxWidth, | |
/*number|string*/columnKey, | |
/*object*/event) { | |
if (Locale.isRTL()) { | |
leftOffset = -leftOffset; | |
} | |
this.setState({ | |
isColumnResizing: true, | |
columnResizingData: { | |
left: leftOffset + combinedWidth - cellWidth, | |
width: cellWidth, | |
minWidth: cellMinWidth, | |
maxWidth: cellMaxWidth, | |
initialEvent: { | |
clientX: event.clientX, | |
clientY: event.clientY, | |
preventDefault: emptyFunction | |
}, | |
key: columnKey | |
} | |
}); | |
}, | |
_areColumnSettingsIdentical: function _areColumnSettingsIdentical(oldColumns, newColumns) { | |
if (oldColumns.length !== newColumns.length) { | |
return false; | |
} | |
for (var index = 0; index < oldColumns.length; ++index) { | |
if (!shallowEqual(oldColumns[index].props, newColumns[index].props)) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
_populateColumnsAndColumnData: function _populateColumnsAndColumnData(columns, columnGroups, oldState) { | |
var canReuseColumnSettings = false; | |
var canReuseColumnGroupSettings = false; | |
if (oldState && oldState.columns) { | |
canReuseColumnSettings = this._areColumnSettingsIdentical(columns, oldState.columns); | |
} | |
if (oldState && oldState.columnGroups && columnGroups) { | |
canReuseColumnGroupSettings = this._areColumnSettingsIdentical(columnGroups, oldState.columnGroups); | |
} | |
var columnInfo = {}; | |
if (canReuseColumnSettings) { | |
columnInfo.bodyFixedColumns = oldState.bodyFixedColumns; | |
columnInfo.bodyScrollableColumns = oldState.bodyScrollableColumns; | |
columnInfo.headFixedColumns = oldState.headFixedColumns; | |
columnInfo.headScrollableColumns = oldState.headScrollableColumns; | |
columnInfo.footFixedColumns = oldState.footFixedColumns; | |
columnInfo.footScrollableColumns = oldState.footScrollableColumns; | |
} else { | |
var bodyColumnTypes = this._splitColumnTypes(columns); | |
columnInfo.bodyFixedColumns = bodyColumnTypes.fixed; | |
columnInfo.bodyScrollableColumns = bodyColumnTypes.scrollable; | |
var headColumnTypes = this._splitColumnTypes(this._createHeadColumns(columns)); | |
columnInfo.headFixedColumns = headColumnTypes.fixed; | |
columnInfo.headScrollableColumns = headColumnTypes.scrollable; | |
var footColumnTypes = this._splitColumnTypes(this._createFootColumns(columns)); | |
columnInfo.footFixedColumns = footColumnTypes.fixed; | |
columnInfo.footScrollableColumns = footColumnTypes.scrollable; | |
} | |
if (canReuseColumnGroupSettings) { | |
columnInfo.groupHeaderFixedColumns = oldState.groupHeaderFixedColumns; | |
columnInfo.groupHeaderScrollableColumns = oldState.groupHeaderScrollableColumns; | |
} else { | |
if (columnGroups) { | |
columnInfo.groupHeaderData = this._getGroupHeaderData(columnGroups); | |
columnGroups = this._createGroupHeaderColumns(columnGroups); | |
var groupHeaderColumnTypes = this._splitColumnTypes(columnGroups); | |
columnInfo.groupHeaderFixedColumns = groupHeaderColumnTypes.fixed; | |
columnInfo.groupHeaderScrollableColumns = groupHeaderColumnTypes.scrollable; | |
} | |
} | |
columnInfo.headData = this._getHeadData(columns); | |
return columnInfo; | |
}, | |
_calculateState: function _calculateState( /*object*/props, /*?object*/oldState) /*object*/{ | |
invariant(props.height !== undefined || props.maxHeight !== undefined, 'You must set either a height or a maxHeight'); | |
var children = []; | |
ReactChildren.forEach(props.children, function (child, index) { | |
if (child == null) { | |
return; | |
} | |
invariant(child.type.__TableColumnGroup__ || child.type.__TableColumn__, 'child type should be <FixedDataTableColumn /> or ' + '<FixedDataTableColumnGroup />'); | |
children.push(child); | |
}); | |
var useGroupHeader = false; | |
if (children.length && children[0].type.__TableColumnGroup__) { | |
useGroupHeader = true; | |
} | |
var firstRowIndex = oldState && oldState.firstRowIndex || 0; | |
var firstRowOffset = oldState && oldState.firstRowOffset || 0; | |
var scrollX, scrollY; | |
if (oldState && props.overflowX !== 'hidden') { | |
scrollX = oldState.scrollX; | |
} else { | |
scrollX = props.scrollLeft; | |
} | |
if (oldState && props.overflowY !== 'hidden') { | |
scrollY = oldState.scrollY; | |
} else { | |
scrollState = this._scrollHelper.scrollTo(props.scrollTop); | |
firstRowIndex = scrollState.index; | |
firstRowOffset = scrollState.offset; | |
scrollY = scrollState.position; | |
} | |
if (this._rowToScrollTo !== undefined) { | |
scrollState = this._scrollHelper.scrollRowIntoView(this._rowToScrollTo); | |
firstRowIndex = scrollState.index; | |
firstRowOffset = scrollState.offset; | |
scrollY = scrollState.position; | |
delete this._rowToScrollTo; | |
} | |
var groupHeaderHeight = useGroupHeader ? props.groupHeaderHeight : 0; | |
if (oldState && props.rowsCount !== oldState.rowsCount) { | |
// Number of rows changed, try to scroll to the row from before the | |
// change | |
var viewportHeight = props.height - props.headerHeight - props.footerHeight - groupHeaderHeight; | |
this._scrollHelper = new FixedDataTableScrollHelper(props.rowsCount, props.rowHeight, viewportHeight, props.rowHeightGetter); | |
var scrollState = this._scrollHelper.scrollToRow(firstRowIndex, firstRowOffset); | |
firstRowIndex = scrollState.index; | |
firstRowOffset = scrollState.offset; | |
scrollY = scrollState.position; | |
} else if (oldState && props.rowHeightGetter !== oldState.rowHeightGetter) { | |
this._scrollHelper.setRowHeightGetter(props.rowHeightGetter); | |
} | |
var columnResizingData; | |
if (props.isColumnResizing) { | |
columnResizingData = oldState && oldState.columnResizingData; | |
} else { | |
columnResizingData = EMPTY_OBJECT; | |
} | |
var columns; | |
var columnGroups; | |
if (useGroupHeader) { | |
var columnGroupSettings = FixedDataTableWidthHelper.adjustColumnGroupWidths(children, props.width); | |
columns = columnGroupSettings.columns; | |
columnGroups = columnGroupSettings.columnGroups; | |
} else { | |
columns = FixedDataTableWidthHelper.adjustColumnWidths(children, props.width); | |
} | |
var columnInfo = this._populateColumnsAndColumnData(columns, columnGroups, oldState); | |
if (this._columnToScrollTo !== undefined) { | |
// If selected column is a fixed column, don't scroll | |
var fixedColumnsCount = columnInfo.bodyFixedColumns.length; | |
if (this._columnToScrollTo >= fixedColumnsCount) { | |
var totalFixedColumnsWidth = 0; | |
var i, column; | |
for (i = 0; i < columnInfo.bodyFixedColumns.length; ++i) { | |
column = columnInfo.bodyFixedColumns[i]; | |
totalFixedColumnsWidth += column.props.width; | |
} | |
var scrollableColumnIndex = this._columnToScrollTo - fixedColumnsCount; | |
var previousColumnsWidth = 0; | |
for (i = 0; i < scrollableColumnIndex; ++i) { | |
column = columnInfo.bodyScrollableColumns[i]; | |
previousColumnsWidth += column.props.width; | |
} | |
var availableScrollWidth = props.width - totalFixedColumnsWidth; | |
var selectedColumnWidth = columnInfo.bodyScrollableColumns[this._columnToScrollTo - fixedColumnsCount].props.width; | |
var minAcceptableScrollPosition = previousColumnsWidth + selectedColumnWidth - availableScrollWidth; | |
if (scrollX < minAcceptableScrollPosition) { | |
scrollX = minAcceptableScrollPosition; | |
} | |
if (scrollX > previousColumnsWidth) { | |
scrollX = previousColumnsWidth; | |
} | |
} | |
delete this._columnToScrollTo; | |
} | |
var useMaxHeight = props.height === undefined; | |
var height = useMaxHeight ? props.maxHeight : props.height; | |
var totalHeightReserved = props.footerHeight + props.headerHeight + groupHeaderHeight + 2 * BORDER_HEIGHT; | |
var bodyHeight = height - totalHeightReserved; | |
var scrollContentHeight = this._scrollHelper.getContentHeight(); | |
var totalHeightNeeded = scrollContentHeight + totalHeightReserved; | |
var scrollContentWidth = FixedDataTableWidthHelper.getTotalWidth(columns); | |
var horizontalScrollbarVisible = scrollContentWidth > props.width && props.overflowX !== 'hidden'; | |
if (horizontalScrollbarVisible) { | |
bodyHeight -= Scrollbar.SIZE; | |
totalHeightNeeded += Scrollbar.SIZE; | |
totalHeightReserved += Scrollbar.SIZE; | |
} | |
var maxScrollX = Math.max(0, scrollContentWidth - props.width); | |
var maxScrollY = Math.max(0, scrollContentHeight - bodyHeight); | |
scrollX = Math.min(scrollX, maxScrollX); | |
scrollY = Math.min(scrollY, maxScrollY); | |
if (!maxScrollY) { | |
// no vertical scrollbar necessary, use the totals we tracked so we | |
// can shrink-to-fit vertically | |
if (useMaxHeight) { | |
height = totalHeightNeeded; | |
} | |
bodyHeight = totalHeightNeeded - totalHeightReserved; | |
} | |
this._scrollHelper.setViewportHeight(bodyHeight); | |
// The order of elements in this object metters and bringing bodyHeight, | |
// height or useGroupHeader to the top can break various features | |
var newState = _extends({ | |
isColumnResizing: oldState && oldState.isColumnResizing | |
}, columnInfo, props, { | |
columns: columns, | |
columnGroups: columnGroups, | |
columnResizingData: columnResizingData, | |
firstRowIndex: firstRowIndex, | |
firstRowOffset: firstRowOffset, | |
horizontalScrollbarVisible: horizontalScrollbarVisible, | |
maxScrollX: maxScrollX, | |
maxScrollY: maxScrollY, | |
reservedHeight: totalHeightReserved, | |
scrollContentHeight: scrollContentHeight, | |
scrollX: scrollX, | |
scrollY: scrollY, | |
// These properties may overwrite properties defined in | |
// columnInfo and props | |
bodyHeight: bodyHeight, | |
height: height, | |
groupHeaderHeight: groupHeaderHeight, | |
useGroupHeader: useGroupHeader | |
}); | |
// Both `headData` and `groupHeaderData` are generated by | |
// `FixedDataTable` will be passed to each header cell to render. | |
// In order to prevent over-rendering the cells, we do not pass the | |
// new `headData` or `groupHeaderData` | |
// if they haven't changed. | |
if (oldState) { | |
if (oldState.headData && newState.headData && shallowEqual(oldState.headData, newState.headData)) { | |
newState.headData = oldState.headData; | |
} | |
if (oldState.groupHeaderData && newState.groupHeaderData && shallowEqual(oldState.groupHeaderData, newState.groupHeaderData)) { | |
newState.groupHeaderData = oldState.groupHeaderData; | |
} | |
} | |
return newState; | |
}, | |
_createGroupHeaderColumns: function _createGroupHeaderColumns( /*array*/columnGroups) /*array*/{ | |
var newColumnGroups = []; | |
for (var i = 0; i < columnGroups.length; ++i) { | |
newColumnGroups[i] = cloneWithProps(columnGroups[i], { | |
dataKey: i, | |
children: undefined, | |
columnData: columnGroups[i].props.columnGroupData, | |
cellRenderer: columnGroups[i].props.groupHeaderRenderer || renderToString, | |
isHeaderCell: true | |
}); | |
} | |
return newColumnGroups; | |
}, | |
_createHeadColumns: function _createHeadColumns( /*array*/columns) /*array*/{ | |
var headColumns = []; | |
for (var i = 0; i < columns.length; ++i) { | |
var columnProps = columns[i].props; | |
headColumns.push(cloneWithProps(columns[i], { | |
cellRenderer: columnProps.headerRenderer || renderToString, | |
columnData: columnProps.columnData, | |
dataKey: columnProps.dataKey, | |
isHeaderCell: true, | |
label: columnProps.label | |
})); | |
} | |
return headColumns; | |
}, | |
_createFootColumns: function _createFootColumns( /*array*/columns) /*array*/{ | |
var footColumns = []; | |
for (var i = 0; i < columns.length; ++i) { | |
var columnProps = columns[i].props; | |
footColumns.push(cloneWithProps(columns[i], { | |
cellRenderer: columnProps.footerRenderer || renderToString, | |
columnData: columnProps.columnData, | |
dataKey: columnProps.dataKey, | |
isFooterCell: true | |
})); | |
} | |
return footColumns; | |
}, | |
_getHeadData: function _getHeadData( /*array*/columns) /*object*/{ | |
var headData = {}; | |
for (var i = 0; i < columns.length; ++i) { | |
var columnProps = columns[i].props; | |
if (this.props.headerDataGetter) { | |
headData[columnProps.dataKey] = this.props.headerDataGetter(columnProps.dataKey); | |
} else { | |
headData[columnProps.dataKey] = columnProps.label || ''; | |
} | |
} | |
return headData; | |
}, | |
_getGroupHeaderData: function _getGroupHeaderData( /*array*/columnGroups) /*array*/{ | |
var groupHeaderData = []; | |
for (var i = 0; i < columnGroups.length; ++i) { | |
groupHeaderData[i] = columnGroups[i].props.label || ''; | |
} | |
return groupHeaderData; | |
}, | |
_splitColumnTypes: function _splitColumnTypes( /*array*/columns) /*object*/{ | |
var fixedColumns = []; | |
var scrollableColumns = []; | |
for (var i = 0; i < columns.length; ++i) { | |
if (columns[i].props.fixed) { | |
fixedColumns.push(columns[i]); | |
} else { | |
scrollableColumns.push(columns[i]); | |
} | |
} | |
return { | |
fixed: fixedColumns, | |
scrollable: scrollableColumns | |
}; | |
}, | |
_onWheel: function _onWheel( /*number*/deltaX, /*number*/deltaY) { | |
if (this.isMounted()) { | |
var x = this.state.scrollX; | |
if (Math.abs(deltaY) > Math.abs(deltaX) && this.props.overflowY !== 'hidden') { | |
var scrollState = this._scrollHelper.scrollBy(Math.round(deltaY)); | |
var maxScrollY = Math.max(0, scrollState.contentHeight - this.state.bodyHeight); | |
this.setState({ | |
firstRowIndex: scrollState.index, | |
firstRowOffset: scrollState.offset, | |
scrollY: scrollState.position, | |
scrollContentHeight: scrollState.contentHeight, | |
maxScrollY: maxScrollY | |
}); | |
} else if (deltaX && this.props.overflowX !== 'hidden') { | |
x += deltaX; | |
x = x < 0 ? 0 : x; | |
x = x > this.state.maxScrollX ? this.state.maxScrollX : x; | |
this.setState({ | |
scrollX: x | |
}); | |
} | |
this._didScrollStop(); | |
} | |
}, | |
_onHorizontalScroll: function _onHorizontalScroll( /*number*/scrollPos) { | |
if (this.isMounted() && scrollPos !== this.state.scrollX) { | |
this.setState({ | |
scrollX: scrollPos | |
}); | |
this._didScrollStop(); | |
} | |
}, | |
_onVerticalScroll: function _onVerticalScroll( /*number*/scrollPos) { | |
if (this.isMounted() && scrollPos !== this.state.scrollY) { | |
var scrollState = this._scrollHelper.scrollTo(Math.round(scrollPos)); | |
this.setState({ | |
firstRowIndex: scrollState.index, | |
firstRowOffset: scrollState.offset, | |
scrollY: scrollState.position, | |
scrollContentHeight: scrollState.contentHeight | |
}); | |
this._didScrollStop(); | |
} | |
}, | |
_didScrollStop: function _didScrollStop() { | |
if (this.isMounted()) { | |
if (this.props.onScrollEnd) { | |
this.props.onScrollEnd(this.state.scrollX, this.state.scrollY); | |
} | |
} | |
} | |
}); | |
var HorizontalScrollbar = React.createClass({ | |
displayName: 'HorizontalScrollbar', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
contentSize: PropTypes.number.isRequired, | |
offset: PropTypes.number.isRequired, | |
onScroll: PropTypes.func.isRequired, | |
position: PropTypes.number.isRequired, | |
size: PropTypes.number.isRequired | |
}, | |
render: function render() /*object*/{ | |
var outerContainerStyle = { | |
height: Scrollbar.SIZE, | |
width: this.props.size | |
}; | |
var innerContainerStyle = { | |
height: Scrollbar.SIZE, | |
position: 'absolute', | |
overflow: 'hidden', | |
width: this.props.size | |
}; | |
translateDOMPositionXY(innerContainerStyle, 0, this.props.offset); | |
return React.createElement( | |
'div', | |
{ | |
className: cx('fixedDataTable/horizontalScrollbar'), | |
style: outerContainerStyle }, | |
React.createElement( | |
'div', | |
{ style: innerContainerStyle }, | |
React.createElement(Scrollbar, _extends({}, this.props, { | |
isOpaque: true, | |
orientation: 'horizontal', | |
offset: undefined | |
})) | |
) | |
); | |
} | |
}); | |
module.exports = FixedDataTable; | |
// isColumnResizing should be overwritten by value from props if | |
// avaialble | |
/***/ }, | |
/* 17 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableScrollHelper | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
var PrefixIntervalTree = __webpack_require__(18); | |
var clamp = __webpack_require__(19); | |
var BUFFER_ROWS = 5; | |
var FixedDataTableScrollHelper = (function () { | |
function FixedDataTableScrollHelper( | |
/*number*/rowCount, | |
/*number*/defaultRowHeight, | |
/*number*/viewportHeight, | |
/*?function*/rowHeightGetter) { | |
_classCallCheck(this, FixedDataTableScrollHelper); | |
this._rowOffsets = new PrefixIntervalTree(rowCount, defaultRowHeight); | |
this._storedHeights = new Array(rowCount); | |
for (var i = 0; i < rowCount; ++i) { | |
this._storedHeights[i] = defaultRowHeight; | |
} | |
this._rowCount = rowCount; | |
this._position = 0; | |
this._contentHeight = rowCount * defaultRowHeight; | |
this._defaultRowHeight = defaultRowHeight; | |
this._rowHeightGetter = rowHeightGetter ? rowHeightGetter : function () { | |
return defaultRowHeight; | |
}; | |
this._viewportHeight = viewportHeight; | |
this.scrollRowIntoView = this.scrollRowIntoView.bind(this); | |
this.setViewportHeight = this.setViewportHeight.bind(this); | |
this.scrollBy = this.scrollBy.bind(this); | |
this.scrollTo = this.scrollTo.bind(this); | |
this.scrollToRow = this.scrollToRow.bind(this); | |
this.setRowHeightGetter = this.setRowHeightGetter.bind(this); | |
this.getContentHeight = this.getContentHeight.bind(this); | |
this.getRowPosition = this.getRowPosition.bind(this); | |
this._updateHeightsInViewport(0, 0); | |
} | |
_createClass(FixedDataTableScrollHelper, [{ | |
key: 'setRowHeightGetter', | |
value: function setRowHeightGetter( /*function*/rowHeightGetter) { | |
this._rowHeightGetter = rowHeightGetter; | |
} | |
}, { | |
key: 'setViewportHeight', | |
value: function setViewportHeight( /*number*/viewportHeight) { | |
this._viewportHeight = viewportHeight; | |
} | |
}, { | |
key: 'getContentHeight', | |
value: function getContentHeight() /*number*/{ | |
return this._contentHeight; | |
} | |
}, { | |
key: '_updateHeightsInViewport', | |
value: function _updateHeightsInViewport( | |
/*number*/firstRowIndex, | |
/*number*/firstRowOffset) { | |
var top = firstRowOffset; | |
var index = firstRowIndex; | |
while (top <= this._viewportHeight && index < this._rowCount) { | |
this._updateRowHeight(index); | |
top += this._storedHeights[index]; | |
index++; | |
} | |
} | |
}, { | |
key: '_updateHeightsAboveViewport', | |
value: function _updateHeightsAboveViewport( /*number*/firstRowIndex) { | |
var index = firstRowIndex - 1; | |
while (index >= 0 && index >= firstRowIndex - BUFFER_ROWS) { | |
var delta = this._updateRowHeight(index); | |
this._position += delta; | |
index--; | |
} | |
} | |
}, { | |
key: '_updateRowHeight', | |
value: function _updateRowHeight( /*number*/rowIndex) /*number*/{ | |
if (rowIndex < 0 || rowIndex >= this._rowCount) { | |
return 0; | |
} | |
var newHeight = this._rowHeightGetter(rowIndex); | |
if (newHeight !== this._storedHeights[rowIndex]) { | |
var change = newHeight - this._storedHeights[rowIndex]; | |
this._rowOffsets.set(rowIndex, newHeight); | |
this._storedHeights[rowIndex] = newHeight; | |
this._contentHeight += change; | |
return change; | |
} | |
return 0; | |
} | |
}, { | |
key: 'getRowPosition', | |
value: function getRowPosition( /*number*/rowIndex) /*number*/{ | |
this._updateRowHeight(rowIndex); | |
return this._rowOffsets.get(rowIndex).value - this._rowHeightGetter(rowIndex); | |
} | |
}, { | |
key: 'scrollBy', | |
value: function scrollBy( /*number*/delta) /*object*/{ | |
var firstRow = this._rowOffsets.upperBound(this._position); | |
var firstRowPosition = firstRow.value - this._storedHeights[firstRow.index]; | |
var rowIndex = firstRow.index; | |
var position = this._position; | |
var rowHeightChange = this._updateRowHeight(rowIndex); | |
if (firstRowPosition !== 0) { | |
position += rowHeightChange; | |
} | |
var visibleRowHeight = this._storedHeights[rowIndex] - (position - firstRowPosition); | |
if (delta >= 0) { | |
while (delta > 0 && rowIndex < this._rowCount) { | |
if (delta < visibleRowHeight) { | |
position += delta; | |
delta = 0; | |
} else { | |
delta -= visibleRowHeight; | |
position += visibleRowHeight; | |
rowIndex++; | |
} | |
if (rowIndex < this._rowCount) { | |
this._updateRowHeight(rowIndex); | |
visibleRowHeight = this._storedHeights[rowIndex]; | |
} | |
} | |
} else if (delta < 0) { | |
delta = -delta; | |
var invisibleRowHeight = this._storedHeights[rowIndex] - visibleRowHeight; | |
while (delta > 0 && rowIndex >= 0) { | |
if (delta < invisibleRowHeight) { | |
position -= delta; | |
delta = 0; | |
} else { | |
position -= invisibleRowHeight; | |
delta -= invisibleRowHeight; | |
rowIndex--; | |
} | |
if (rowIndex >= 0) { | |
var change = this._updateRowHeight(rowIndex); | |
invisibleRowHeight = this._storedHeights[rowIndex]; | |
position += change; | |
} | |
} | |
} | |
var maxPosition = this._contentHeight - this._viewportHeight; | |
position = clamp(0, position, maxPosition); | |
this._position = position; | |
var firstVisibleRow = this._rowOffsets.upperBound(position); | |
var firstRowIndex = firstVisibleRow.index; | |
firstRowPosition = firstVisibleRow.value - this._rowHeightGetter(firstRowIndex); | |
var firstRowOffset = firstRowPosition - position; | |
this._updateHeightsInViewport(firstRowIndex, firstRowOffset); | |
this._updateHeightsAboveViewport(firstRowIndex); | |
return { | |
index: firstRowIndex, | |
offset: firstRowOffset, | |
position: this._position, | |
contentHeight: this._contentHeight | |
}; | |
} | |
}, { | |
key: '_getRowAtEndPosition', | |
value: function _getRowAtEndPosition( /*number*/rowIndex) /*number*/{ | |
// We need to update enough rows above the selected one to be sure that when | |
// we scroll to selected position all rows between first shown and selected | |
// one have most recent heights computed and will not resize | |
this._updateRowHeight(rowIndex); | |
var currentRowIndex = rowIndex; | |
var top = this._storedHeights[currentRowIndex]; | |
while (top < this._viewportHeight && currentRowIndex >= 0) { | |
currentRowIndex--; | |
if (currentRowIndex >= 0) { | |
this._updateRowHeight(currentRowIndex); | |
top += this._storedHeights[currentRowIndex]; | |
} | |
} | |
var position = this._rowOffsets.get(rowIndex).value - this._viewportHeight; | |
if (position < 0) { | |
position = 0; | |
} | |
return position; | |
} | |
}, { | |
key: 'scrollTo', | |
value: function scrollTo( /*number*/position) /*object*/{ | |
if (position <= 0) { | |
// If position less than or equal to 0 first row should be fully visible | |
// on top | |
this._position = 0; | |
this._updateHeightsInViewport(0, 0); | |
return { | |
index: 0, | |
offset: 0, | |
position: this._position, | |
contentHeight: this._contentHeight | |
}; | |
} else if (position >= this._contentHeight - this._viewportHeight) { | |
// If position is equal to or greater than max scroll value, we need | |
// to make sure to have bottom border of last row visible. | |
var rowIndex = this._rowCount - 1; | |
position = this._getRowAtEndPosition(rowIndex); | |
} | |
this._position = position; | |
var firstVisibleRow = this._rowOffsets.upperBound(position); | |
var firstRowIndex = Math.max(firstVisibleRow.index, 0); | |
var firstRowPosition = firstVisibleRow.value - this._rowHeightGetter(firstRowIndex); | |
var firstRowOffset = firstRowPosition - position; | |
this._updateHeightsInViewport(firstRowIndex, firstRowOffset); | |
this._updateHeightsAboveViewport(firstRowIndex); | |
return { | |
index: firstRowIndex, | |
offset: firstRowOffset, | |
position: this._position, | |
contentHeight: this._contentHeight | |
}; | |
} | |
}, { | |
key: 'scrollToRow', | |
/** | |
* Allows to scroll to selected row with specified offset. It always | |
* brings that row to top of viewport with that offset | |
*/ | |
value: function scrollToRow( /*number*/rowIndex, /*number*/offset) /*object*/{ | |
rowIndex = clamp(0, rowIndex, this._rowCount - 1); | |
offset = clamp(-this._storedHeights[rowIndex], offset, 0); | |
var firstRow = this._rowOffsets.get(rowIndex); | |
return this.scrollTo(firstRow.value - this._storedHeights[rowIndex] - offset); | |
} | |
}, { | |
key: 'scrollRowIntoView', | |
/** | |
* Allows to scroll to selected row by bringing it to viewport with minimal | |
* scrolling. This that if row is fully visible, scroll will not be changed. | |
* If top border of row is above top of viewport it will be scrolled to be | |
* fully visible on the top of viewport. If the bottom border of row is | |
* below end of viewport, it will be scrolled up to be fully visible on the | |
* bottom of viewport. | |
*/ | |
value: function scrollRowIntoView( /*number*/rowIndex) /*object*/{ | |
rowIndex = clamp(0, rowIndex, this._rowCount - 1); | |
var rowEnd = this._rowOffsets.get(rowIndex).value; | |
var rowBegin = rowEnd - this._storedHeights[rowIndex]; | |
if (rowBegin < this._position) { | |
return this.scrollTo(rowBegin); | |
} else if (rowEnd > this._position + this._viewportHeight) { | |
var position = this._getRowAtEndPosition(rowIndex); | |
return this.scrollTo(position); | |
} | |
return this.scrollTo(this._position); | |
} | |
}]); | |
return FixedDataTableScrollHelper; | |
})(); | |
module.exports = FixedDataTableScrollHelper; | |
/***/ }, | |
/* 18 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(global) {/** | |
* Copyright (c) 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 PrefixIntervalTree | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
/** | |
* An interval tree that allows to set a number at index and given the value | |
* find the largest index for which prefix sum is greater than or equal to value | |
* (lower bound) or greater than value (upper bound) | |
* Complexity: | |
* construct: O(n) | |
* query: O(log(n)) | |
* memory: O(log(n)), | |
* where n is leafCount from the constructor | |
*/ | |
var PrefixIntervalTree = (function () { | |
function PrefixIntervalTree( /*number*/leafCount, /*?number*/initialLeafValue) { | |
_classCallCheck(this, PrefixIntervalTree); | |
var internalLeafCount = this.getInternalLeafCount(leafCount); | |
this._leafCount = leafCount; | |
this._internalLeafCount = internalLeafCount; | |
var nodeCount = 2 * internalLeafCount; | |
var Int32Array = global.Int32Array || this._initArray; | |
this._value = new Int32Array(nodeCount); | |
this._initTables(initialLeafValue || 0); | |
this.get = this.get.bind(this); | |
this.set = this.set.bind(this); | |
this.lowerBound = this.lowerBound.bind(this); | |
this.upperBound = this.upperBound.bind(this); | |
} | |
_createClass(PrefixIntervalTree, [{ | |
key: 'getInternalLeafCount', | |
value: function getInternalLeafCount( /*number*/leafCount) /*number*/{ | |
var internalLeafCount = 1; | |
while (internalLeafCount < leafCount) { | |
internalLeafCount *= 2; | |
} | |
return internalLeafCount; | |
} | |
}, { | |
key: '_initArray', | |
value: function _initArray( /*number*/size) /*array*/{ | |
var arr = []; | |
while (size > 0) { | |
size--; | |
arr[size] = 0; | |
} | |
return arr; | |
} | |
}, { | |
key: '_initTables', | |
value: function _initTables( /*number*/initialLeafValue) { | |
var firstLeaf = this._internalLeafCount; | |
var lastLeaf = this._internalLeafCount + this._leafCount - 1; | |
var i; | |
for (i = firstLeaf; i <= lastLeaf; ++i) { | |
this._value[i] = initialLeafValue; | |
} | |
var lastInternalNode = this._internalLeafCount - 1; | |
for (i = lastInternalNode; i > 0; --i) { | |
this._value[i] = this._value[2 * i] + this._value[2 * i + 1]; | |
} | |
} | |
}, { | |
key: 'set', | |
value: function set( /*number*/position, /*number*/value) { | |
var nodeIndex = position + this._internalLeafCount; | |
this._value[nodeIndex] = value; | |
nodeIndex = Math.floor(nodeIndex / 2); | |
while (nodeIndex !== 0) { | |
this._value[nodeIndex] = this._value[2 * nodeIndex] + this._value[2 * nodeIndex + 1]; | |
nodeIndex = Math.floor(nodeIndex / 2); | |
} | |
} | |
}, { | |
key: 'get', | |
/** | |
* Returns an object {index, value} for given position (including value at | |
* specified position), or the same for last position if provided position | |
* is out of range | |
*/ | |
value: function get( /*number*/position) /*object*/{ | |
position = Math.min(position, this._leafCount); | |
var nodeIndex = position + this._internalLeafCount; | |
var result = this._value[nodeIndex]; | |
while (nodeIndex > 1) { | |
if (nodeIndex % 2 === 1) { | |
result = this._value[nodeIndex - 1] + result; | |
} | |
nodeIndex = Math.floor(nodeIndex / 2); | |
} | |
return { index: position, value: result }; | |
} | |
}, { | |
key: 'upperBound', | |
/** | |
* Returns an object {index, value} where index is index of leaf that was | |
* found by upper bound algorithm. Upper bound finds first element for which | |
* value is greater than argument | |
*/ | |
value: function upperBound( /*number*/value) /*object*/{ | |
var result = this._upperBoundImpl(1, 0, this._internalLeafCount - 1, value); | |
if (result.index > this._leafCount - 1) { | |
result.index = this._leafCount - 1; | |
} | |
return result; | |
} | |
}, { | |
key: 'lowerBound', | |
/** | |
* Returns result in the same format as upperBound, but finds first element | |
* for which value is greater than or equal to argument | |
*/ | |
value: function lowerBound( /*number*/value) /*object*/{ | |
var result = this.upperBound(value); | |
if (result.value > value && result.index > 0) { | |
var previousValue = result.value - this._value[this._internalLeafCount + result.index]; | |
if (previousValue === value) { | |
result.value = previousValue; | |
result.index--; | |
} | |
} | |
return result; | |
} | |
}, { | |
key: '_upperBoundImpl', | |
value: function _upperBoundImpl( | |
/*number*/nodeIndex, | |
/*number*/nodeIntervalBegin, | |
/*number*/nodeIntervalEnd, | |
/*number*/value) /*object*/{ | |
if (nodeIntervalBegin === nodeIntervalEnd) { | |
return { | |
index: nodeIndex - this._internalLeafCount, | |
value: this._value[nodeIndex] | |
}; | |
} | |
var nodeIntervalMidpoint = Math.floor((nodeIntervalBegin + nodeIntervalEnd + 1) / 2); | |
if (value < this._value[nodeIndex * 2]) { | |
return this._upperBoundImpl(2 * nodeIndex, nodeIntervalBegin, nodeIntervalMidpoint - 1, value); | |
} else { | |
var result = this._upperBoundImpl(2 * nodeIndex + 1, nodeIntervalMidpoint, nodeIntervalEnd, value - this._value[2 * nodeIndex]); | |
result.value += this._value[2 * nodeIndex]; | |
return result; | |
} | |
} | |
}]); | |
return PrefixIntervalTree; | |
})(); | |
module.exports = PrefixIntervalTree; | |
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | |
/***/ }, | |
/* 19 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 clamp | |
* @typechecks | |
*/ | |
/** | |
* @param {number} min | |
* @param {number} value | |
* @param {number} max | |
* @return {number} | |
*/ | |
"use strict"; | |
function clamp(min, value, max) { | |
if (value < min) { | |
return min; | |
} | |
if (value > max) { | |
return max; | |
} | |
return value; | |
} | |
module.exports = clamp; | |
/***/ }, | |
/* 20 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableHelper | |
* @typechecks | |
*/ | |
'use strict'; | |
var Locale = __webpack_require__(21); | |
var React = __webpack_require__(22); | |
var FixedDataTableColumnGroup = __webpack_require__(24); | |
var FixedDataTableColumn = __webpack_require__(25); | |
var cloneWithProps = __webpack_require__(26); | |
var DIR_SIGN = Locale.isRTL() ? -1 : +1; | |
// A cell up to 5px outside of the visible area will still be considered visible | |
var CELL_VISIBILITY_TOLERANCE = 5; // used for flyouts | |
function renderToString(value) /*string*/{ | |
if (value === null || value === undefined) { | |
return ''; | |
} else { | |
return String(value); | |
} | |
} | |
/** | |
* Helper method to execute a callback against all columns given the children | |
* of a table. | |
* @param {?object|array} children | |
* Children of a table. | |
* @param {function} callback | |
* Function to excecute for each column. It is passed the column. | |
*/ | |
function forEachColumn(children, callback) { | |
React.Children.forEach(children, function (child) { | |
if (child.type === FixedDataTableColumnGroup) { | |
forEachColumn(child.props.children, callback); | |
} else if (child.type === FixedDataTableColumn) { | |
callback(child); | |
} | |
}); | |
} | |
/** | |
* Helper method to map columns to new columns. This takes into account column | |
* groups and will generate a new column group if its columns change. | |
* @param {?object|array} children | |
* Children of a table. | |
* @param {function} callback | |
* Function to excecute for each column. It is passed the column and should | |
* return a result column. | |
*/ | |
function mapColumns(children, callback) { | |
var newChildren = []; | |
React.Children.forEach(children, function (originalChild) { | |
var newChild = originalChild; | |
// The child is either a column group or a column. If it is a column group | |
// we need to iterate over its columns and then potentially generate a | |
// new column group | |
if (originalChild.type === FixedDataTableColumnGroup) { | |
var haveColumnsChanged = false; | |
var newColumns = []; | |
forEachColumn(originalChild.props.children, function (originalcolumn) { | |
var newColumn = callback(originalcolumn); | |
if (newColumn !== originalcolumn) { | |
haveColumnsChanged = true; | |
} | |
newColumns.push(newColumn); | |
}); | |
// If the column groups columns have changed clone the group and supply | |
// new children | |
if (haveColumnsChanged) { | |
newChild = cloneWithProps(originalChild, { | |
key: originalChild.key, | |
children: newColumns | |
}); | |
} | |
} else if (originalChild.type === FixedDataTableColumn) { | |
newChild = callback(originalChild); | |
} | |
newChildren.push(newChild); | |
}); | |
return newChildren; | |
} | |
var FixedDataTableHelper = { | |
DIR_SIGN: DIR_SIGN, | |
CELL_VISIBILITY_TOLERANCE: CELL_VISIBILITY_TOLERANCE, | |
renderToString: renderToString, | |
forEachColumn: forEachColumn, | |
mapColumns: mapColumns | |
}; | |
module.exports = FixedDataTableHelper; | |
/***/ }, | |
/* 21 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 Locale | |
*/ | |
"use strict"; | |
// Hard code this for now. | |
var Locale = { | |
isRTL: function isRTL() { | |
return false; | |
}, | |
getDirection: function getDirection() { | |
return "LTR"; | |
} | |
}; | |
module.exports = Locale; | |
/***/ }, | |
/* 22 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 React | |
*/ | |
'use strict'; | |
module.exports = __webpack_require__(23); | |
/***/ }, | |
/* 23 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = __WEBPACK_EXTERNAL_MODULE_23__; | |
/***/ }, | |
/* 24 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableColumnGroup.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var React = __webpack_require__(22); | |
var PropTypes = React.PropTypes; | |
/** | |
* Component that defines the attributes of a table column group. | |
*/ | |
var FixedDataTableColumnGroup = React.createClass({ | |
displayName: 'FixedDataTableColumnGroup', | |
statics: { | |
__TableColumnGroup__: true | |
}, | |
propTypes: { | |
/** | |
* The horizontal alignment of the table cell content. | |
*/ | |
align: PropTypes.oneOf(['left', 'center', 'right']), | |
/** | |
* Controls if the column group is fixed when scrolling in the X axis. | |
*/ | |
fixed: PropTypes.bool, | |
/** | |
* Bucket for any data to be passed into column group renderer functions. | |
*/ | |
columnGroupData: PropTypes.object, | |
/** | |
* The column group's header label. | |
*/ | |
label: PropTypes.string, | |
/** | |
* The cell renderer that returns React-renderable content for a table | |
* column group header. If it's not specified, the label from props will | |
* be rendered as header content. | |
* ``` | |
* function( | |
* label: ?string, | |
* cellDataKey: string, | |
* columnGroupData: any, | |
* rowData: array<?object>, // array of labels of all coludmnGroups | |
* width: number | |
* ): ?$jsx | |
* ``` | |
*/ | |
groupHeaderRenderer: PropTypes.func | |
}, | |
getDefaultProps: function getDefaultProps() /*object*/{ | |
return { | |
fixed: false | |
}; | |
}, | |
render: function render() { | |
if (true) { | |
throw new Error('Component <FixedDataTableColumnGroup /> should never render'); | |
} | |
return null; | |
} | |
}); | |
module.exports = FixedDataTableColumnGroup; | |
/***/ }, | |
/* 25 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableColumn.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var React = __webpack_require__(22); | |
var PropTypes = React.PropTypes; | |
/** | |
* Component that defines the attributes of table column. | |
*/ | |
var FixedDataTableColumn = React.createClass({ | |
displayName: 'FixedDataTableColumn', | |
statics: { | |
__TableColumn__: true | |
}, | |
propTypes: { | |
/** | |
* The horizontal alignment of the table cell content. | |
*/ | |
align: PropTypes.oneOf(['left', 'center', 'right']), | |
/** | |
* className for each of this column's data cells. | |
*/ | |
cellClassName: PropTypes.string, | |
/** | |
* The cell renderer that returns React-renderable content for table cell. | |
* ``` | |
* function( | |
* cellData: any, | |
* cellDataKey: string, | |
* rowData: object, | |
* rowIndex: number, | |
* columnData: any, | |
* width: number | |
* ): ?$jsx | |
* ``` | |
*/ | |
cellRenderer: PropTypes.func, | |
/** | |
* The getter `function(string_cellDataKey, object_rowData)` that returns | |
* the cell data for the `cellRenderer`. | |
* If not provided, the cell data will be collected from | |
* `rowData[cellDataKey]` instead. The value that `cellDataGetter` returns | |
* will be used to determine whether the cell should re-render. | |
*/ | |
cellDataGetter: PropTypes.func, | |
/** | |
* The key to retrieve the cell data from the data row. Provided key type | |
* must be either `string` or `number`. Since we use this | |
* for keys, it must be specified for each column. | |
*/ | |
dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, | |
/** | |
* Controls if the column is fixed when scrolling in the X axis. | |
*/ | |
fixed: PropTypes.bool, | |
/** | |
* The cell renderer that returns React-renderable content for table column | |
* header. | |
* ``` | |
* function( | |
* label: ?string, | |
* cellDataKey: string, | |
* columnData: any, | |
* rowData: array<?object>, | |
* width: number | |
* ): ?$jsx | |
* ``` | |
*/ | |
headerRenderer: PropTypes.func, | |
/** | |
* The cell renderer that returns React-renderable content for table column | |
* footer. | |
* ``` | |
* function( | |
* label: ?string, | |
* cellDataKey: string, | |
* columnData: any, | |
* rowData: array<?object>, | |
* width: number | |
* ): ?$jsx | |
* ``` | |
*/ | |
footerRenderer: PropTypes.func, | |
/** | |
* Bucket for any data to be passed into column renderer functions. | |
*/ | |
columnData: PropTypes.object, | |
/** | |
* The column's header label. | |
*/ | |
label: PropTypes.string, | |
/** | |
* The pixel width of the column. | |
*/ | |
width: PropTypes.number.isRequired, | |
/** | |
* If this is a resizable column this is its minimum pixel width. | |
*/ | |
minWidth: PropTypes.number, | |
/** | |
* If this is a resizable column this is its maximum pixel width. | |
*/ | |
maxWidth: PropTypes.number, | |
/** | |
* The grow factor relative to other columns. Same as the flex-grow API | |
* from http://www.w3.org/TR/css3-flexbox/. Basically, take any available | |
* extra width and distribute it proportionally according to all columns' | |
* flexGrow values. Defaults to zero (no-flexing). | |
*/ | |
flexGrow: PropTypes.number, | |
/** | |
* Whether the column can be resized with the | |
* FixedDataTableColumnResizeHandle. Please note that if a column | |
* has a flex grow, once you resize the column this will be set to 0. | |
* | |
* This property only provides the UI for the column resizing. If this | |
* is set to true, you wil need to set the onResizeColumnEndCallback table | |
* property and render your columns appropriately. | |
*/ | |
isResizable: PropTypes.bool, | |
/** | |
* Experimental feature | |
* Whether cells in this column can be removed from document when outside | |
* of viewport as a result of horizontal scrolling. | |
* Setting this property to true allows the table to not render cells in | |
* particular column that are outside of viewport for visible rows. This | |
* allows to create table with many columns and not have vertical scrolling | |
* performance drop. | |
* Setting the property to false will keep previous behaviour and keep | |
* cell rendered if the row it belongs to is visible. | |
*/ | |
allowCellsRecycling: PropTypes.bool | |
}, | |
getDefaultProps: function getDefaultProps() /*object*/{ | |
return { | |
allowCellsRecycling: false, | |
fixed: false | |
}; | |
}, | |
render: function render() { | |
if (true) { | |
throw new Error('Component <FixedDataTableColumn /> should never render'); | |
} | |
return null; | |
} | |
}); | |
module.exports = FixedDataTableColumn; | |
/***/ }, | |
/* 26 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 cloneWithProps | |
*/ | |
'use strict'; | |
module.exports = __webpack_require__(27); | |
/***/ }, | |
/* 27 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(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. | |
* | |
* @typechecks static-only | |
* @providesModule cloneWithProps | |
*/ | |
'use strict'; | |
var ReactElement = __webpack_require__(29); | |
var ReactPropTransferer = __webpack_require__(36); | |
var keyOf = __webpack_require__(38); | |
var warning = __webpack_require__(33); | |
var CHILDREN_PROP = keyOf({children: null}); | |
/** | |
* Sometimes you want to change the props of a child passed to you. Usually | |
* this is to add a CSS class. | |
* | |
* @param {ReactElement} child child element you'd like to clone | |
* @param {object} props props you'd like to modify. className and style will be | |
* merged automatically. | |
* @return {ReactElement} a clone of child with props merged in. | |
*/ | |
function cloneWithProps(child, props) { | |
if ("production" !== process.env.NODE_ENV) { | |
("production" !== process.env.NODE_ENV ? warning( | |
!child.ref, | |
'You are calling cloneWithProps() on a child with a ref. This is ' + | |
'dangerous because you\'re creating a new child which will not be ' + | |
'added as a ref to its parent.' | |
) : null); | |
} | |
var newProps = ReactPropTransferer.mergeProps(props, child.props); | |
// Use `child.props.children` if it is provided. | |
if (!newProps.hasOwnProperty(CHILDREN_PROP) && | |
child.props.hasOwnProperty(CHILDREN_PROP)) { | |
newProps.children = child.props.children; | |
} | |
// The current API doesn't retain _owner and _context, which is why this | |
// doesn't use ReactElement.cloneAndReplaceProps. | |
return ReactElement.createElement(child.type, newProps); | |
} | |
module.exports = cloneWithProps; | |
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(28))) | |
/***/ }, | |
/* 28 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// shim for using process in browser | |
var process = module.exports = {}; | |
var queue = []; | |
var draining = false; | |
var currentQueue; | |
var queueIndex = -1; | |
function cleanUpNextTick() { | |
draining = false; | |
if (currentQueue.length) { | |
queue = currentQueue.concat(queue); | |
} else { | |
queueIndex = -1; | |
} | |
if (queue.length) { | |
drainQueue(); | |
} | |
} | |
function drainQueue() { | |
if (draining) { | |
return; | |
} | |
var timeout = setTimeout(cleanUpNextTick); | |
draining = true; | |
var len = queue.length; | |
while(len) { | |
currentQueue = queue; | |
queue = []; | |
while (++queueIndex < len) { | |
currentQueue[queueIndex].run(); | |
} | |
queueIndex = -1; | |
len = queue.length; | |
} | |
currentQueue = null; | |
draining = false; | |
clearTimeout(timeout); | |
} | |
process.nextTick = function (fun) { | |
var args = new Array(arguments.length - 1); | |
if (arguments.length > 1) { | |
for (var i = 1; i < arguments.length; i++) { | |
args[i - 1] = arguments[i]; | |
} | |
} | |
queue.push(new Item(fun, args)); | |
if (queue.length === 1 && !draining) { | |
setTimeout(drainQueue, 0); | |
} | |
}; | |
// v8 likes predictible objects | |
function Item(fun, array) { | |
this.fun = fun; | |
this.array = array; | |
} | |
Item.prototype.run = function () { | |
this.fun.apply(null, this.array); | |
}; | |
process.title = 'browser'; | |
process.browser = true; | |
process.env = {}; | |
process.argv = []; | |
process.version = ''; // empty string to avoid regexp issues | |
process.versions = {}; | |
function noop() {} | |
process.on = noop; | |
process.addListener = noop; | |
process.once = noop; | |
process.off = noop; | |
process.removeListener = noop; | |
process.removeAllListeners = noop; | |
process.emit = noop; | |
process.binding = function (name) { | |
throw new Error('process.binding is not supported'); | |
}; | |
// TODO(shtylman) | |
process.cwd = function () { return '/' }; | |
process.chdir = function (dir) { | |
throw new Error('process.chdir is not supported'); | |
}; | |
process.umask = function() { return 0; }; | |
/***/ }, | |
/* 29 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(process) {/** | |
* Copyright 2014-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactElement | |
*/ | |
'use strict'; | |
var ReactContext = __webpack_require__(30); | |
var ReactCurrentOwner = __webpack_require__(35); | |
var assign = __webpack_require__(31); | |
var warning = __webpack_require__(33); | |
var RESERVED_PROPS = { | |
key: true, | |
ref: true | |
}; | |
/** | |
* Warn for mutations. | |
* | |
* @internal | |
* @param {object} object | |
* @param {string} key | |
*/ | |
function defineWarningProperty(object, key) { | |
Object.defineProperty(object, key, { | |
configurable: false, | |
enumerable: true, | |
get: function() { | |
if (!this._store) { | |
return null; | |
} | |
return this._store[key]; | |
}, | |
set: function(value) { | |
("production" !== process.env.NODE_ENV ? warning( | |
false, | |
'Don\'t set the %s property of the React element. Instead, ' + | |
'specify the correct value when initially creating the element.', | |
key | |
) : null); | |
this._store[key] = value; | |
} | |
}); | |
} | |
/** | |
* This is updated to true if the membrane is successfully created. | |
*/ | |
var useMutationMembrane = false; | |
/** | |
* Warn for mutations. | |
* | |
* @internal | |
* @param {object} element | |
*/ | |
function defineMutationMembrane(prototype) { | |
try { | |
var pseudoFrozenProperties = { | |
props: true | |
}; | |
for (var key in pseudoFrozenProperties) { | |
defineWarningProperty(prototype, key); | |
} | |
useMutationMembrane = true; | |
} catch (x) { | |
// IE will fail on defineProperty | |
} | |
} | |
/** | |
* Base constructor for all React elements. This is only used to make this | |
* work with a dynamic instanceof check. Nothing should live on this prototype. | |
* | |
* @param {*} type | |
* @param {string|object} ref | |
* @param {*} key | |
* @param {*} props | |
* @internal | |
*/ | |
var ReactElement = function(type, key, ref, owner, context, props) { | |
// Built-in properties that belong on the element | |
this.type = type; | |
this.key = key; | |
this.ref = ref; | |
// Record the component responsible for creating this element. | |
this._owner = owner; | |
// TODO: Deprecate withContext, and then the context becomes accessible | |
// through the owner. | |
this._context = context; | |
if ("production" !== process.env.NODE_ENV) { | |
// The validation flag and props are currently mutative. We put them on | |
// an external backing store so that we can freeze the whole object. | |
// This can be replaced with a WeakMap once they are implemented in | |
// commonly used development environments. | |
this._store = {props: props, originalProps: assign({}, props)}; | |
// To make comparing ReactElements easier for testing purposes, we make | |
// the validation flag non-enumerable (where possible, which should | |
// include every environment we run tests in), so the test framework | |
// ignores it. | |
try { | |
Object.defineProperty(this._store, 'validated', { | |
configurable: false, | |
enumerable: false, | |
writable: true | |
}); | |
} catch (x) { | |
} | |
this._store.validated = false; | |
// We're not allowed to set props directly on the object so we early | |
// return and rely on the prototype membrane to forward to the backing | |
// store. | |
if (useMutationMembrane) { | |
Object.freeze(this); | |
return; | |
} | |
} | |
this.props = props; | |
}; | |
// We intentionally don't expose the function on the constructor property. | |
// ReactElement should be indistinguishable from a plain object. | |
ReactElement.prototype = { | |
_isReactElement: true | |
}; | |
if ("production" !== process.env.NODE_ENV) { | |
defineMutationMembrane(ReactElement.prototype); | |
} | |
ReactElement.createElement = function(type, config, children) { | |
var propName; | |
// Reserved names are extracted | |
var props = {}; | |
var key = null; | |
var ref = null; | |
if (config != null) { | |
ref = config.ref === undefined ? null : config.ref; | |
key = config.key === undefined ? null : '' + config.key; | |
// Remaining properties are added to a new props object | |
for (propName in config) { | |
if (config.hasOwnProperty(propName) && | |
!RESERVED_PROPS.hasOwnProperty(propName)) { | |
props[propName] = config[propName]; | |
} | |
} | |
} | |
// Children can be more than one argument, and those are transferred onto | |
// the newly allocated props object. | |
var childrenLength = arguments.length - 2; | |
if (childrenLength === 1) { | |
props.children = children; | |
} else if (childrenLength > 1) { | |
var childArray = Array(childrenLength); | |
for (var i = 0; i < childrenLength; i++) { | |
childArray[i] = arguments[i + 2]; | |
} | |
props.children = childArray; | |
} | |
// Resolve default props | |
if (type && type.defaultProps) { | |
var defaultProps = type.defaultProps; | |
for (propName in defaultProps) { | |
if (typeof props[propName] === 'undefined') { | |
props[propName] = defaultProps[propName]; | |
} | |
} | |
} | |
return new ReactElement( | |
type, | |
key, | |
ref, | |
ReactCurrentOwner.current, | |
ReactContext.current, | |
props | |
); | |
}; | |
ReactElement.createFactory = function(type) { | |
var factory = ReactElement.createElement.bind(null, type); | |
// Expose the type on the factory and the prototype so that it can be | |
// easily accessed on elements. E.g. <Foo />.type === Foo.type. | |
// This should not be named `constructor` since this may not be the function | |
// that created the element, and it may not even be a constructor. | |
// Legacy hook TODO: Warn if this is accessed | |
factory.type = type; | |
return factory; | |
}; | |
ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { | |
var newElement = new ReactElement( | |
oldElement.type, | |
oldElement.key, | |
oldElement.ref, | |
oldElement._owner, | |
oldElement._context, | |
newProps | |
); | |
if ("production" !== process.env.NODE_ENV) { | |
// If the key on the original is valid, then the clone is valid | |
newElement._store.validated = oldElement._store.validated; | |
} | |
return newElement; | |
}; | |
ReactElement.cloneElement = function(element, config, children) { | |
var propName; | |
// Original props are copied | |
var props = assign({}, element.props); | |
// Reserved names are extracted | |
var key = element.key; | |
var ref = element.ref; | |
// Owner will be preserved, unless ref is overridden | |
var owner = element._owner; | |
if (config != null) { | |
if (config.ref !== undefined) { | |
// Silently steal the ref from the parent. | |
ref = config.ref; | |
owner = ReactCurrentOwner.current; | |
} | |
if (config.key !== undefined) { | |
key = '' + config.key; | |
} | |
// Remaining properties override existing props | |
for (propName in config) { | |
if (config.hasOwnProperty(propName) && | |
!RESERVED_PROPS.hasOwnProperty(propName)) { | |
props[propName] = config[propName]; | |
} | |
} | |
} | |
// Children can be more than one argument, and those are transferred onto | |
// the newly allocated props object. | |
var childrenLength = arguments.length - 2; | |
if (childrenLength === 1) { | |
props.children = children; | |
} else if (childrenLength > 1) { | |
var childArray = Array(childrenLength); | |
for (var i = 0; i < childrenLength; i++) { | |
childArray[i] = arguments[i + 2]; | |
} | |
props.children = childArray; | |
} | |
return new ReactElement( | |
element.type, | |
key, | |
ref, | |
owner, | |
element._context, | |
props | |
); | |
}; | |
/** | |
* @param {?object} object | |
* @return {boolean} True if `object` is a valid component. | |
* @final | |
*/ | |
ReactElement.isValidElement = function(object) { | |
// ReactTestUtils is often used outside of beforeEach where as React is | |
// within it. This leads to two different instances of React on the same | |
// page. To identify a element from a different React instance we use | |
// a flag instead of an instanceof check. | |
var isElement = !!(object && object._isReactElement); | |
// if (isElement && !(object instanceof ReactElement)) { | |
// This is an indicator that you're using multiple versions of React at the | |
// same time. This will screw with ownership and stuff. Fix it, please. | |
// TODO: We could possibly warn here. | |
// } | |
return isElement; | |
}; | |
module.exports = ReactElement; | |
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(28))) | |
/***/ }, | |
/* 30 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(process) {/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactContext | |
*/ | |
'use strict'; | |
var assign = __webpack_require__(31); | |
var emptyObject = __webpack_require__(32); | |
var warning = __webpack_require__(33); | |
var didWarn = false; | |
/** | |
* Keeps track of the current context. | |
* | |
* The context is automatically passed down the component ownership hierarchy | |
* and is accessible via `this.context` on ReactCompositeComponents. | |
*/ | |
var ReactContext = { | |
/** | |
* @internal | |
* @type {object} | |
*/ | |
current: emptyObject, | |
/** | |
* Temporarily extends the current context while executing scopedCallback. | |
* | |
* A typical use case might look like | |
* | |
* render: function() { | |
* var children = ReactContext.withContext({foo: 'foo'}, () => ( | |
* | |
* )); | |
* return <div>{children}</div>; | |
* } | |
* | |
* @param {object} newContext New context to merge into the existing context | |
* @param {function} scopedCallback Callback to run with the new context | |
* @return {ReactComponent|array<ReactComponent>} | |
*/ | |
withContext: function(newContext, scopedCallback) { | |
if ("production" !== process.env.NODE_ENV) { | |
("production" !== process.env.NODE_ENV ? warning( | |
didWarn, | |
'withContext is deprecated and will be removed in a future version. ' + | |
'Use a wrapper component with getChildContext instead.' | |
) : null); | |
didWarn = true; | |
} | |
var result; | |
var previousContext = ReactContext.current; | |
ReactContext.current = assign({}, previousContext, newContext); | |
try { | |
result = scopedCallback(); | |
} finally { | |
ReactContext.current = previousContext; | |
} | |
return result; | |
} | |
}; | |
module.exports = ReactContext; | |
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(28))) | |
/***/ }, | |
/* 31 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2014-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule Object.assign | |
*/ | |
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign | |
'use strict'; | |
function assign(target, sources) { | |
if (target == null) { | |
throw new TypeError('Object.assign target cannot be null or undefined'); | |
} | |
var to = Object(target); | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { | |
var nextSource = arguments[nextIndex]; | |
if (nextSource == null) { | |
continue; | |
} | |
var from = Object(nextSource); | |
// We don't currently support accessors nor proxies. Therefore this | |
// copy cannot throw. If we ever supported this then we must handle | |
// exceptions and side-effects. We don't support symbols so they won't | |
// be transferred. | |
for (var key in from) { | |
if (hasOwnProperty.call(from, key)) { | |
to[key] = from[key]; | |
} | |
} | |
} | |
return to; | |
} | |
module.exports = assign; | |
/***/ }, | |
/* 32 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(process) {/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule emptyObject | |
*/ | |
"use strict"; | |
var emptyObject = {}; | |
if ("production" !== process.env.NODE_ENV) { | |
Object.freeze(emptyObject); | |
} | |
module.exports = emptyObject; | |
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(28))) | |
/***/ }, | |
/* 33 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(process) {/** | |
* Copyright 2014-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule warning | |
*/ | |
"use strict"; | |
var emptyFunction = __webpack_require__(34); | |
/** | |
* 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 ("production" !== process.env.NODE_ENV) { | |
warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); | |
if (format === undefined) { | |
throw new Error( | |
'`warning(condition, format, ...args)` requires a warning ' + | |
'message argument' | |
); | |
} | |
if (format.length < 10 || /^[s\W]*$/.test(format)) { | |
throw new Error( | |
'The warning format should be able to uniquely identify this ' + | |
'warning. Please, use a more descriptive format than: ' + format | |
); | |
} | |
if (format.indexOf('Failed Composite propType: ') === 0) { | |
return; // Ignore CompositeComponent proptype check. | |
} | |
if (!condition) { | |
var argIndex = 0; | |
var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); | |
console.warn(message); | |
try { | |
// --- Welcome to debugging React --- | |
// This error was thrown as a convenience so that you can use this stack | |
// to find the callsite that caused this warning to fire. | |
throw new Error(message); | |
} catch(x) {} | |
} | |
}; | |
} | |
module.exports = warning; | |
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(28))) | |
/***/ }, | |
/* 34 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule emptyFunction | |
*/ | |
function makeEmptyFunction(arg) { | |
return function() { | |
return arg; | |
}; | |
} | |
/** | |
* This function accepts and discards inputs; it has no side effects. This is | |
* primarily useful idiomatically for overridable function endpoints which | |
* always need to be callable, since JS lacks a null-call idiom ala Cocoa. | |
*/ | |
function emptyFunction() {} | |
emptyFunction.thatReturns = makeEmptyFunction; | |
emptyFunction.thatReturnsFalse = makeEmptyFunction(false); | |
emptyFunction.thatReturnsTrue = makeEmptyFunction(true); | |
emptyFunction.thatReturnsNull = makeEmptyFunction(null); | |
emptyFunction.thatReturnsThis = function() { return this; }; | |
emptyFunction.thatReturnsArgument = function(arg) { return arg; }; | |
module.exports = emptyFunction; | |
/***/ }, | |
/* 35 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactCurrentOwner | |
*/ | |
'use strict'; | |
/** | |
* Keeps track of the current owner. | |
* | |
* The current owner is the component who should own any components that are | |
* currently being constructed. | |
* | |
* The depth indicate how many composite components are above this render level. | |
*/ | |
var ReactCurrentOwner = { | |
/** | |
* @internal | |
* @type {ReactComponent} | |
*/ | |
current: null | |
}; | |
module.exports = ReactCurrentOwner; | |
/***/ }, | |
/* 36 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* 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 ReactPropTransferer | |
*/ | |
'use strict'; | |
var assign = __webpack_require__(31); | |
var emptyFunction = __webpack_require__(34); | |
var joinClasses = __webpack_require__(37); | |
/** | |
* Creates a transfer strategy that will merge prop values using the supplied | |
* `mergeStrategy`. If a prop was previously unset, this just sets it. | |
* | |
* @param {function} mergeStrategy | |
* @return {function} | |
*/ | |
function createTransferStrategy(mergeStrategy) { | |
return function(props, key, value) { | |
if (!props.hasOwnProperty(key)) { | |
props[key] = value; | |
} else { | |
props[key] = mergeStrategy(props[key], value); | |
} | |
}; | |
} | |
var transferStrategyMerge = createTransferStrategy(function(a, b) { | |
// `merge` overrides the first object's (`props[key]` above) keys using the | |
// second object's (`value`) keys. An object's style's existing `propA` would | |
// get overridden. Flip the order here. | |
return assign({}, b, a); | |
}); | |
/** | |
* Transfer strategies dictate how props are transferred by `transferPropsTo`. | |
* NOTE: if you add any more exceptions to this list you should be sure to | |
* update `cloneWithProps()` accordingly. | |
*/ | |
var TransferStrategies = { | |
/** | |
* Never transfer `children`. | |
*/ | |
children: emptyFunction, | |
/** | |
* Transfer the `className` prop by merging them. | |
*/ | |
className: createTransferStrategy(joinClasses), | |
/** | |
* Transfer the `style` prop (which is an object) by merging them. | |
*/ | |
style: transferStrategyMerge | |
}; | |
/** | |
* Mutates the first argument by transferring the properties from the second | |
* argument. | |
* | |
* @param {object} props | |
* @param {object} newProps | |
* @return {object} | |
*/ | |
function transferInto(props, newProps) { | |
for (var thisKey in newProps) { | |
if (!newProps.hasOwnProperty(thisKey)) { | |
continue; | |
} | |
var transferStrategy = TransferStrategies[thisKey]; | |
if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { | |
transferStrategy(props, thisKey, newProps[thisKey]); | |
} else if (!props.hasOwnProperty(thisKey)) { | |
props[thisKey] = newProps[thisKey]; | |
} | |
} | |
return props; | |
} | |
/** | |
* ReactPropTransferer are capable of transferring props to another component | |
* using a `transferPropsTo` method. | |
* | |
* @class ReactPropTransferer | |
*/ | |
var ReactPropTransferer = { | |
/** | |
* Merge two props objects using TransferStrategies. | |
* | |
* @param {object} oldProps original props (they take precedence) | |
* @param {object} newProps new props to merge in | |
* @return {object} a new object containing both sets of props merged. | |
*/ | |
mergeProps: function(oldProps, newProps) { | |
return transferInto(assign({}, oldProps), newProps); | |
} | |
}; | |
module.exports = ReactPropTransferer; | |
/***/ }, | |
/* 37 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule joinClasses | |
* @typechecks static-only | |
*/ | |
'use strict'; | |
/** | |
* Combines multiple className strings into one. | |
* http://jsperf.com/joinclasses-args-vs-array | |
* | |
* @param {...?string} classes | |
* @return {string} | |
*/ | |
function joinClasses(className/*, ... */) { | |
if (!className) { | |
className = ''; | |
} | |
var nextClass; | |
var argLength = arguments.length; | |
if (argLength > 1) { | |
for (var ii = 1; ii < argLength; ii++) { | |
nextClass = arguments[ii]; | |
if (nextClass) { | |
className = (className ? className + ' ' : '') + nextClass; | |
} | |
} | |
} | |
return className; | |
} | |
module.exports = joinClasses; | |
/***/ }, | |
/* 38 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule keyOf | |
*/ | |
/** | |
* Allows extraction of a minified key. Let's the build system minify keys | |
* without loosing the ability to dynamically use key strings as values | |
* themselves. Pass in an object with a single key/val pair and it will return | |
* you the string key of that single record. Suppose you want to grab the | |
* value for a key 'className' inside of an object. Key/val minification may | |
* have aliased that key to be 'xa12'. keyOf({className: null}) will return | |
* 'xa12' in that case. Resolve keys you want to use once at startup time, then | |
* reuse those resolutions. | |
*/ | |
var keyOf = function(oneKeyObj) { | |
var key; | |
for (key in oneKeyObj) { | |
if (!oneKeyObj.hasOwnProperty(key)) { | |
continue; | |
} | |
return key; | |
} | |
return null; | |
}; | |
module.exports = keyOf; | |
/***/ }, | |
/* 39 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 ReactComponentWithPureRenderMixin | |
*/ | |
'use strict'; | |
module.exports = __webpack_require__(40); | |
/***/ }, | |
/* 40 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* 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 ReactComponentWithPureRenderMixin | |
*/ | |
'use strict'; | |
var shallowEqual = __webpack_require__(41); | |
/** | |
* If your React component's render function is "pure", e.g. it will render the | |
* same result given the same props and state, provide this Mixin for a | |
* considerable performance boost. | |
* | |
* Most React components have pure render functions. | |
* | |
* Example: | |
* | |
* var ReactComponentWithPureRenderMixin = | |
* require('ReactComponentWithPureRenderMixin'); | |
* React.createClass({ | |
* mixins: [ReactComponentWithPureRenderMixin], | |
* | |
* render: function() { | |
* return <div className={this.props.className}>foo</div>; | |
* } | |
* }); | |
* | |
* Note: This only checks shallow equality for props and state. If these contain | |
* complex data structures this mixin may have false-negatives for deeper | |
* differences. Only mixin to components which have simple props and state, or | |
* use `forceUpdate()` when you know deep data structures have changed. | |
*/ | |
var ReactComponentWithPureRenderMixin = { | |
shouldComponentUpdate: function(nextProps, nextState) { | |
return !shallowEqual(this.props, nextProps) || | |
!shallowEqual(this.state, nextState); | |
} | |
}; | |
module.exports = ReactComponentWithPureRenderMixin; | |
/***/ }, | |
/* 41 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright 2013-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule shallowEqual | |
*/ | |
'use strict'; | |
/** | |
* Performs equality by iterating through keys on an object and returning | |
* false when any key has values which are not strictly equal between | |
* objA and objB. Returns true when the values of all keys are strictly equal. | |
* | |
* @return {boolean} | |
*/ | |
function shallowEqual(objA, objB) { | |
if (objA === objB) { | |
return true; | |
} | |
var key; | |
// Test for A's keys different from B. | |
for (key in objA) { | |
if (objA.hasOwnProperty(key) && | |
(!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { | |
return false; | |
} | |
} | |
// Test for B's keys missing from A. | |
for (key in objB) { | |
if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
module.exports = shallowEqual; | |
/***/ }, | |
/* 42 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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. | |
* | |
* This is utility that hanlds onWheel events and calls provided wheel | |
* callback with correct frame rate. | |
* | |
* @providesModule ReactWheelHandler | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
var emptyFunction = __webpack_require__(43); | |
var normalizeWheel = __webpack_require__(44); | |
var requestAnimationFramePolyfill = __webpack_require__(48); | |
var ReactWheelHandler = (function () { | |
/** | |
* onWheel is the callback that will be called with right frame rate if | |
* any wheel events happened | |
* onWheel should is to be called with two arguments: deltaX and deltaY in | |
* this order | |
*/ | |
function ReactWheelHandler( | |
/*function*/onWheel, | |
/*boolean|function*/handleScrollX, | |
/*boolean|function*/handleScrollY, | |
/*?boolean|?function*/stopPropagation) { | |
_classCallCheck(this, ReactWheelHandler); | |
this._animationFrameID = null; | |
this._deltaX = 0; | |
this._deltaY = 0; | |
this._didWheel = this._didWheel.bind(this); | |
if (typeof handleScrollX !== 'function') { | |
handleScrollX = handleScrollX ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse; | |
} | |
if (typeof handleScrollY !== 'function') { | |
handleScrollY = handleScrollY ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse; | |
} | |
if (typeof stopPropagation !== 'function') { | |
stopPropagation = stopPropagation ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse; | |
} | |
this._handleScrollX = handleScrollX; | |
this._handleScrollY = handleScrollY; | |
this._stopPropagation = stopPropagation; | |
this._onWheelCallback = onWheel; | |
this.onWheel = this.onWheel.bind(this); | |
} | |
_createClass(ReactWheelHandler, [{ | |
key: 'onWheel', | |
value: function onWheel( /*object*/event) { | |
var normalizedEvent = normalizeWheel(event); | |
var deltaX = this._deltaX + normalizedEvent.pixelX; | |
var deltaY = this._deltaY + normalizedEvent.pixelY; | |
var handleScrollX = this._handleScrollX(deltaX); | |
var handleScrollY = this._handleScrollY(deltaY); | |
if (!handleScrollX && !handleScrollY) { | |
return; | |
} | |
this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0; | |
this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0; | |
event.preventDefault(); | |
var changed; | |
if (this._deltaX !== 0 || this._deltaY !== 0) { | |
if (this._stopPropagation()) { | |
event.stopPropagation(); | |
} | |
changed = true; | |
} | |
if (changed === true && this._animationFrameID === null) { | |
this._animationFrameID = requestAnimationFramePolyfill(this._didWheel); | |
} | |
} | |
}, { | |
key: '_didWheel', | |
value: function _didWheel() { | |
this._animationFrameID = null; | |
this._onWheelCallback(this._deltaX, this._deltaY); | |
this._deltaX = 0; | |
this._deltaY = 0; | |
} | |
}]); | |
return ReactWheelHandler; | |
})(); | |
module.exports = ReactWheelHandler; | |
/***/ }, | |
/* 43 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule emptyFunction | |
*/ | |
"use strict"; | |
function makeEmptyFunction(arg) { | |
return function () { | |
return arg; | |
}; | |
} | |
/** | |
* This function accepts and discards inputs; it has no side effects. This is | |
* primarily useful idiomatically for overridable function endpoints which | |
* always need to be callable, since JS lacks a null-call idiom ala Cocoa. | |
*/ | |
function emptyFunction() {} | |
emptyFunction.thatReturns = makeEmptyFunction; | |
emptyFunction.thatReturnsFalse = makeEmptyFunction(false); | |
emptyFunction.thatReturnsTrue = makeEmptyFunction(true); | |
emptyFunction.thatReturnsNull = makeEmptyFunction(null); | |
emptyFunction.thatReturnsThis = function () { | |
return this; | |
}; | |
emptyFunction.thatReturnsArgument = function (arg) { | |
return arg; | |
}; | |
module.exports = emptyFunction; | |
/***/ }, | |
/* 44 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 normalizeWheel | |
* @typechecks | |
*/ | |
'use strict'; | |
var UserAgent_DEPRECATED = __webpack_require__(45); | |
var isEventSupported = __webpack_require__(46); | |
// Reasonable defaults | |
var PIXEL_STEP = 10; | |
var LINE_HEIGHT = 40; | |
var PAGE_HEIGHT = 800; | |
/** | |
* Mouse wheel (and 2-finger trackpad) support on the web sucks. It is | |
* complicated, thus this doc is long and (hopefully) detailed enough to answer | |
* your questions. | |
* | |
* If you need to react to the mouse wheel in a predictable way, this code is | |
* like your bestest friend. * hugs * | |
* | |
* As of today, there are 4 DOM event types you can listen to: | |
* | |
* 'wheel' -- Chrome(31+), FF(17+), IE(9+) | |
* 'mousewheel' -- Chrome, IE(6+), Opera, Safari | |
* 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother! | |
* 'DOMMouseScroll' -- FF(0.9.7+) since 2003 | |
* | |
* So what to do? The is the best: | |
* | |
* normalizeWheel.getEventType(); | |
* | |
* In your event callback, use this code to get sane interpretation of the | |
* deltas. This code will return an object with properties: | |
* | |
* spinX -- normalized spin speed (use for zoom) - x plane | |
* spinY -- " - y plane | |
* pixelX -- normalized distance (to pixels) - x plane | |
* pixelY -- " - y plane | |
* | |
* Wheel values are provided by the browser assuming you are using the wheel to | |
* scroll a web page by a number of lines or pixels (or pages). Values can vary | |
* significantly on different platforms and browsers, forgetting that you can | |
* scroll at different speeds. Some devices (like trackpads) emit more events | |
* at smaller increments with fine granularity, and some emit massive jumps with | |
* linear speed or acceleration. | |
* | |
* This code does its best to normalize the deltas for you: | |
* | |
* - spin is trying to normalize how far the wheel was spun (or trackpad | |
* dragged). This is super useful for zoom support where you want to | |
* throw away the chunky scroll steps on the PC and make those equal to | |
* the slow and smooth tiny steps on the Mac. Key data: This code tries to | |
* resolve a single slow step on a wheel to 1. | |
* | |
* - pixel is normalizing the desired scroll delta in pixel units. You'll | |
* get the crazy differences between browsers, but at least it'll be in | |
* pixels! | |
* | |
* - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This | |
* should translate to positive value zooming IN, negative zooming OUT. | |
* This matches the newer 'wheel' event. | |
* | |
* Why are there spinX, spinY (or pixels)? | |
* | |
* - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn | |
* with a mouse. It results in side-scrolling in the browser by default. | |
* | |
* - spinY is what you expect -- it's the classic axis of a mouse wheel. | |
* | |
* - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and | |
* probably is by browsers in conjunction with fancy 3D controllers .. but | |
* you know. | |
* | |
* Implementation info: | |
* | |
* Examples of 'wheel' event if you scroll slowly (down) by one step with an | |
* average mouse: | |
* | |
* OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120) | |
* OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12) | |
* OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A) | |
* Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120) | |
* Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120) | |
* | |
* On the trackpad: | |
* | |
* OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6) | |
* OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A) | |
* | |
* On other/older browsers.. it's more complicated as there can be multiple and | |
* also missing delta values. | |
* | |
* The 'wheel' event is more standard: | |
* | |
* http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents | |
* | |
* The basics is that it includes a unit, deltaMode (pixels, lines, pages), and | |
* deltaX, deltaY and deltaZ. Some browsers provide other values to maintain | |
* backward compatibility with older events. Those other values help us | |
* better normalize spin speed. Example of what the browsers provide: | |
* | |
* | event.wheelDelta | event.detail | |
* ------------------+------------------+-------------- | |
* Safari v5/OS X | -120 | 0 | |
* Safari v5/Win7 | -120 | 0 | |
* Chrome v17/OS X | -120 | 0 | |
* Chrome v17/Win7 | -120 | 0 | |
* IE9/Win7 | -120 | undefined | |
* Firefox v4/OS X | undefined | 1 | |
* Firefox v4/Win7 | undefined | 3 | |
* | |
*/ | |
function normalizeWheel( /*object*/event) /*object*/{ | |
var sX = 0, | |
sY = 0, | |
// spinX, spinY | |
pX = 0, | |
pY = 0; // pixelX, pixelY | |
// Legacy | |
if ('detail' in event) { | |
sY = event.detail; | |
} | |
if ('wheelDelta' in event) { | |
sY = -event.wheelDelta / 120; | |
} | |
if ('wheelDeltaY' in event) { | |
sY = -event.wheelDeltaY / 120; | |
} | |
if ('wheelDeltaX' in event) { | |
sX = -event.wheelDeltaX / 120; | |
} | |
// side scrolling on FF with DOMMouseScroll | |
if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) { | |
sX = sY; | |
sY = 0; | |
} | |
pX = sX * PIXEL_STEP; | |
pY = sY * PIXEL_STEP; | |
if ('deltaY' in event) { | |
pY = event.deltaY; | |
} | |
if ('deltaX' in event) { | |
pX = event.deltaX; | |
} | |
if ((pX || pY) && event.deltaMode) { | |
if (event.deltaMode == 1) { | |
// delta in LINE units | |
pX *= LINE_HEIGHT; | |
pY *= LINE_HEIGHT; | |
} else { | |
// delta in PAGE units | |
pX *= PAGE_HEIGHT; | |
pY *= PAGE_HEIGHT; | |
} | |
} | |
// Fall-back if spin cannot be determined | |
if (pX && !sX) { | |
sX = pX < 1 ? -1 : 1; | |
} | |
if (pY && !sY) { | |
sY = pY < 1 ? -1 : 1; | |
} | |
return { spinX: sX, | |
spinY: sY, | |
pixelX: pX, | |
pixelY: pY }; | |
} | |
/** | |
* The best combination if you prefer spinX + spinY normalization. It favors | |
* the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with | |
* 'wheel' event, making spin speed determination impossible. | |
*/ | |
normalizeWheel.getEventType = function () /*string*/{ | |
return UserAgent_DEPRECATED.firefox() ? 'DOMMouseScroll' : isEventSupported('wheel') ? 'wheel' : 'mousewheel'; | |
}; | |
module.exports = normalizeWheel; | |
/***/ }, | |
/* 45 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 UserAgent_DEPRECATED | |
*/ | |
/** | |
* Provides entirely client-side User Agent and OS detection. You should prefer | |
* the non-deprecated UserAgent module when possible, which exposes our | |
* authoritative server-side PHP-based detection to the client. | |
* | |
* Usage is straightforward: | |
* | |
* if (UserAgent_DEPRECATED.ie()) { | |
* // IE | |
* } | |
* | |
* You can also do version checks: | |
* | |
* if (UserAgent_DEPRECATED.ie() >= 7) { | |
* // IE7 or better | |
* } | |
* | |
* The browser functions will return NaN if the browser does not match, so | |
* you can also do version compares the other way: | |
* | |
* if (UserAgent_DEPRECATED.ie() < 7) { | |
* // IE6 or worse | |
* } | |
* | |
* Note that the version is a float and may include a minor version number, | |
* so you should always use range operators to perform comparisons, not | |
* strict equality. | |
* | |
* **Note:** You should **strongly** prefer capability detection to browser | |
* version detection where it's reasonable: | |
* | |
* http://www.quirksmode.org/js/support.html | |
* | |
* Further, we have a large number of mature wrapper functions and classes | |
* which abstract away many browser irregularities. Check the documentation, | |
* grep for things, or ask on javascript@lists.facebook.com before writing yet | |
* another copy of "event || window.event". | |
* | |
*/ | |
'use strict'; | |
var _populated = false; | |
// Browsers | |
var _ie, _firefox, _opera, _webkit, _chrome; | |
// Actual IE browser for compatibility mode | |
var _ie_real_version; | |
// Platforms | |
var _osx, _windows, _linux, _android; | |
// Architectures | |
var _win64; | |
// Devices | |
var _iphone, _ipad, _native; | |
var _mobile; | |
function _populate() { | |
if (_populated) { | |
return; | |
} | |
_populated = true; | |
// To work around buggy JS libraries that can't handle multi-digit | |
// version numbers, Opera 10's user agent string claims it's Opera | |
// 9, then later includes a Version/X.Y field: | |
// | |
// Opera/9.80 (foo) Presto/2.2.15 Version/10.10 | |
var uas = navigator.userAgent; | |
var agent = /(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(uas); | |
var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas); | |
_iphone = /\b(iPhone|iP[ao]d)/.exec(uas); | |
_ipad = /\b(iP[ao]d)/.exec(uas); | |
_android = /Android/i.exec(uas); | |
_native = /FBAN\/\w+;/i.exec(uas); | |
_mobile = /Mobile/i.exec(uas); | |
// Note that the IE team blog would have you believe you should be checking | |
// for 'Win64; x64'. But MSDN then reveals that you can actually be coming | |
// from either x64 or ia64; so ultimately, you should just check for Win64 | |
// as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit | |
// Windows will send 'WOW64' instead. | |
_win64 = !!/Win64/.exec(uas); | |
if (agent) { | |
_ie = agent[1] ? parseFloat(agent[1]) : agent[5] ? parseFloat(agent[5]) : NaN; | |
// IE compatibility mode | |
if (_ie && document && document.documentMode) { | |
_ie = document.documentMode; | |
} | |
// grab the "true" ie version from the trident token if available | |
var trident = /(?:Trident\/(\d+.\d+))/.exec(uas); | |
_ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie; | |
_firefox = agent[2] ? parseFloat(agent[2]) : NaN; | |
_opera = agent[3] ? parseFloat(agent[3]) : NaN; | |
_webkit = agent[4] ? parseFloat(agent[4]) : NaN; | |
if (_webkit) { | |
// We do not add the regexp to the above test, because it will always | |
// match 'safari' only since 'AppleWebKit' appears before 'Chrome' in | |
// the userAgent string. | |
agent = /(?:Chrome\/(\d+\.\d+))/.exec(uas); | |
_chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN; | |
} else { | |
_chrome = NaN; | |
} | |
} else { | |
_ie = _firefox = _opera = _chrome = _webkit = NaN; | |
} | |
if (os) { | |
if (os[1]) { | |
// Detect OS X version. If no version number matches, set _osx to true. | |
// Version examples: 10, 10_6_1, 10.7 | |
// Parses version number as a float, taking only first two sets of | |
// digits. If only one set of digits is found, returns just the major | |
// version number. | |
var ver = /(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(uas); | |
_osx = ver ? parseFloat(ver[1].replace('_', '.')) : true; | |
} else { | |
_osx = false; | |
} | |
_windows = !!os[2]; | |
_linux = !!os[3]; | |
} else { | |
_osx = _windows = _linux = false; | |
} | |
} | |
var UserAgent_DEPRECATED = { | |
/** | |
* Check if the UA is Internet Explorer. | |
* | |
* | |
* @return float|NaN Version number (if match) or NaN. | |
*/ | |
ie: function ie() { | |
return _populate() || _ie; | |
}, | |
/** | |
* Check if we're in Internet Explorer compatibility mode. | |
* | |
* @return bool true if in compatibility mode, false if | |
* not compatibility mode or not ie | |
*/ | |
ieCompatibilityMode: function ieCompatibilityMode() { | |
return _populate() || _ie_real_version > _ie; | |
}, | |
/** | |
* Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we | |
* only need this because Skype can't handle 64-bit IE yet. We need to remove | |
* this when we don't need it -- tracked by #601957. | |
*/ | |
ie64: function ie64() { | |
return UserAgent_DEPRECATED.ie() && _win64; | |
}, | |
/** | |
* Check if the UA is Firefox. | |
* | |
* | |
* @return float|NaN Version number (if match) or NaN. | |
*/ | |
firefox: function firefox() { | |
return _populate() || _firefox; | |
}, | |
/** | |
* Check if the UA is Opera. | |
* | |
* | |
* @return float|NaN Version number (if match) or NaN. | |
*/ | |
opera: function opera() { | |
return _populate() || _opera; | |
}, | |
/** | |
* Check if the UA is WebKit. | |
* | |
* | |
* @return float|NaN Version number (if match) or NaN. | |
*/ | |
webkit: function webkit() { | |
return _populate() || _webkit; | |
}, | |
/** | |
* For Push | |
* WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit | |
*/ | |
safari: function safari() { | |
return UserAgent_DEPRECATED.webkit(); | |
}, | |
/** | |
* Check if the UA is a Chrome browser. | |
* | |
* | |
* @return float|NaN Version number (if match) or NaN. | |
*/ | |
chrome: function chrome() { | |
return _populate() || _chrome; | |
}, | |
/** | |
* Check if the user is running Windows. | |
* | |
* @return bool `true' if the user's OS is Windows. | |
*/ | |
windows: function windows() { | |
return _populate() || _windows; | |
}, | |
/** | |
* Check if the user is running Mac OS X. | |
* | |
* @return float|bool Returns a float if a version number is detected, | |
* otherwise true/false. | |
*/ | |
osx: function osx() { | |
return _populate() || _osx; | |
}, | |
/** | |
* Check if the user is running Linux. | |
* | |
* @return bool `true' if the user's OS is some flavor of Linux. | |
*/ | |
linux: function linux() { | |
return _populate() || _linux; | |
}, | |
/** | |
* Check if the user is running on an iPhone or iPod platform. | |
* | |
* @return bool `true' if the user is running some flavor of the | |
* iPhone OS. | |
*/ | |
iphone: function iphone() { | |
return _populate() || _iphone; | |
}, | |
mobile: function mobile() { | |
return _populate() || (_iphone || _ipad || _android || _mobile); | |
}, | |
nativeApp: function nativeApp() { | |
// webviews inside of the native apps | |
return _populate() || _native; | |
}, | |
android: function android() { | |
return _populate() || _android; | |
}, | |
ipad: function ipad() { | |
return _populate() || _ipad; | |
} | |
}; | |
module.exports = UserAgent_DEPRECATED; | |
/***/ }, | |
/* 46 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 isEventSupported | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = __webpack_require__(47); | |
var useHasFeature; | |
if (ExecutionEnvironment.canUseDOM) { | |
useHasFeature = document.implementation && document.implementation.hasFeature && | |
// always returns true in newer browsers as per the standard. | |
// @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature | |
document.implementation.hasFeature('', '') !== true; | |
} | |
/** | |
* Checks if an event is supported in the current execution environment. | |
* | |
* NOTE: This will not work correctly for non-generic events such as `change`, | |
* `reset`, `load`, `error`, and `select`. | |
* | |
* Borrows from Modernizr. | |
* | |
* @param {string} eventNameSuffix Event name, e.g. "click". | |
* @param {?boolean} capture Check if the capture phase is supported. | |
* @return {boolean} True if the event is supported. | |
* @internal | |
* @license Modernizr 3.0.0pre (Custom Build) | MIT | |
*/ | |
function isEventSupported(eventNameSuffix, capture) { | |
if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { | |
return false; | |
} | |
var eventName = 'on' + eventNameSuffix; | |
var isSupported = (eventName in document); | |
if (!isSupported) { | |
var element = document.createElement('div'); | |
element.setAttribute(eventName, 'return;'); | |
isSupported = typeof element[eventName] === 'function'; | |
} | |
if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { | |
// This is the only way to test support for the `wheel` event in IE9+. | |
isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); | |
} | |
return isSupported; | |
} | |
module.exports = isEventSupported; | |
/***/ }, | |
/* 47 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ExecutionEnvironment | |
*/ | |
/*jslint evil: true */ | |
'use strict'; | |
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); | |
/** | |
* Simple, lightweight module assisting with the detection and context of | |
* Worker. Helps avoid circular dependencies and allows code to reason about | |
* whether or not they are in a Worker, even if they never include the main | |
* `ReactWorker` dependency. | |
*/ | |
var ExecutionEnvironment = { | |
canUseDOM: canUseDOM, | |
canUseWorkers: typeof Worker !== 'undefined', | |
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), | |
canUseViewport: canUseDOM && !!window.screen, | |
isInWorker: !canUseDOM // For now, this is true - might change in the future. | |
}; | |
module.exports = ExecutionEnvironment; | |
/***/ }, | |
/* 48 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(global) {/** | |
* Copyright (c) 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 requestAnimationFramePolyfill | |
*/ | |
'use strict'; | |
var emptyFunction = __webpack_require__(43); | |
var nativeRequestAnimationFrame = __webpack_require__(49); | |
var lastTime = 0; | |
/** | |
* Here is the native and polyfill version of requestAnimationFrame. | |
* Please don't use it directly and use requestAnimationFrame module instead. | |
*/ | |
var requestAnimationFrame = nativeRequestAnimationFrame || function (callback) { | |
var currTime = Date.now(); | |
var timeDelay = Math.max(0, 16 - (currTime - lastTime)); | |
lastTime = currTime + timeDelay; | |
return global.setTimeout(function () { | |
callback(Date.now()); | |
}, timeDelay); | |
}; | |
// Works around a rare bug in Safari 6 where the first request is never invoked. | |
requestAnimationFrame(emptyFunction); | |
module.exports = requestAnimationFrame; | |
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | |
/***/ }, | |
/* 49 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(global) {/** | |
* Copyright (c) 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 nativeRequestAnimationFrame | |
*/ | |
"use strict"; | |
var nativeRequestAnimationFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame || global.msRequestAnimationFrame; | |
module.exports = nativeRequestAnimationFrame; | |
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | |
/***/ }, | |
/* 50 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 Scrollbar.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var DOMMouseMoveTracker = __webpack_require__(51); | |
var Keys = __webpack_require__(54); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var ReactWheelHandler = __webpack_require__(42); | |
var cssVar = __webpack_require__(55); | |
var cx = __webpack_require__(56); | |
var emptyFunction = __webpack_require__(43); | |
var translateDOMPositionXY = __webpack_require__(57); | |
var PropTypes = React.PropTypes; | |
var UNSCROLLABLE_STATE = { | |
position: 0, | |
scrollable: false | |
}; | |
var FACE_MARGIN = parseInt(cssVar('scrollbar-face-margin'), 10); | |
var FACE_MARGIN_2 = FACE_MARGIN * 2; | |
var FACE_SIZE_MIN = 30; | |
var KEYBOARD_SCROLL_AMOUNT = 40; | |
var _lastScrolledScrollbar = null; | |
var Scrollbar = React.createClass({ | |
displayName: 'Scrollbar', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
contentSize: PropTypes.number.isRequired, | |
defaultPosition: PropTypes.number, | |
isOpaque: PropTypes.bool, | |
orientation: PropTypes.oneOf(['vertical', 'horizontal']), | |
onScroll: PropTypes.func, | |
position: PropTypes.number, | |
size: PropTypes.number.isRequired, | |
trackColor: PropTypes.oneOf(['gray']), | |
zIndex: PropTypes.number | |
}, | |
getInitialState: function getInitialState() /*object*/{ | |
var props = this.props; | |
return this._calculateState(props.position || props.defaultPosition || 0, props.size, props.contentSize, props.orientation); | |
}, | |
componentWillReceiveProps: function componentWillReceiveProps( /*object*/nextProps) { | |
var controlledPosition = nextProps.position; | |
if (controlledPosition === undefined) { | |
this._setNextState(this._calculateState(this.state.position, nextProps.size, nextProps.contentSize, nextProps.orientation)); | |
} else { | |
this._setNextState(this._calculateState(controlledPosition, nextProps.size, nextProps.contentSize, nextProps.orientation), nextProps); | |
} | |
}, | |
getDefaultProps: function getDefaultProps() /*object*/{ | |
return { | |
defaultPosition: 0, | |
isOpaque: false, | |
onScroll: emptyFunction, | |
orientation: 'vertical', | |
zIndex: 99 | |
}; | |
}, | |
render: function render() /*?object*/{ | |
if (!this.state.scrollable) { | |
return null; | |
} | |
var size = this.props.size; | |
var mainStyle; | |
var faceStyle; | |
var isHorizontal = this.state.isHorizontal; | |
var isVertical = !isHorizontal; | |
var isActive = this.state.focused || this.state.isDragging; | |
var faceSize = this.state.faceSize; | |
var isOpaque = this.props.isOpaque; | |
var mainClassName = cx({ | |
'public/Scrollbar/main': true, | |
'public/Scrollbar/mainHorizontal': isHorizontal, | |
'public/Scrollbar/mainVertical': isVertical, | |
'Scrollbar/mainActive': isActive, | |
'Scrollbar/mainOpaque': isOpaque | |
}); | |
var faceClassName = cx({ | |
'Scrollbar/face': true, | |
'Scrollbar/faceHorizontal': isHorizontal, | |
'Scrollbar/faceVertical': isVertical, | |
'Scrollbar/faceActive': isActive | |
}); | |
var position = this.state.position * this.state.scale + FACE_MARGIN; | |
if (isHorizontal) { | |
mainStyle = { | |
width: size | |
}; | |
faceStyle = { | |
width: faceSize - FACE_MARGIN_2 | |
}; | |
translateDOMPositionXY(faceStyle, position, 0); | |
} else { | |
mainStyle = { | |
height: size | |
}; | |
faceStyle = { | |
height: faceSize - FACE_MARGIN_2 | |
}; | |
translateDOMPositionXY(faceStyle, 0, position); | |
} | |
mainStyle.zIndex = this.props.zIndex; | |
if (this.props.trackColor === 'gray') { | |
mainStyle.backgroundColor = cssVar('fbui-desktop-background-light'); | |
} | |
return React.createElement( | |
'div', | |
{ | |
onFocus: this._onFocus, | |
onBlur: this._onBlur, | |
onKeyDown: this._onKeyDown, | |
onMouseDown: this._onMouseDown, | |
onWheel: this._wheelHandler.onWheel, | |
className: mainClassName, | |
style: mainStyle, | |
tabIndex: 0 }, | |
React.createElement('div', { | |
ref: 'face', | |
className: faceClassName, | |
style: faceStyle | |
}) | |
); | |
}, | |
componentWillMount: function componentWillMount() { | |
var isHorizontal = this.props.orientation === 'horizontal'; | |
var onWheel = isHorizontal ? this._onWheelX : this._onWheelY; | |
this._wheelHandler = new ReactWheelHandler(onWheel, this._shouldHandleX, // Should hanlde horizontal scroll | |
this._shouldHandleY // Should handle vertical scroll | |
); | |
}, | |
componentDidMount: function componentDidMount() { | |
this._mouseMoveTracker = new DOMMouseMoveTracker(this._onMouseMove, this._onMouseMoveEnd, document.documentElement); | |
if (this.props.position !== undefined && this.state.position !== this.props.position) { | |
this._didScroll(); | |
} | |
}, | |
componentWillUnmount: function componentWillUnmount() { | |
this._nextState = null; | |
this._mouseMoveTracker.releaseMouseMoves(); | |
if (_lastScrolledScrollbar === this) { | |
_lastScrolledScrollbar = null; | |
} | |
delete this._mouseMoveTracker; | |
}, | |
scrollBy: function scrollBy( /*number*/delta) { | |
this._onWheel(delta); | |
}, | |
_shouldHandleX: function _shouldHandleX( /*number*/delta) /*boolean*/{ | |
return this.props.orientation === 'horizontal' ? this._shouldHandleChange(delta) : false; | |
}, | |
_shouldHandleY: function _shouldHandleY( /*number*/delta) /*boolean*/{ | |
return this.props.orientation !== 'horizontal' ? this._shouldHandleChange(delta) : false; | |
}, | |
_shouldHandleChange: function _shouldHandleChange( /*number*/delta) /*boolean*/{ | |
var nextState = this._calculateState(this.state.position + delta, this.props.size, this.props.contentSize, this.props.orientation); | |
return nextState.position !== this.state.position; | |
}, | |
_calculateState: function _calculateState( | |
/*number*/position, | |
/*number*/size, | |
/*number*/contentSize, | |
/*string*/orientation) /*object*/{ | |
if (size < 1 || contentSize <= size) { | |
return UNSCROLLABLE_STATE; | |
} | |
var stateKey = '' + position + '_' + size + '_' + contentSize + '_' + orientation; | |
if (this._stateKey === stateKey) { | |
return this._stateForKey; | |
} | |
// There are two types of positions here. | |
// 1) Phisical position: changed by mouse / keyboard | |
// 2) Logical position: changed by props. | |
// The logical position will be kept as as internal state and the `render()` | |
// function will translate it into physical position to render. | |
var isHorizontal = orientation === 'horizontal'; | |
var scale = size / contentSize; | |
var faceSize = Math.round(size * scale); | |
if (faceSize < FACE_SIZE_MIN) { | |
scale = (size - FACE_SIZE_MIN) / (contentSize - FACE_SIZE_MIN); | |
faceSize = FACE_SIZE_MIN; | |
} | |
var scrollable = true; | |
var maxPosition = contentSize - size; | |
if (position < 0) { | |
position = 0; | |
} else if (position > maxPosition) { | |
position = maxPosition; | |
} | |
var isDragging = this._mouseMoveTracker ? this._mouseMoveTracker.isDragging() : false; | |
position = Math.round(position); | |
faceSize = Math.round(faceSize); | |
// This function should only return flat values that can be compared quiclky | |
// by `ReactComponentWithPureRenderMixin`. | |
var state = { | |
faceSize: faceSize, | |
isDragging: isDragging, | |
isHorizontal: isHorizontal, | |
position: position, | |
scale: scale, | |
scrollable: scrollable | |
}; | |
// cache the state for later use. | |
this._stateKey = stateKey; | |
this._stateForKey = state; | |
return state; | |
}, | |
_onWheelY: function _onWheelY( /*number*/deltaX, /*number*/deltaY) { | |
this._onWheel(deltaY); | |
}, | |
_onWheelX: function _onWheelX( /*number*/deltaX, /*number*/deltaY) { | |
this._onWheel(deltaX); | |
}, | |
_onWheel: function _onWheel( /*number*/delta) { | |
var props = this.props; | |
// The mouse may move faster then the animation frame does. | |
// Use `requestAnimationFrame` to avoid over-updating. | |
this._setNextState(this._calculateState(this.state.position + delta, props.size, props.contentSize, props.orientation)); | |
}, | |
_onMouseDown: function _onMouseDown( /*object*/event) { | |
var nextState; | |
if (event.target !== React.findDOMNode(this.refs.face)) { | |
// Both `offsetX` and `layerX` are non-standard DOM property but they are | |
// magically available for browsers somehow. | |
var nativeEvent = event.nativeEvent; | |
var position = this.state.isHorizontal ? nativeEvent.offsetX || nativeEvent.layerX : nativeEvent.offsetY || nativeEvent.layerY; | |
// MouseDown on the scroll-track directly, move the center of the | |
// scroll-face to the mouse position. | |
var props = this.props; | |
position = position / this.state.scale; | |
nextState = this._calculateState(position - this.state.faceSize * 0.5 / this.state.scale, props.size, props.contentSize, props.orientation); | |
} else { | |
nextState = {}; | |
} | |
nextState.focused = true; | |
this._setNextState(nextState); | |
this._mouseMoveTracker.captureMouseMoves(event); | |
// Focus the node so it may receive keyboard event. | |
React.findDOMNode(this).focus(); | |
}, | |
_onMouseMove: function _onMouseMove( /*number*/deltaX, /*number*/deltaY) { | |
var props = this.props; | |
var delta = this.state.isHorizontal ? deltaX : deltaY; | |
delta = delta / this.state.scale; | |
this._setNextState(this._calculateState(this.state.position + delta, props.size, props.contentSize, props.orientation)); | |
}, | |
_onMouseMoveEnd: function _onMouseMoveEnd() { | |
this._nextState = null; | |
this._mouseMoveTracker.releaseMouseMoves(); | |
this.setState({ isDragging: false }); | |
}, | |
_onKeyDown: function _onKeyDown( /*object*/event) { | |
var keyCode = event.keyCode; | |
if (keyCode === Keys.TAB) { | |
// Let focus move off the scrollbar. | |
return; | |
} | |
var distance = KEYBOARD_SCROLL_AMOUNT; | |
var direction = 0; | |
if (this.state.isHorizontal) { | |
switch (keyCode) { | |
case Keys.HOME: | |
direction = -1; | |
distance = this.props.contentSize; | |
break; | |
case Keys.LEFT: | |
direction = -1; | |
break; | |
case Keys.RIGHT: | |
direction = 1; | |
break; | |
default: | |
return; | |
} | |
} | |
if (!this.state.isHorizontal) { | |
switch (keyCode) { | |
case Keys.SPACE: | |
if (event.shiftKey) { | |
direction = -1; | |
} else { | |
direction = 1; | |
} | |
break; | |
case Keys.HOME: | |
direction = -1; | |
distance = this.props.contentSize; | |
break; | |
case Keys.UP: | |
direction = -1; | |
break; | |
case Keys.DOWN: | |
direction = 1; | |
break; | |
case Keys.PAGE_UP: | |
direction = -1; | |
distance = this.props.size; | |
break; | |
case Keys.PAGE_DOWN: | |
direction = 1; | |
distance = this.props.size; | |
break; | |
default: | |
return; | |
} | |
} | |
event.preventDefault(); | |
var props = this.props; | |
this._setNextState(this._calculateState(this.state.position + distance * direction, props.size, props.contentSize, props.orientation)); | |
}, | |
_onFocus: function _onFocus() { | |
this.setState({ | |
focused: true | |
}); | |
}, | |
_onBlur: function _onBlur() { | |
this.setState({ | |
focused: false | |
}); | |
}, | |
_blur: function _blur() { | |
if (this.isMounted()) { | |
try { | |
this._onBlur(); | |
React.findDOMNode(this).blur(); | |
} catch (oops) {} | |
} | |
}, | |
_setNextState: function _setNextState( /*object*/nextState, /*?object*/props) { | |
props = props || this.props; | |
var controlledPosition = props.position; | |
var willScroll = this.state.position !== nextState.position; | |
if (controlledPosition === undefined) { | |
var callback = willScroll ? this._didScroll : undefined; | |
this.setState(nextState, callback); | |
} else if (controlledPosition === nextState.position) { | |
this.setState(nextState); | |
} else { | |
// Scrolling is controlled. Don't update the state and let the owner | |
// to update the scrollbar instead. | |
if (nextState.position !== undefined && nextState.position !== this.state.position) { | |
this.props.onScroll(nextState.position); | |
} | |
return; | |
} | |
if (willScroll && _lastScrolledScrollbar !== this) { | |
_lastScrolledScrollbar && _lastScrolledScrollbar._blur(); | |
_lastScrolledScrollbar = this; | |
} | |
}, | |
_didScroll: function _didScroll() { | |
this.props.onScroll(this.state.position); | |
} | |
}); | |
Scrollbar.KEYBOARD_SCROLL_AMOUNT = KEYBOARD_SCROLL_AMOUNT; | |
Scrollbar.SIZE = parseInt(cssVar('scrollbar-size'), 10); | |
module.exports = Scrollbar; | |
// pass | |
/***/ }, | |
/* 51 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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. | |
* | |
* This class listens to events on the document and then updates a react | |
* component through callbacks. | |
* Please note that captureMouseMove must be called in | |
* order to initialize listeners on mousemove and mouseup. | |
* releaseMouseMove must be called to remove them. It is important to | |
* call releaseMouseMoves since mousemove is expensive to listen to. | |
* | |
* @providesModule DOMMouseMoveTracker | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
var EventListener = __webpack_require__(52); | |
var cancelAnimationFramePolyfill = __webpack_require__(53); | |
var requestAnimationFramePolyfill = __webpack_require__(48); | |
var DOMMouseMoveTracker = (function () { | |
/** | |
* onMove is the callback that will be called on every mouse move. | |
* onMoveEnd is called on mouse up when movement has ended. | |
*/ | |
function DOMMouseMoveTracker( | |
/*function*/onMove, | |
/*function*/onMoveEnd, | |
/*DOMElement*/domNode) { | |
_classCallCheck(this, DOMMouseMoveTracker); | |
this._isDragging = false; | |
this._animationFrameID = null; | |
this._domNode = domNode; | |
this._onMove = onMove; | |
this._onMoveEnd = onMoveEnd; | |
this._onMouseMove = this._onMouseMove.bind(this); | |
this._onMouseUp = this._onMouseUp.bind(this); | |
this._didMouseMove = this._didMouseMove.bind(this); | |
} | |
_createClass(DOMMouseMoveTracker, [{ | |
key: 'captureMouseMoves', | |
/** | |
* This is to set up the listeners for listening to mouse move | |
* and mouse up signaling the movement has ended. Please note that these | |
* listeners are added at the document.body level. It takes in an event | |
* in order to grab inital state. | |
*/ | |
value: function captureMouseMoves( /*object*/event) { | |
if (!this._eventMoveToken && !this._eventUpToken) { | |
this._eventMoveToken = EventListener.listen(this._domNode, 'mousemove', this._onMouseMove); | |
this._eventUpToken = EventListener.listen(this._domNode, 'mouseup', this._onMouseUp); | |
} | |
if (!this._isDragging) { | |
this._deltaX = 0; | |
this._deltaY = 0; | |
this._isDragging = true; | |
this._x = event.clientX; | |
this._y = event.clientY; | |
} | |
event.preventDefault(); | |
} | |
}, { | |
key: 'releaseMouseMoves', | |
/** | |
* These releases all of the listeners on document.body. | |
*/ | |
value: function releaseMouseMoves() { | |
if (this._eventMoveToken && this._eventUpToken) { | |
this._eventMoveToken.remove(); | |
this._eventMoveToken = null; | |
this._eventUpToken.remove(); | |
this._eventUpToken = null; | |
} | |
if (this._animationFrameID !== null) { | |
cancelAnimationFramePolyfill(this._animationFrameID); | |
this._animationFrameID = null; | |
} | |
if (this._isDragging) { | |
this._isDragging = false; | |
this._x = null; | |
this._y = null; | |
} | |
} | |
}, { | |
key: 'isDragging', | |
/** | |
* Returns whether or not if the mouse movement is being tracked. | |
*/ | |
value: function isDragging() /*boolean*/{ | |
return this._isDragging; | |
} | |
}, { | |
key: '_onMouseMove', | |
/** | |
* Calls onMove passed into constructor and updates internal state. | |
*/ | |
value: function _onMouseMove( /*object*/event) { | |
var x = event.clientX; | |
var y = event.clientY; | |
this._deltaX += x - this._x; | |
this._deltaY += y - this._y; | |
if (this._animationFrameID === null) { | |
// The mouse may move faster then the animation frame does. | |
// Use `requestAnimationFramePolyfill` to avoid over-updating. | |
this._animationFrameID = requestAnimationFramePolyfill(this._didMouseMove); | |
} | |
this._x = x; | |
this._y = y; | |
event.preventDefault(); | |
} | |
}, { | |
key: '_didMouseMove', | |
value: function _didMouseMove() { | |
this._animationFrameID = null; | |
this._onMove(this._deltaX, this._deltaY); | |
this._deltaX = 0; | |
this._deltaY = 0; | |
} | |
}, { | |
key: '_onMouseUp', | |
/** | |
* Calls onMoveEnd passed into constructor and updates internal state. | |
*/ | |
value: function _onMouseUp() { | |
if (this._animationFrameID) { | |
this._didMouseMove(); | |
} | |
this._onMoveEnd(); | |
} | |
}]); | |
return DOMMouseMoveTracker; | |
})(); | |
module.exports = DOMMouseMoveTracker; | |
/***/ }, | |
/* 52 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 EventListener | |
* @typechecks | |
*/ | |
'use strict'; | |
var emptyFunction = __webpack_require__(43); | |
/** | |
* Upstream version of event listener. Does not take into account specific | |
* nature of platform. | |
*/ | |
var EventListener = { | |
/** | |
* Listen to DOM events during the bubble phase. | |
* | |
* @param {DOMEventTarget} target DOM element to register listener on. | |
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'. | |
* @param {function} callback Callback function. | |
* @return {object} Object with a `remove` method. | |
*/ | |
listen: function listen(target, eventType, callback) { | |
if (target.addEventListener) { | |
target.addEventListener(eventType, callback, false); | |
return { | |
remove: function remove() { | |
target.removeEventListener(eventType, callback, false); | |
} | |
}; | |
} else if (target.attachEvent) { | |
target.attachEvent('on' + eventType, callback); | |
return { | |
remove: function remove() { | |
target.detachEvent('on' + eventType, callback); | |
} | |
}; | |
} | |
}, | |
/** | |
* Listen to DOM events during the capture phase. | |
* | |
* @param {DOMEventTarget} target DOM element to register listener on. | |
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'. | |
* @param {function} callback Callback function. | |
* @return {object} Object with a `remove` method. | |
*/ | |
capture: function capture(target, eventType, callback) { | |
if (!target.addEventListener) { | |
if (true) { | |
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); | |
} | |
return { | |
remove: emptyFunction | |
}; | |
} else { | |
target.addEventListener(eventType, callback, true); | |
return { | |
remove: function remove() { | |
target.removeEventListener(eventType, callback, true); | |
} | |
}; | |
} | |
}, | |
registerDefault: function registerDefault() {} | |
}; | |
module.exports = EventListener; | |
/***/ }, | |
/* 53 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(global) {/** | |
* Copyright (c) 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 cancelAnimationFramePolyfill | |
*/ | |
/** | |
* Here is the native and polyfill version of cancelAnimationFrame. | |
* Please don't use it directly and use cancelAnimationFrame module instead. | |
*/ | |
"use strict"; | |
var cancelAnimationFrame = global.cancelAnimationFrame || global.webkitCancelAnimationFrame || global.mozCancelAnimationFrame || global.oCancelAnimationFrame || global.msCancelAnimationFrame || global.clearTimeout; | |
module.exports = cancelAnimationFrame; | |
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | |
/***/ }, | |
/* 54 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 Keys | |
*/ | |
"use strict"; | |
module.exports = { | |
BACKSPACE: 8, | |
TAB: 9, | |
RETURN: 13, | |
ALT: 18, | |
ESC: 27, | |
SPACE: 32, | |
PAGE_UP: 33, | |
PAGE_DOWN: 34, | |
END: 35, | |
HOME: 36, | |
LEFT: 37, | |
UP: 38, | |
RIGHT: 39, | |
DOWN: 40, | |
DELETE: 46, | |
COMMA: 188, | |
PERIOD: 190, | |
A: 65, | |
Z: 90, | |
ZERO: 48, | |
NUMPAD_0: 96, | |
NUMPAD_9: 105 | |
}; | |
/***/ }, | |
/* 55 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 cssVar | |
* @typechecks | |
*/ | |
'use strict'; | |
var CSS_VARS = { | |
'scrollbar-face-active-color': '#7d7d7d', | |
'scrollbar-face-color': '#c2c2c2', | |
'scrollbar-face-margin': '4px', | |
'scrollbar-face-radius': '6px', | |
'scrollbar-size': '15px', | |
'scrollbar-size-large': '17px', | |
'scrollbar-track-color': 'rgba(255, 255, 255, 0.8)' | |
}; | |
/** | |
* @param {string} name | |
*/ | |
function cssVar(name) { | |
if (CSS_VARS.hasOwnProperty(name)) { | |
return CSS_VARS[name]; | |
} | |
throw new Error('cssVar' + '("' + name + '"): Unexpected class transformation.'); | |
} | |
cssVar.CSS_VARS = CSS_VARS; | |
module.exports = cssVar; | |
/***/ }, | |
/* 56 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule cx | |
*/ | |
'use strict'; | |
var slashReplaceRegex = /\//g; | |
var cache = {}; | |
function getClassName(className) { | |
if (cache[className]) { | |
return cache[className]; | |
} | |
cache[className] = className.replace(slashReplaceRegex, '_'); | |
return cache[className]; | |
} | |
/** | |
* This function is used to mark string literals representing CSS class names | |
* so that they can be transformed statically. This allows for modularization | |
* and minification of CSS class names. | |
* | |
* In static_upstream, this function is actually implemented, but it should | |
* eventually be replaced with something more descriptive, and the transform | |
* that is used in the main stack should be ported for use elsewhere. | |
* | |
* @param string|object className to modularize, or an object of key/values. | |
* In the object case, the values are conditions that | |
* determine if the className keys should be included. | |
* @param [string ...] Variable list of classNames in the string case. | |
* @return string Renderable space-separated CSS className. | |
*/ | |
function cx(classNames) { | |
var classNamesArray; | |
if (typeof classNames == 'object') { | |
classNamesArray = Object.keys(classNames).filter(function (className) { | |
return classNames[className]; | |
}); | |
} else { | |
classNamesArray = Array.prototype.slice.call(arguments); | |
} | |
return classNamesArray.map(getClassName).join(' '); | |
} | |
module.exports = cx; | |
/***/ }, | |
/* 57 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/* WEBPACK VAR INJECTION */(function(global) {/** | |
* Copyright (c) 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 translateDOMPositionXY | |
* @typechecks | |
*/ | |
'use strict'; | |
var BrowserSupportCore = __webpack_require__(58); | |
var getVendorPrefixedName = __webpack_require__(59); | |
var TRANSFORM = getVendorPrefixedName('transform'); | |
var BACKFACE_VISIBILITY = getVendorPrefixedName('backfaceVisibility'); | |
var translateDOMPositionXY = (function () { | |
if (BrowserSupportCore.hasCSSTransforms()) { | |
var ua = global.window ? global.window.navigator.userAgent : 'UNKNOWN'; | |
var isSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua); | |
// It appears that Safari messes up the composition order | |
// of GPU-accelerated layers | |
// (see bug https://bugs.webkit.org/show_bug.cgi?id=61824). | |
// Use 2D translation instead. | |
if (!isSafari && BrowserSupportCore.hasCSS3DTransforms()) { | |
return function ( /*object*/style, /*number*/x, /*number*/y) { | |
style[TRANSFORM] = 'translate3d(' + x + 'px,' + y + 'px,0)'; | |
style[BACKFACE_VISIBILITY] = 'hidden'; | |
}; | |
} else { | |
return function ( /*object*/style, /*number*/x, /*number*/y) { | |
style[TRANSFORM] = 'translate(' + x + 'px,' + y + 'px)'; | |
}; | |
} | |
} else { | |
return function ( /*object*/style, /*number*/x, /*number*/y) { | |
style.left = x + 'px'; | |
style.top = y + 'px'; | |
}; | |
} | |
})(); | |
module.exports = translateDOMPositionXY; | |
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | |
/***/ }, | |
/* 58 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 BrowserSupportCore | |
*/ | |
'use strict'; | |
var getVendorPrefixedName = __webpack_require__(59); | |
var BrowserSupportCore = { | |
/** | |
* @return {bool} True if browser supports css animations. | |
*/ | |
hasCSSAnimations: function hasCSSAnimations() { | |
return !!getVendorPrefixedName('animationName'); | |
}, | |
/** | |
* @return {bool} True if browser supports css transforms. | |
*/ | |
hasCSSTransforms: function hasCSSTransforms() { | |
return !!getVendorPrefixedName('transform'); | |
}, | |
/** | |
* @return {bool} True if browser supports css 3d transforms. | |
*/ | |
hasCSS3DTransforms: function hasCSS3DTransforms() { | |
return !!getVendorPrefixedName('perspective'); | |
}, | |
/** | |
* @return {bool} True if browser supports css transitions. | |
*/ | |
hasCSSTransitions: function hasCSSTransitions() { | |
return !!getVendorPrefixedName('transition'); | |
} | |
}; | |
module.exports = BrowserSupportCore; | |
/***/ }, | |
/* 59 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 getVendorPrefixedName | |
* @typechecks | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = __webpack_require__(47); | |
var camelize = __webpack_require__(60); | |
var invariant = __webpack_require__(61); | |
var memoized = {}; | |
var prefixes = ['Webkit', 'ms', 'Moz', 'O']; | |
var prefixRegex = new RegExp('^(' + prefixes.join('|') + ')'); | |
var testStyle = ExecutionEnvironment.canUseDOM ? document.createElement('div').style : {}; | |
function getWithPrefix(name) { | |
for (var i = 0; i < prefixes.length; i++) { | |
var prefixedName = prefixes[i] + name; | |
if (prefixedName in testStyle) { | |
return prefixedName; | |
} | |
} | |
return null; | |
} | |
/** | |
* @param {string} property Name of a css property to check for. | |
* @return {?string} property name supported in the browser, or null if not | |
* supported. | |
*/ | |
function getVendorPrefixedName(property) { | |
var name = camelize(property); | |
if (memoized[name] === undefined) { | |
var capitalizedName = name.charAt(0).toUpperCase() + name.slice(1); | |
if (prefixRegex.test(capitalizedName)) { | |
invariant(false, 'getVendorPrefixedName must only be called with unprefixed' + 'CSS property names. It was called with %s', property); | |
} | |
memoized[name] = name in testStyle ? name : getWithPrefix(capitalizedName); | |
} | |
return memoized[name]; | |
} | |
module.exports = getVendorPrefixedName; | |
/***/ }, | |
/* 60 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule camelize | |
* @typechecks | |
*/ | |
"use strict"; | |
var _hyphenPattern = /-(.)/g; | |
/** | |
* Camelcases a hyphenated string, for example: | |
* | |
* > camelize('background-color') | |
* < "backgroundColor" | |
* | |
* @param {string} string | |
* @return {string} | |
*/ | |
function camelize(string) { | |
return string.replace(_hyphenPattern, function (_, character) { | |
return character.toUpperCase(); | |
}); | |
} | |
module.exports = camelize; | |
/***/ }, | |
/* 61 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule invariant | |
*/ | |
'use strict'; | |
/** | |
* Use invariant() to assert state which your program assumes to be true. | |
* | |
* Provide sprintf-style format (only %s is supported) and arguments | |
* to provide information about what broke and what you were | |
* expecting. | |
* | |
* The invariant message will be stripped in production, but the invariant | |
* will remain to ensure logic does not differ in production. | |
*/ | |
var invariant = function invariant(condition, format, a, b, c, d, e, f) { | |
if (true) { | |
if (format === undefined) { | |
throw new Error('invariant requires an error message argument'); | |
} | |
} | |
if (!condition) { | |
var error; | |
if (format === undefined) { | |
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); | |
} else { | |
var args = [a, b, c, d, e, f]; | |
var argIndex = 0; | |
error = new Error('Invariant Violation: ' + format.replace(/%s/g, function () { | |
return args[argIndex++]; | |
})); | |
} | |
error.framesToPop = 1; // we don't care about invariant's own frame | |
throw error; | |
} | |
}; | |
module.exports = invariant; | |
/***/ }, | |
/* 62 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableBufferedRows.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var React = __webpack_require__(22); | |
var FixedDataTableRowBuffer = __webpack_require__(63); | |
var FixedDataTableRow = __webpack_require__(66); | |
var cx = __webpack_require__(56); | |
var emptyFunction = __webpack_require__(43); | |
var joinClasses = __webpack_require__(75); | |
var translateDOMPositionXY = __webpack_require__(57); | |
var PropTypes = React.PropTypes; | |
var FixedDataTableBufferedRows = React.createClass({ | |
displayName: 'FixedDataTableBufferedRows', | |
propTypes: { | |
defaultRowHeight: PropTypes.number.isRequired, | |
firstRowIndex: PropTypes.number.isRequired, | |
firstRowOffset: PropTypes.number.isRequired, | |
fixedColumns: PropTypes.array.isRequired, | |
height: PropTypes.number.isRequired, | |
offsetTop: PropTypes.number.isRequired, | |
onRowClick: PropTypes.func, | |
onRowDoubleClick: PropTypes.func, | |
onRowMouseDown: PropTypes.func, | |
onRowMouseEnter: PropTypes.func, | |
onRowMouseLeave: PropTypes.func, | |
rowClassNameGetter: PropTypes.func, | |
rowsCount: PropTypes.number.isRequired, | |
rowGetter: PropTypes.func.isRequired, | |
rowHeightGetter: PropTypes.func, | |
rowPositionGetter: PropTypes.func.isRequired, | |
scrollLeft: PropTypes.number.isRequired, | |
scrollableColumns: PropTypes.array.isRequired, | |
showLastRowBorder: PropTypes.bool, | |
width: PropTypes.number.isRequired | |
}, | |
getInitialState: function getInitialState() /*object*/{ | |
this._rowBuffer = new FixedDataTableRowBuffer(this.props.rowsCount, this.props.defaultRowHeight, this.props.height, this._getRowHeight); | |
return { | |
rowsToRender: this._rowBuffer.getRows(this.props.firstRowIndex, this.props.firstRowOffset) | |
}; | |
}, | |
componentWillMount: function componentWillMount() { | |
this._staticRowArray = []; | |
}, | |
componentDidMount: function componentDidMount() { | |
this._bufferUpdateTimer = setTimeout(this._updateBuffer, 1000); | |
}, | |
componentWillReceiveProps: function componentWillReceiveProps( /*object*/nextProps) { | |
if (nextProps.rowsCount !== this.props.rowsCount || nextProps.defaultRowHeight !== this.props.defaultRowHeight || nextProps.height !== this.props.height) { | |
this._rowBuffer = new FixedDataTableRowBuffer(nextProps.rowsCount, nextProps.defaultRowHeight, nextProps.height, this._getRowHeight); | |
} | |
this.setState({ | |
rowsToRender: this._rowBuffer.getRows(nextProps.firstRowIndex, nextProps.firstRowOffset) | |
}); | |
if (this._bufferUpdateTimer) { | |
clearTimeout(this._bufferUpdateTimer); | |
} | |
this._bufferUpdateTimer = setTimeout(this._updateBuffer, 400); | |
}, | |
_updateBuffer: function _updateBuffer() { | |
this._bufferUpdateTimer = null; | |
if (this.isMounted()) { | |
this.setState({ | |
rowsToRender: this._rowBuffer.getRowsWithUpdatedBuffer() | |
}); | |
} | |
}, | |
shouldComponentUpdate: function shouldComponentUpdate() /*boolean*/{ | |
// Don't add PureRenderMixin to this component please. | |
return true; | |
}, | |
componentWillUnmount: function componentWillUnmount() { | |
this._staticRowArray.length = 0; | |
}, | |
render: function render() /*object*/{ | |
var props = this.props; | |
var rowClassNameGetter = props.rowClassNameGetter || emptyFunction; | |
var rowGetter = props.rowGetter; | |
var rowPositionGetter = props.rowPositionGetter; | |
var rowsToRender = this.state.rowsToRender; | |
this._staticRowArray.length = rowsToRender.length; | |
for (var i = 0; i < rowsToRender.length; ++i) { | |
var rowIndex = rowsToRender[i]; | |
var currentRowHeight = this._getRowHeight(rowIndex); | |
var rowOffsetTop = rowPositionGetter(rowIndex); | |
var hasBottomBorder = rowIndex === props.rowsCount - 1 && props.showLastRowBorder; | |
this._staticRowArray[i] = React.createElement(FixedDataTableRow, { | |
key: i, | |
index: rowIndex, | |
data: rowGetter(rowIndex), | |
width: props.width, | |
height: currentRowHeight, | |
scrollLeft: Math.round(props.scrollLeft), | |
offsetTop: Math.round(rowOffsetTop), | |
fixedColumns: props.fixedColumns, | |
scrollableColumns: props.scrollableColumns, | |
onClick: props.onRowClick, | |
onDoubleClick: props.onRowDoubleClick, | |
onMouseDown: props.onRowMouseDown, | |
onMouseEnter: props.onRowMouseEnter, | |
onMouseLeave: props.onRowMouseLeave, | |
className: joinClasses(rowClassNameGetter(rowIndex), cx('public/fixedDataTable/bodyRow'), hasBottomBorder ? cx('fixedDataTable/hasBottomBorder') : null) | |
}); | |
} | |
var firstRowPosition = props.rowPositionGetter(props.firstRowIndex); | |
var style = { | |
position: 'absolute' | |
}; | |
translateDOMPositionXY(style, 0, props.firstRowOffset - firstRowPosition + props.offsetTop); | |
return React.createElement( | |
'div', | |
{ style: style }, | |
this._staticRowArray | |
); | |
}, | |
_getRowHeight: function _getRowHeight( /*number*/index) /*number*/{ | |
return this.props.rowHeightGetter ? this.props.rowHeightGetter(index) : this.props.defaultRowHeight; | |
} | |
}); | |
module.exports = FixedDataTableBufferedRows; | |
/***/ }, | |
/* 63 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableRowBuffer | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
var IntegerBufferSet = __webpack_require__(64); | |
var clamp = __webpack_require__(19); | |
var invariant = __webpack_require__(61); | |
var MIN_BUFFER_ROWS = 3; | |
var MAX_BUFFER_ROWS = 6; | |
// FixedDataTableRowBuffer is a helper class that executes row buffering | |
// logic for FixedDataTable. It figures out which rows should be rendered | |
// and in which positions. | |
var FixedDataTableRowBuffer = (function () { | |
function FixedDataTableRowBuffer( | |
/*number*/rowsCount, | |
/*number*/defaultRowHeight, | |
/*number*/viewportHeight, | |
/*?function*/rowHeightGetter) { | |
_classCallCheck(this, FixedDataTableRowBuffer); | |
invariant(defaultRowHeight !== 0, 'defaultRowHeight musn\'t be equal 0 in FixedDataTableRowBuffer'); | |
this._bufferSet = new IntegerBufferSet(); | |
this._defaultRowHeight = defaultRowHeight; | |
this._viewportRowsBegin = 0; | |
this._viewportRowsEnd = 0; | |
this._maxVisibleRowCount = Math.ceil(viewportHeight / defaultRowHeight) + 1; | |
this._bufferRowsCount = clamp(MIN_BUFFER_ROWS, Math.floor(this._maxVisibleRowCount / 2), MAX_BUFFER_ROWS); | |
this._rowsCount = rowsCount; | |
this._rowHeightGetter = rowHeightGetter; | |
this._rows = []; | |
this._viewportHeight = viewportHeight; | |
this.getRows = this.getRows.bind(this); | |
this.getRowsWithUpdatedBuffer = this.getRowsWithUpdatedBuffer.bind(this); | |
} | |
_createClass(FixedDataTableRowBuffer, [{ | |
key: 'getRowsWithUpdatedBuffer', | |
value: function getRowsWithUpdatedBuffer() /*array*/{ | |
var remainingBufferRows = 2 * this._bufferRowsCount; | |
var bufferRowIndex = Math.max(this._viewportRowsBegin - this._bufferRowsCount, 0); | |
while (bufferRowIndex < this._viewportRowsBegin) { | |
this._addRowToBuffer(bufferRowIndex, this._viewportRowsBegin, this._viewportRowsEnd - 1); | |
bufferRowIndex++; | |
remainingBufferRows--; | |
} | |
bufferRowIndex = this._viewportRowsEnd; | |
while (bufferRowIndex < this._rowsCount && remainingBufferRows > 0) { | |
this._addRowToBuffer(bufferRowIndex, this._viewportRowsBegin, this._viewportRowsEnd - 1); | |
bufferRowIndex++; | |
remainingBufferRows--; | |
} | |
return this._rows; | |
} | |
}, { | |
key: 'getRows', | |
value: function getRows( | |
/*number*/firstRowIndex, | |
/*number*/firstRowOffset) /*array*/{ | |
var top = firstRowOffset; | |
var totalHeight = top; | |
var rowIndex = firstRowIndex; | |
var endIndex = Math.min(firstRowIndex + this._maxVisibleRowCount, this._rowsCount); | |
this._viewportRowsBegin = firstRowIndex; | |
while (rowIndex < endIndex || totalHeight < this._viewportHeight && rowIndex < this._rowsCount) { | |
this._addRowToBuffer(rowIndex, firstRowIndex, endIndex - 1); | |
totalHeight += this._rowHeightGetter(rowIndex); | |
++rowIndex; | |
// Store index after the last viewport row as end, to be able to | |
// distinguish when there are no rows rendered in viewport | |
this._viewportRowsEnd = rowIndex; | |
} | |
return this._rows; | |
} | |
}, { | |
key: '_addRowToBuffer', | |
value: function _addRowToBuffer( | |
/*number*/rowIndex, | |
/*number*/firstViewportRowIndex, | |
/*number*/lastViewportRowIndex) { | |
var rowPosition = this._bufferSet.getValuePosition(rowIndex); | |
var viewportRowsCount = lastViewportRowIndex - firstViewportRowIndex + 1; | |
var allowedRowsCount = viewportRowsCount + this._bufferRowsCount * 2; | |
if (rowPosition === null && this._bufferSet.getSize() >= allowedRowsCount) { | |
rowPosition = this._bufferSet.replaceFurthestValuePosition(firstViewportRowIndex, lastViewportRowIndex, rowIndex); | |
} | |
if (rowPosition === null) { | |
// We can't reuse any of existing positions for this row. We have to | |
// create new position | |
rowPosition = this._bufferSet.getNewPositionForValue(rowIndex); | |
this._rows[rowPosition] = rowIndex; | |
} else { | |
// This row already is in the table with rowPosition position or it | |
// can replace row that is in that position | |
this._rows[rowPosition] = rowIndex; | |
} | |
} | |
}]); | |
return FixedDataTableRowBuffer; | |
})(); | |
module.exports = FixedDataTableRowBuffer; | |
/***/ }, | |
/* 64 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 IntegerBufferSet | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
var Heap = __webpack_require__(65); | |
var invariant = __webpack_require__(61); | |
// Data structure that allows to store values and assign positions to them | |
// in a way to minimize changing positions of stored values when new ones are | |
// added or when some values are replaced. Stored elements are alwasy assigned | |
// a consecutive set of positoins startin from 0 up to count of elements less 1 | |
// Following actions can be executed | |
// * get position assigned to given value (null if value is not stored) | |
// * create new entry for new value and get assigned position back | |
// * replace value that is furthest from specified value range with new value | |
// and get it's position back | |
// All operations take amortized log(n) time where n is number of elements in | |
// the set. | |
var IntegerBufferSet = (function () { | |
function IntegerBufferSet() { | |
_classCallCheck(this, IntegerBufferSet); | |
this._valueToPositionMap = {}; | |
this._size = 0; | |
this._smallValues = new Heap([], // Initial data in the heap | |
this._smallerComparator); | |
this._largeValues = new Heap([], // Initial data in the heap | |
this._greaterComparator); | |
this.getNewPositionForValue = this.getNewPositionForValue.bind(this); | |
this.getValuePosition = this.getValuePosition.bind(this); | |
this.getSize = this.getSize.bind(this); | |
this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this); | |
} | |
_createClass(IntegerBufferSet, [{ | |
key: 'getSize', | |
value: function getSize() /*number*/{ | |
return this._size; | |
} | |
}, { | |
key: 'getValuePosition', | |
value: function getValuePosition( /*number*/value) /*?number*/{ | |
if (this._valueToPositionMap[value] === undefined) { | |
return null; | |
} | |
return this._valueToPositionMap[value]; | |
} | |
}, { | |
key: 'getNewPositionForValue', | |
value: function getNewPositionForValue( /*number*/value) /*number*/{ | |
invariant(this._valueToPositionMap[value] === undefined, 'Shouldn\'t try to find new position for value already stored in BufferSet'); | |
var newPosition = this._size; | |
this._size++; | |
this._pushToHeaps(newPosition, value); | |
this._valueToPositionMap[value] = newPosition; | |
return newPosition; | |
} | |
}, { | |
key: 'replaceFurthestValuePosition', | |
value: function replaceFurthestValuePosition( | |
/*number*/lowValue, | |
/*number*/highValue, | |
/*number*/newValue) /*?number*/{ | |
invariant(this._valueToPositionMap[newValue] === undefined, 'Shouldn\'t try to replace values with value already stored value in ' + 'BufferSet'); | |
this._cleanHeaps(); | |
if (this._smallValues.empty() || this._largeValues.empty()) { | |
// Threre are currently no values stored. We will have to create new | |
// position for this value. | |
return null; | |
} | |
var minValue = this._smallValues.peek().value; | |
var maxValue = this._largeValues.peek().value; | |
if (minValue >= lowValue && maxValue <= highValue) { | |
// All values currently stored are necessary, we can't reuse any of them. | |
return null; | |
} | |
var valueToReplace; | |
if (lowValue - minValue > maxValue - highValue) { | |
// minValue is further from provided range. We will reuse it's position. | |
valueToReplace = minValue; | |
this._smallValues.pop(); | |
} else { | |
valueToReplace = maxValue; | |
this._largeValues.pop(); | |
} | |
var position = this._valueToPositionMap[valueToReplace]; | |
delete this._valueToPositionMap[valueToReplace]; | |
this._valueToPositionMap[newValue] = position; | |
this._pushToHeaps(position, newValue); | |
return position; | |
} | |
}, { | |
key: '_pushToHeaps', | |
value: function _pushToHeaps( /*number*/position, /*number*/value) { | |
var element = { | |
position: position, | |
value: value | |
}; | |
// We can reuse the same object in both heaps, because we don't mutate them | |
this._smallValues.push(element); | |
this._largeValues.push(element); | |
} | |
}, { | |
key: '_cleanHeaps', | |
value: function _cleanHeaps() { | |
// We not usually only remove object from one heap while moving value. | |
// Here we make sure that there is no stale data on top of heaps. | |
this._cleanHeap(this._smallValues); | |
this._cleanHeap(this._largeValues); | |
var minHeapSize = Math.min(this._smallValues.size(), this._largeValues.size()); | |
var maxHeapSize = Math.max(this._smallValues.size(), this._largeValues.size()); | |
if (maxHeapSize > 10 * minHeapSize) { | |
// There are many old values in one of heaps. We nned to get rid of them | |
// to not use too avoid memory leaks | |
this._recreateHeaps(); | |
} | |
} | |
}, { | |
key: '_recreateHeaps', | |
value: function _recreateHeaps() { | |
var sourceHeap = this._smallValues.size() < this._largeValues.size() ? this._smallValues : this._largeValues; | |
var newSmallValues = new Heap([], // Initial data in the heap | |
this._smallerComparator); | |
var newLargeValues = new Heap([], // Initial datat in the heap | |
this._greaterComparator); | |
while (!sourceHeap.empty()) { | |
var element = sourceHeap.pop(); | |
// Push all stil valid elements to new heaps | |
if (this._valueToPositionMap[element.value] !== undefined) { | |
newSmallValues.push(element); | |
newLargeValues.push(element); | |
} | |
} | |
this._smallValues = newSmallValues; | |
this._largeValues = newLargeValues; | |
} | |
}, { | |
key: '_cleanHeap', | |
value: function _cleanHeap( /*object*/heap) { | |
while (!heap.empty() && this._valueToPositionMap[heap.peek().value] === undefined) { | |
heap.pop(); | |
} | |
} | |
}, { | |
key: '_smallerComparator', | |
value: function _smallerComparator( /*object*/lhs, /*object*/rhs) /*boolean*/{ | |
return lhs.value < rhs.value; | |
} | |
}, { | |
key: '_greaterComparator', | |
value: function _greaterComparator( /*object*/lhs, /*object*/rhs) /*boolean*/{ | |
return lhs.value > rhs.value; | |
} | |
}]); | |
return IntegerBufferSet; | |
})(); | |
module.exports = IntegerBufferSet; | |
/***/ }, | |
/* 65 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 Heap | |
* @typechecks | |
* @preventMunge | |
*/ | |
'use strict'; | |
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
/* | |
* @param {*} a | |
* @param {*} b | |
* @return {boolean} | |
*/ | |
function defaultComparator(a, b) { | |
return a < b; | |
} | |
var Heap = (function () { | |
function Heap(items, comparator) { | |
_classCallCheck(this, Heap); | |
this._items = items || []; | |
this._size = this._items.length; | |
this._comparator = comparator || defaultComparator; | |
this._heapify(); | |
} | |
_createClass(Heap, [{ | |
key: 'empty', | |
/* | |
* @return {boolean} | |
*/ | |
value: function empty() { | |
return this._size === 0; | |
} | |
}, { | |
key: 'pop', | |
/* | |
* @return {*} | |
*/ | |
value: function pop() { | |
if (this._size === 0) { | |
return; | |
} | |
var elt = this._items[0]; | |
var lastElt = this._items.pop(); | |
this._size--; | |
if (this._size > 0) { | |
this._items[0] = lastElt; | |
this._sinkDown(0); | |
} | |
return elt; | |
} | |
}, { | |
key: 'push', | |
/* | |
* @param {*} item | |
*/ | |
value: function push(item) { | |
this._items[this._size++] = item; | |
this._bubbleUp(this._size - 1); | |
} | |
}, { | |
key: 'size', | |
/* | |
* @return {number} | |
*/ | |
value: function size() { | |
return this._size; | |
} | |
}, { | |
key: 'peek', | |
/* | |
* @return {*} | |
*/ | |
value: function peek() { | |
if (this._size === 0) { | |
return; | |
} | |
return this._items[0]; | |
} | |
}, { | |
key: '_heapify', | |
value: function _heapify() { | |
for (var index = Math.floor((this._size + 1) / 2); index >= 0; index--) { | |
this._sinkDown(index); | |
} | |
} | |
}, { | |
key: '_bubbleUp', | |
/* | |
* @parent {number} index | |
*/ | |
value: function _bubbleUp(index) { | |
var elt = this._items[index]; | |
while (index > 0) { | |
var parentIndex = Math.floor((index + 1) / 2) - 1; | |
var parentElt = this._items[parentIndex]; | |
// if parentElt < elt, stop | |
if (this._comparator(parentElt, elt)) { | |
return; | |
} | |
// swap | |
this._items[parentIndex] = elt; | |
this._items[index] = parentElt; | |
index = parentIndex; | |
} | |
} | |
}, { | |
key: '_sinkDown', | |
/* | |
* @parent {number} index | |
*/ | |
value: function _sinkDown(index) { | |
var elt = this._items[index]; | |
while (true) { | |
var leftChildIndex = 2 * (index + 1) - 1; | |
var rightChildIndex = 2 * (index + 1); | |
var swapIndex = -1; | |
if (leftChildIndex < this._size) { | |
var leftChild = this._items[leftChildIndex]; | |
if (this._comparator(leftChild, elt)) { | |
swapIndex = leftChildIndex; | |
} | |
} | |
if (rightChildIndex < this._size) { | |
var rightChild = this._items[rightChildIndex]; | |
if (this._comparator(rightChild, elt)) { | |
if (swapIndex === -1 || this._comparator(rightChild, this._items[swapIndex])) { | |
swapIndex = rightChildIndex; | |
} | |
} | |
} | |
// if we don't have a swap, stop | |
if (swapIndex === -1) { | |
return; | |
} | |
this._items[index] = this._items[swapIndex]; | |
this._items[swapIndex] = elt; | |
index = swapIndex; | |
} | |
} | |
}]); | |
return Heap; | |
})(); | |
module.exports = Heap; | |
/***/ }, | |
/* 66 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableRow.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
var FixedDataTableHelper = __webpack_require__(20); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var FixedDataTableCellGroup = __webpack_require__(67); | |
var cx = __webpack_require__(56); | |
var joinClasses = __webpack_require__(75); | |
var translateDOMPositionXY = __webpack_require__(57); | |
var DIR_SIGN = FixedDataTableHelper.DIR_SIGN; | |
var PropTypes = React.PropTypes; | |
/** | |
* Component that renders the row for <FixedDataTable />. | |
* This component should not be used directly by developer. Instead, | |
* only <FixedDataTable /> should use the component internally. | |
*/ | |
var FixedDataTableRowImpl = React.createClass({ | |
displayName: 'FixedDataTableRowImpl', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
/** | |
* The row data to render. The data format can be a simple Map object | |
* or an Array of data. | |
*/ | |
data: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), | |
/** | |
* Array of <FixedDataTableColumn /> for the fixed columns. | |
*/ | |
fixedColumns: PropTypes.array.isRequired, | |
/** | |
* Height of the row. | |
*/ | |
height: PropTypes.number.isRequired, | |
/** | |
* The row index. | |
*/ | |
index: PropTypes.number.isRequired, | |
/** | |
* Array of <FixedDataTableColumn /> for the scrollable columns. | |
*/ | |
scrollableColumns: PropTypes.array.isRequired, | |
/** | |
* The distance between the left edge of the table and the leftmost portion | |
* of the row currently visible in the table. | |
*/ | |
scrollLeft: PropTypes.number.isRequired, | |
/** | |
* Width of the row. | |
*/ | |
width: PropTypes.number.isRequired, | |
/** | |
* Fire when a row is clicked. | |
*/ | |
onClick: PropTypes.func, | |
/** | |
* Fire when a row is double clicked. | |
*/ | |
onDoubleClick: PropTypes.func, | |
/** | |
* Callback for when resizer knob (in FixedDataTableCell) is clicked | |
* to initialize resizing. Please note this is only on the cells | |
* in the header. | |
* @param number combinedWidth | |
* @param number leftOffset | |
* @param number cellWidth | |
* @param number|string columnKey | |
* @param object event | |
*/ | |
onColumnResize: PropTypes.func | |
}, | |
render: function render() /*object*/{ | |
var style = { | |
width: this.props.width, | |
height: this.props.height | |
}; | |
var className = cx({ | |
'public/fixedDataTableRow/main': true, | |
'public/fixedDataTableRow/highlighted': this.props.index % 2 === 1 | |
}); | |
if (!this.props.data) { | |
return React.createElement('div', { | |
className: joinClasses(className, this.props.className), | |
style: style | |
}); | |
} | |
var fixedColumnsWidth = this._getColumnsWidth(this.props.fixedColumns); | |
var fixedColumns = React.createElement(FixedDataTableCellGroup, { | |
key: 'fixed_cells', | |
height: this.props.height, | |
left: 0, | |
width: fixedColumnsWidth, | |
zIndex: 2, | |
columns: this.props.fixedColumns, | |
data: this.props.data, | |
onColumnResize: this.props.onColumnResize, | |
rowHeight: this.props.height, | |
rowIndex: this.props.index | |
}); | |
var columnsShadow = this._renderColumnsShadow(fixedColumnsWidth); | |
var scrollableColumns = React.createElement(FixedDataTableCellGroup, { | |
key: 'scrollable_cells', | |
height: this.props.height, | |
left: this.props.scrollLeft * DIR_SIGN, | |
offsetLeft: fixedColumnsWidth * DIR_SIGN, | |
width: this.props.width - fixedColumnsWidth, | |
zIndex: 0, | |
columns: this.props.scrollableColumns, | |
data: this.props.data, | |
onColumnResize: this.props.onColumnResize, | |
rowHeight: this.props.height, | |
rowIndex: this.props.index | |
}); | |
return React.createElement( | |
'div', | |
{ | |
className: joinClasses(className, this.props.className), | |
onClick: this.props.onClick ? this._onClick : null, | |
onDoubleClick: this.props.onDoubleClick ? this._onDoubleClick : null, | |
onMouseDown: this.props.onMouseDown ? this._onMouseDown : null, | |
onMouseEnter: this.props.onMouseEnter ? this._onMouseEnter : null, | |
onMouseLeave: this.props.onMouseLeave ? this._onMouseLeave : null, | |
style: style }, | |
React.createElement( | |
'div', | |
{ className: cx('fixedDataTableRow/body') }, | |
fixedColumns, | |
scrollableColumns, | |
columnsShadow | |
) | |
); | |
}, | |
_getColumnsWidth: function _getColumnsWidth( /*array*/columns) /*number*/{ | |
var width = 0; | |
for (var i = 0; i < columns.length; ++i) { | |
width += columns[i].props.width; | |
} | |
return width; | |
}, | |
_renderColumnsShadow: function _renderColumnsShadow( /*number*/left) /*?object*/{ | |
if (left > 0) { | |
var className = cx({ | |
'fixedDataTableRow/fixedColumnsDivider': true, | |
'fixedDataTableRow/columnsShadow': this.props.scrollLeft > 0 | |
}); | |
var style = { | |
left: left, | |
height: this.props.height | |
}; | |
return React.createElement('div', { className: className, style: style }); | |
} | |
}, | |
_onClick: function _onClick( /*object*/event) { | |
this.props.onClick(event, this.props.index, this.props.data); | |
}, | |
_onDoubleClick: function _onDoubleClick( /*object*/event) { | |
this.props.onDoubleClick(event, this.props.index, this.props.data); | |
}, | |
_onMouseDown: function _onMouseDown( /*object*/event) { | |
this.props.onMouseDown(event, this.props.index, this.props.data); | |
}, | |
_onMouseEnter: function _onMouseEnter( /*object*/event) { | |
this.props.onMouseEnter(event, this.props.index, this.props.data); | |
}, | |
_onMouseLeave: function _onMouseLeave( /*object*/event) { | |
this.props.onMouseLeave(event, this.props.index, this.props.data); | |
} | |
}); | |
var FixedDataTableRow = React.createClass({ | |
displayName: 'FixedDataTableRow', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
/** | |
* Height of the row. | |
*/ | |
height: PropTypes.number.isRequired, | |
/** | |
* Z-index on which the row will be displayed. Used e.g. for keeping | |
* header and footer in front of other rows. | |
*/ | |
zIndex: PropTypes.number, | |
/** | |
* The vertical position where the row should render itself | |
*/ | |
offsetTop: PropTypes.number.isRequired, | |
/** | |
* Width of the row. | |
*/ | |
width: PropTypes.number.isRequired | |
}, | |
render: function render() /*object*/{ | |
var style = { | |
width: this.props.width, | |
height: this.props.height, | |
zIndex: this.props.zIndex ? this.props.zIndex : 0 | |
}; | |
translateDOMPositionXY(style, 0, this.props.offsetTop); | |
return React.createElement( | |
'div', | |
{ | |
style: style, | |
className: cx('fixedDataTableRow/rowWrapper') }, | |
React.createElement(FixedDataTableRowImpl, _extends({}, this.props, { | |
offsetTop: undefined, | |
zIndex: undefined | |
})) | |
); | |
} | |
}); | |
module.exports = FixedDataTableRow; | |
/***/ }, | |
/* 67 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableCellGroup.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | |
var FixedDataTableHelper = __webpack_require__(20); | |
var ImmutableObject = __webpack_require__(68); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var FixedDataTableCell = __webpack_require__(74); | |
var cx = __webpack_require__(56); | |
var renderToString = FixedDataTableHelper.renderToString; | |
var translateDOMPositionXY = __webpack_require__(57); | |
var PropTypes = React.PropTypes; | |
var EMPTY_OBJECT = new ImmutableObject({}); | |
var FixedDataTableCellGroupImpl = React.createClass({ | |
displayName: 'FixedDataTableCellGroupImpl', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
/** | |
* Array of <FixedDataTableColumn />. | |
*/ | |
columns: PropTypes.array.isRequired, | |
/** | |
* The row data to render. The data format can be a simple Map object | |
* or an Array of data. | |
*/ | |
data: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), | |
left: PropTypes.number, | |
onColumnResize: PropTypes.func, | |
rowHeight: PropTypes.number.isRequired, | |
rowIndex: PropTypes.number.isRequired, | |
width: PropTypes.number.isRequired, | |
zIndex: PropTypes.number.isRequired | |
}, | |
render: function render() /*object*/{ | |
var props = this.props; | |
var columns = props.columns; | |
var cells = new Array(columns.length); | |
var currentPosition = 0; | |
for (var i = 0, j = columns.length; i < j; i++) { | |
var columnProps = columns[i].props; | |
if (!columnProps.allowCellsRecycling || currentPosition - props.left <= props.width && currentPosition - props.left + columnProps.width >= 0) { | |
var key = 'cell_' + i; | |
cells[i] = this._renderCell(props.data, props.rowIndex, props.rowHeight, columnProps, currentPosition, key); | |
} | |
currentPosition += columnProps.width; | |
} | |
var contentWidth = this._getColumnsWidth(columns); | |
var style = { | |
height: props.height, | |
position: 'absolute', | |
width: contentWidth, | |
zIndex: props.zIndex | |
}; | |
translateDOMPositionXY(style, -1 * props.left, 0); | |
return React.createElement( | |
'div', | |
{ className: cx('fixedDataTableCellGroup/cellGroup'), style: style }, | |
cells | |
); | |
}, | |
_renderCell: function _renderCell( | |
/*object|array*/rowData, | |
/*number*/rowIndex, | |
/*number*/height, | |
/*object*/columnProps, | |
/*number*/left, | |
/*string*/key) /*object*/{ | |
var cellRenderer = columnProps.cellRenderer || renderToString; | |
var columnData = columnProps.columnData || EMPTY_OBJECT; | |
var cellDataKey = columnProps.dataKey; | |
var isFooterCell = columnProps.isFooterCell; | |
var isHeaderCell = columnProps.isHeaderCell; | |
var cellData; | |
if (isHeaderCell || isFooterCell) { | |
cellData = rowData[cellDataKey]; | |
} else { | |
var cellDataGetter = columnProps.cellDataGetter; | |
cellData = cellDataGetter ? cellDataGetter(cellDataKey, rowData) : rowData[cellDataKey]; | |
} | |
var cellIsResizable = columnProps.isResizable && this.props.onColumnResize; | |
var onColumnResize = cellIsResizable ? this.props.onColumnResize : null; | |
return React.createElement(FixedDataTableCell, { | |
align: columnProps.align, | |
cellData: cellData, | |
cellDataKey: cellDataKey, | |
cellRenderer: cellRenderer, | |
className: columnProps.cellClassName, | |
columnData: columnData, | |
height: height, | |
isFooterCell: isFooterCell, | |
isHeaderCell: isHeaderCell, | |
key: key, | |
maxWidth: columnProps.maxWidth, | |
minWidth: columnProps.minWidth, | |
onColumnResize: onColumnResize, | |
rowData: rowData, | |
rowIndex: rowIndex, | |
width: columnProps.width, | |
left: left | |
}); | |
}, | |
_getColumnsWidth: function _getColumnsWidth(columns) { | |
var width = 0; | |
for (var i = 0; i < columns.length; ++i) { | |
width += columns[i].props.width; | |
} | |
return width; | |
} | |
}); | |
var FixedDataTableCellGroup = React.createClass({ | |
displayName: 'FixedDataTableCellGroup', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
/** | |
* Height of the row. | |
*/ | |
height: PropTypes.number.isRequired, | |
offsetLeft: PropTypes.number, | |
/** | |
* Z-index on which the row will be displayed. Used e.g. for keeping | |
* header and footer in front of other rows. | |
*/ | |
zIndex: PropTypes.number.isRequired | |
}, | |
render: function render() /*object*/{ | |
var _props = this.props; | |
var offsetLeft = _props.offsetLeft; | |
var props = _objectWithoutProperties(_props, ['offsetLeft']); | |
var style = { | |
height: props.height | |
}; | |
if (offsetLeft) { | |
translateDOMPositionXY(style, offsetLeft, 0); | |
} | |
var onColumnResize = props.onColumnResize ? this._onColumnResize : null; | |
return React.createElement( | |
'div', | |
{ | |
style: style, | |
className: cx('fixedDataTableCellGroup/cellGroupWrapper') }, | |
React.createElement(FixedDataTableCellGroupImpl, _extends({}, props, { | |
onColumnResize: onColumnResize | |
})) | |
); | |
}, | |
_onColumnResize: function _onColumnResize( | |
/*number*/left, | |
/*number*/width, | |
/*?number*/minWidth, | |
/*?number*/maxWidth, | |
/*string|number*/cellDataKey, | |
/*object*/event) { | |
this.props.onColumnResize && this.props.onColumnResize(this.props.offsetLeft, left - this.props.left + width, width, minWidth, maxWidth, cellDataKey, event); | |
} | |
}); | |
module.exports = FixedDataTableCellGroup; | |
/***/ }, | |
/* 68 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 ImmutableObject | |
* @typechecks | |
*/ | |
'use strict'; | |
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 _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
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) subClass.__proto__ = superClass; } | |
var ImmutableValue = __webpack_require__(69); | |
var invariant = __webpack_require__(61); | |
var keyOf = __webpack_require__(71); | |
var mergeHelpers = __webpack_require__(72); | |
var checkMergeObjectArgs = mergeHelpers.checkMergeObjectArgs; | |
var isTerminal = mergeHelpers.isTerminal; | |
var SECRET_KEY = keyOf({ _DONT_EVER_TYPE_THIS_SECRET_KEY: null }); | |
/** | |
* Static methods creating and operating on instances of `ImmutableValue`. | |
*/ | |
function assertImmutable(immutable) { | |
invariant(immutable instanceof ImmutableValue, 'ImmutableObject: Attempted to set fields on an object that is not an ' + 'instance of ImmutableValue.'); | |
} | |
/** | |
* Static methods for reasoning about instances of `ImmutableObject`. Execute | |
* the freeze commands in `__DEV__` mode to alert the programmer that something | |
* is attempting to mutate. Since freezing is very expensive, we avoid doing it | |
* at all in production. | |
*/ | |
var ImmutableObject = (function (_ImmutableValue) { | |
/** | |
* @arguments {array<object>} The arguments is an array of objects that, when | |
* merged together, will form the immutable objects. | |
*/ | |
function ImmutableObject() { | |
_classCallCheck(this, ImmutableObject); | |
_get(Object.getPrototypeOf(ImmutableObject.prototype), 'constructor', this).call(this, ImmutableValue[SECRET_KEY]); | |
ImmutableValue.mergeAllPropertiesInto(this, arguments); | |
if (true) { | |
ImmutableValue.deepFreezeRootNode(this); | |
} | |
} | |
_inherits(ImmutableObject, _ImmutableValue); | |
_createClass(ImmutableObject, null, [{ | |
key: 'create', | |
/** | |
* DEPRECATED - prefer to instantiate with new ImmutableObject(). | |
* | |
* @arguments {array<object>} The arguments is an array of objects that, when | |
* merged together, will form the immutable objects. | |
*/ | |
value: function create() { | |
var obj = Object.create(ImmutableObject.prototype); | |
ImmutableObject.apply(obj, arguments); | |
return obj; | |
} | |
}, { | |
key: 'set', | |
/** | |
* Returns a new `ImmutableValue` that is identical to the supplied | |
* `ImmutableValue` but with the specified changes, `put`. Any keys that are | |
* in the intersection of `immutable` and `put` retain the ordering of | |
* `immutable`. New keys are placed after keys that exist in `immutable`. | |
* | |
* @param {ImmutableValue} immutable Starting object. | |
* @param {?object} put Fields to merge into the object. | |
* @return {ImmutableValue} The result of merging in `put` fields. | |
*/ | |
value: function set(immutable, put) { | |
assertImmutable(immutable); | |
invariant(typeof put === 'object' && put !== undefined && !Array.isArray(put), 'Invalid ImmutableMap.set argument `put`'); | |
return new ImmutableObject(immutable, put); | |
} | |
}, { | |
key: 'setProperty', | |
/** | |
* Sugar for `ImmutableObject.set(ImmutableObject, {fieldName: putField})`. | |
* Look out for key crushing: Use `keyOf()` to guard against it. | |
* | |
* @param {ImmutableValue} immutableObject Object on which to set properties. | |
* @param {string} fieldName Name of the field to set. | |
* @param {*} putField Value of the field to set. | |
* @return {ImmutableValue} new ImmutableValue as described in `set`. | |
*/ | |
value: function setProperty(immutableObject, fieldName, putField) { | |
var put = {}; | |
put[fieldName] = putField; | |
return ImmutableObject.set(immutableObject, put); | |
} | |
}, { | |
key: 'deleteProperty', | |
/** | |
* Returns a new immutable object with the given field name removed. | |
* Look out for key crushing: Use `keyOf()` to guard against it. | |
* | |
* @param {ImmutableObject} immutableObject from which to delete the key. | |
* @param {string} droppedField Name of the field to delete. | |
* @return {ImmutableObject} new ImmutableObject without the key | |
*/ | |
value: function deleteProperty(immutableObject, droppedField) { | |
var copy = {}; | |
for (var key in immutableObject) { | |
if (key !== droppedField && immutableObject.hasOwnProperty(key)) { | |
copy[key] = immutableObject[key]; | |
} | |
} | |
return new ImmutableObject(copy); | |
} | |
}, { | |
key: 'setDeep', | |
/** | |
* Returns a new `ImmutableValue` that is identical to the supplied object but | |
* with the supplied changes recursively applied. | |
* | |
* Experimental. Likely does not handle `Arrays` correctly. | |
* | |
* @param {ImmutableValue} immutable Object on which to set fields. | |
* @param {object} put Fields to merge into the object. | |
* @return {ImmutableValue} The result of merging in `put` fields. | |
*/ | |
value: function setDeep(immutable, put) { | |
assertImmutable(immutable); | |
return _setDeep(immutable, put); | |
} | |
}, { | |
key: 'values', | |
/** | |
* Retrieves an ImmutableObject's values as an array. | |
* | |
* @param {ImmutableValue} immutable | |
* @return {array} | |
*/ | |
value: function values(immutable) { | |
return Object.keys(immutable).map(function (key) { | |
return immutable[key]; | |
}); | |
} | |
}]); | |
return ImmutableObject; | |
})(ImmutableValue); | |
function _setDeep(obj, put) { | |
checkMergeObjectArgs(obj, put); | |
var totalNewFields = {}; | |
// To maintain the order of the keys, copy the base object's entries first. | |
var keys = Object.keys(obj); | |
for (var ii = 0; ii < keys.length; ii++) { | |
var key = keys[ii]; | |
if (!put.hasOwnProperty(key)) { | |
totalNewFields[key] = obj[key]; | |
} else if (isTerminal(obj[key]) || isTerminal(put[key])) { | |
totalNewFields[key] = put[key]; | |
} else { | |
totalNewFields[key] = _setDeep(obj[key], put[key]); | |
} | |
} | |
// Apply any new keys that the base obj didn't have. | |
var newKeys = Object.keys(put); | |
for (ii = 0; ii < newKeys.length; ii++) { | |
var newKey = newKeys[ii]; | |
if (obj.hasOwnProperty(newKey)) { | |
continue; | |
} | |
totalNewFields[newKey] = put[newKey]; | |
} | |
return obj instanceof ImmutableValue ? new ImmutableObject(totalNewFields) : put instanceof ImmutableValue ? new ImmutableObject(totalNewFields) : totalNewFields; | |
} | |
module.exports = ImmutableObject; | |
/***/ }, | |
/* 69 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | |
/** | |
* Copyright (c) 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 ImmutableValue | |
* @typechecks | |
*/ | |
'use strict'; | |
var invariant = __webpack_require__(61); | |
var isNode = __webpack_require__(70); | |
var keyOf = __webpack_require__(71); | |
var SECRET_KEY = keyOf({ _DONT_EVER_TYPE_THIS_SECRET_KEY: null }); | |
/** | |
* `ImmutableValue` provides a guarantee of immutability at developer time when | |
* strict mode is used. The extra computations required to enforce immutability | |
* are stripped out in production for performance reasons. `ImmutableValue` | |
* guarantees to enforce immutability for enumerable, own properties. This | |
* allows easy wrapping of `ImmutableValue` with the ability to store | |
* non-enumerable properties on the instance that only your static methods | |
* reason about. In order to achieve IE8 compatibility (which doesn't have the | |
* ability to define non-enumerable properties), modules that want to build | |
* their own reasoning of `ImmutableValue`s and store computations can define | |
* their non-enumerable properties under the name `toString`, and in IE8 only | |
* define a standard property called `toString` which will mistakenly be | |
* considered not enumerable due to its name (but only in IE8). The only | |
* limitation is that no one can store their own `toString` property. | |
* https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug | |
*/ | |
var ImmutableValue = (function () { | |
/** | |
* An instance of `ImmutableValue` appears to be a plain JavaScript object, | |
* except `instanceof ImmutableValue` evaluates to `true`, and it is deeply | |
* frozen in development mode. | |
* | |
* @param {number} secret Ensures this isn't accidentally constructed outside | |
* of convenience constructors. If created outside of a convenience | |
* constructor, may not be frozen. Forbidding that use case for now until we | |
* have a better API. | |
*/ | |
function ImmutableValue(secret) { | |
_classCallCheck(this, ImmutableValue); | |
invariant(secret === ImmutableValue[SECRET_KEY], 'Only certain classes should create instances of `ImmutableValue`.' + 'You probably want something like ImmutableValueObject.create.'); | |
} | |
_createClass(ImmutableValue, null, [{ | |
key: 'mergeAllPropertiesInto', | |
/** | |
* Helper method for classes that make use of `ImmutableValue`. | |
* @param {ImmutableValue} destination Object to merge properties into. | |
* @param {object} propertyObjects List of objects to merge into | |
* `destination`. | |
*/ | |
value: function mergeAllPropertiesInto(destination, propertyObjects) { | |
var argLength = propertyObjects.length; | |
for (var i = 0; i < argLength; i++) { | |
_extends(destination, propertyObjects[i]); | |
} | |
} | |
}, { | |
key: 'deepFreezeRootNode', | |
/** | |
* Freezes the supplied object deeply. Other classes may implement their own | |
* version based on this. | |
* | |
* @param {*} object The object to freeze. | |
*/ | |
value: function deepFreezeRootNode(object) { | |
if (isNode(object)) { | |
return; // Don't try to freeze DOM nodes. | |
} | |
Object.freeze(object); // First freeze the object. | |
for (var prop in object) { | |
if (object.hasOwnProperty(prop)) { | |
ImmutableValue.recurseDeepFreeze(object[prop]); | |
} | |
} | |
Object.seal(object); | |
} | |
}, { | |
key: 'recurseDeepFreeze', | |
/** | |
* Differs from `deepFreezeRootNode`, in that we first check if this is a | |
* necessary recursion. If the object is already an `ImmutableValue`, then the | |
* recursion is unnecessary as it is already frozen. That check obviously | |
* wouldn't work for the root node version `deepFreezeRootNode`! | |
*/ | |
value: function recurseDeepFreeze(object) { | |
if (isNode(object) || !ImmutableValue.shouldRecurseFreeze(object)) { | |
return; // Don't try to freeze DOM nodes. | |
} | |
Object.freeze(object); // First freeze the object. | |
for (var prop in object) { | |
if (object.hasOwnProperty(prop)) { | |
ImmutableValue.recurseDeepFreeze(object[prop]); | |
} | |
} | |
Object.seal(object); | |
} | |
}, { | |
key: 'shouldRecurseFreeze', | |
/** | |
* Checks if an object should be deep frozen. Instances of `ImmutableValue` | |
* are assumed to have already been deep frozen, so we can have large | |
* `__DEV__` time savings by skipping freezing of them. | |
* | |
* @param {*} object The object to check. | |
* @return {boolean} Whether or not deep freeze is needed. | |
*/ | |
value: function shouldRecurseFreeze(object) { | |
return typeof object === 'object' && !(object instanceof ImmutableValue) && object !== null; | |
} | |
}]); | |
return ImmutableValue; | |
})(); | |
ImmutableValue._DONT_EVER_TYPE_THIS_SECRET_KEY = Math.random(); | |
module.exports = ImmutableValue; | |
/***/ }, | |
/* 70 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule isNode | |
* @typechecks | |
*/ | |
/** | |
* @param {*} object The object to check. | |
* @return {boolean} Whether or not the object is a DOM node. | |
*/ | |
'use strict'; | |
function isNode(object) { | |
return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); | |
} | |
module.exports = isNode; | |
/***/ }, | |
/* 71 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule keyOf | |
*/ | |
/** | |
* Allows extraction of a minified key. Let's the build system minify keys | |
* without losing the ability to dynamically use key strings as values | |
* themselves. Pass in an object with a single key/val pair and it will return | |
* you the string key of that single record. Suppose you want to grab the | |
* value for a key 'className' inside of an object. Key/val minification may | |
* have aliased that key to be 'xa12'. keyOf({className: null}) will return | |
* 'xa12' in that case. Resolve keys you want to use once at startup time, then | |
* reuse those resolutions. | |
*/ | |
"use strict"; | |
var keyOf = function keyOf(oneKeyObj) { | |
var key; | |
for (key in oneKeyObj) { | |
if (!oneKeyObj.hasOwnProperty(key)) { | |
continue; | |
} | |
return key; | |
} | |
return null; | |
}; | |
module.exports = keyOf; | |
/***/ }, | |
/* 72 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 mergeHelpers | |
* | |
* requiresPolyfills: Array.isArray | |
*/ | |
'use strict'; | |
var invariant = __webpack_require__(61); | |
var keyMirror = __webpack_require__(73); | |
/** | |
* Maximum number of levels to traverse. Will catch circular structures. | |
* @const | |
*/ | |
var MAX_MERGE_DEPTH = 36; | |
/** | |
* We won't worry about edge cases like new String('x') or new Boolean(true). | |
* Functions and Dates are considered terminals, and arrays are not. | |
* @param {*} o The item/object/value to test. | |
* @return {boolean} true iff the argument is a terminal. | |
*/ | |
var isTerminal = function isTerminal(o) { | |
return typeof o !== 'object' || o instanceof Date || o === null; | |
}; | |
var mergeHelpers = { | |
MAX_MERGE_DEPTH: MAX_MERGE_DEPTH, | |
isTerminal: isTerminal, | |
/** | |
* Converts null/undefined values into empty object. | |
* | |
* @param {?Object=} arg Argument to be normalized (nullable optional) | |
* @return {!Object} | |
*/ | |
normalizeMergeArg: function normalizeMergeArg(arg) { | |
return arg === undefined || arg === null ? {} : arg; | |
}, | |
/** | |
* If merging Arrays, a merge strategy *must* be supplied. If not, it is | |
* likely the caller's fault. If this function is ever called with anything | |
* but `one` and `two` being `Array`s, it is the fault of the merge utilities. | |
* | |
* @param {*} one Array to merge into. | |
* @param {*} two Array to merge from. | |
*/ | |
checkMergeArrayArgs: function checkMergeArrayArgs(one, two) { | |
invariant(Array.isArray(one) && Array.isArray(two), 'Tried to merge arrays, instead got %s and %s.', one, two); | |
}, | |
/** | |
* @param {*} one Object to merge into. | |
* @param {*} two Object to merge from. | |
*/ | |
checkMergeObjectArgs: function checkMergeObjectArgs(one, two) { | |
mergeHelpers.checkMergeObjectArg(one); | |
mergeHelpers.checkMergeObjectArg(two); | |
}, | |
/** | |
* @param {*} arg | |
*/ | |
checkMergeObjectArg: function checkMergeObjectArg(arg) { | |
invariant(!isTerminal(arg) && !Array.isArray(arg), 'Tried to merge an object, instead got %s.', arg); | |
}, | |
/** | |
* @param {*} arg | |
*/ | |
checkMergeIntoObjectArg: function checkMergeIntoObjectArg(arg) { | |
invariant((!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg), 'Tried to merge into an object, instead got %s.', arg); | |
}, | |
/** | |
* Checks that a merge was not given a circular object or an object that had | |
* too great of depth. | |
* | |
* @param {number} Level of recursion to validate against maximum. | |
*/ | |
checkMergeLevel: function checkMergeLevel(level) { | |
invariant(level < MAX_MERGE_DEPTH, 'Maximum deep merge depth exceeded. You may be attempting to merge ' + 'circular structures in an unsupported way.'); | |
}, | |
/** | |
* Checks that the supplied merge strategy is valid. | |
* | |
* @param {string} Array merge strategy. | |
*/ | |
checkArrayStrategy: function checkArrayStrategy(strategy) { | |
invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies, 'You must provide an array strategy to deep merge functions to ' + 'instruct the deep merge how to resolve merging two arrays.'); | |
}, | |
/** | |
* Set of possible behaviors of merge algorithms when encountering two Arrays | |
* that must be merged together. | |
* - `clobber`: The left `Array` is ignored. | |
* - `indexByIndex`: The result is achieved by recursively deep merging at | |
* each index. (not yet supported.) | |
*/ | |
ArrayStrategies: keyMirror({ | |
Clobber: true, | |
IndexByIndex: true | |
}) | |
}; | |
module.exports = mergeHelpers; | |
/***/ }, | |
/* 73 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule keyMirror | |
* @typechecks static-only | |
*/ | |
'use strict'; | |
var invariant = __webpack_require__(61); | |
/** | |
* Constructs an enumeration with keys equal to their value. | |
* | |
* For example: | |
* | |
* var COLORS = keyMirror({blue: null, red: null}); | |
* var myColor = COLORS.blue; | |
* var isColorValid = !!COLORS[myColor]; | |
* | |
* The last line could not be performed if the values of the generated enum were | |
* not equal to their keys. | |
* | |
* Input: {key1: val1, key2: val2} | |
* Output: {key1: key1, key2: key2} | |
* | |
* @param {object} obj | |
* @return {object} | |
*/ | |
var keyMirror = function keyMirror(obj) { | |
var ret = {}; | |
var key; | |
invariant(obj instanceof Object && !Array.isArray(obj), 'keyMirror(...): Argument must be an object.'); | |
for (key in obj) { | |
if (!obj.hasOwnProperty(key)) { | |
continue; | |
} | |
ret[key] = key; | |
} | |
return ret; | |
}; | |
module.exports = keyMirror; | |
/***/ }, | |
/* 74 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableCell.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var ImmutableObject = __webpack_require__(68); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var cloneWithProps = __webpack_require__(26); | |
var cx = __webpack_require__(56); | |
var joinClasses = __webpack_require__(75); | |
var PropTypes = React.PropTypes; | |
var DEFAULT_PROPS = new ImmutableObject({ | |
align: 'left', | |
highlighted: false, | |
isFooterCell: false, | |
isHeaderCell: false | |
}); | |
var FixedDataTableCell = React.createClass({ | |
displayName: 'FixedDataTableCell', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
align: PropTypes.oneOf(['left', 'center', 'right']), | |
className: PropTypes.string, | |
highlighted: PropTypes.bool, | |
isFooterCell: PropTypes.bool, | |
isHeaderCell: PropTypes.bool, | |
width: PropTypes.number.isRequired, | |
minWidth: PropTypes.number, | |
maxWidth: PropTypes.number, | |
height: PropTypes.number.isRequired, | |
/** | |
* The cell data that will be passed to `cellRenderer` to render. | |
*/ | |
cellData: PropTypes.any, | |
/** | |
* The key to retrieve the cell data from the `rowData`. | |
*/ | |
cellDataKey: PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.number.isRequired]), | |
/** | |
* The function to render the `cellData`. | |
*/ | |
cellRenderer: PropTypes.func.isRequired, | |
/** | |
* The column data that will be passed to `cellRenderer` to render. | |
*/ | |
columnData: PropTypes.any, | |
/** | |
* The row data that will be passed to `cellRenderer` to render. | |
*/ | |
rowData: PropTypes.oneOfType([PropTypes.object.isRequired, PropTypes.array.isRequired]), | |
/** | |
* The row index that will be passed to `cellRenderer` to render. | |
*/ | |
rowIndex: PropTypes.number.isRequired, | |
/** | |
* Callback for when resizer knob (in FixedDataTableCell) is clicked | |
* to initialize resizing. Please note this is only on the cells | |
* in the header. | |
* @param number combinedWidth | |
* @param number left | |
* @param number width | |
* @param number minWidth | |
* @param number maxWidth | |
* @param number|string columnKey | |
* @param object event | |
*/ | |
onColumnResize: PropTypes.func, | |
/** | |
* The left offset in pixels of the cell. | |
*/ | |
left: PropTypes.number | |
}, | |
getDefaultProps: function getDefaultProps() /*object*/{ | |
return DEFAULT_PROPS; | |
}, | |
render: function render() /*object*/{ | |
var props = this.props; | |
var style = { | |
height: props.height, | |
left: props.left, | |
width: props.width | |
}; | |
var className = joinClasses(cx({ | |
'public/fixedDataTableCell/main': true, | |
'public/fixedDataTableCell/highlighted': props.highlighted, | |
'public/fixedDataTableCell/lastChild': props.lastChild, | |
'public/fixedDataTableCell/alignRight': props.align === 'right', | |
'public/fixedDataTableCell/alignCenter': props.align === 'center' | |
}), props.isHeaderCell || props.isFooterCell ? '' : props.className); | |
var content; | |
if (props.isHeaderCell || props.isFooterCell) { | |
content = props.cellRenderer(props.cellData, props.cellDataKey, props.columnData, props.rowData, props.width); | |
} else { | |
content = props.cellRenderer(props.cellData, props.cellDataKey, props.rowData, props.rowIndex, props.columnData, props.width); | |
} | |
var contentClass = cx('public/fixedDataTableCell/cellContent'); | |
if (React.isValidElement(content)) { | |
content = cloneWithProps(content, { | |
key: content.key, | |
className: contentClass | |
}); | |
} else { | |
content = React.createElement( | |
'div', | |
{ className: contentClass }, | |
content | |
); | |
} | |
var columnResizerComponent; | |
if (props.onColumnResize) { | |
var columnResizerStyle = { | |
height: props.height | |
}; | |
columnResizerComponent = React.createElement( | |
'div', | |
{ | |
className: cx('fixedDataTableCell/columnResizerContainer'), | |
style: columnResizerStyle, | |
onMouseDown: this._onColumnResizerMouseDown }, | |
React.createElement('div', { | |
className: cx('fixedDataTableCell/columnResizerKnob'), | |
style: columnResizerStyle | |
}) | |
); | |
} | |
var innerStyle = { | |
height: props.height, | |
width: props.width | |
}; | |
return React.createElement( | |
'div', | |
{ className: className, style: style }, | |
columnResizerComponent, | |
React.createElement( | |
'div', | |
{ | |
className: cx('public/fixedDataTableCell/wrap1'), | |
style: innerStyle }, | |
React.createElement( | |
'div', | |
{ className: cx('public/fixedDataTableCell/wrap2') }, | |
React.createElement( | |
'div', | |
{ className: cx('public/fixedDataTableCell/wrap3') }, | |
content | |
) | |
) | |
) | |
); | |
}, | |
_onColumnResizerMouseDown: function _onColumnResizerMouseDown( /*object*/event) { | |
this.props.onColumnResize(this.props.left, this.props.width, this.props.minWidth, this.props.maxWidth, this.props.cellDataKey, event); | |
} | |
}); | |
module.exports = FixedDataTableCell; | |
/***/ }, | |
/* 75 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule joinClasses | |
* @typechecks static-only | |
*/ | |
'use strict'; | |
/** | |
* Combines multiple className strings into one. | |
* http://jsperf.com/joinclasses-args-vs-array | |
* | |
* @param {...?string} classes | |
* @return {string} | |
*/ | |
function joinClasses(className /*, ... */) { | |
if (!className) { | |
className = ''; | |
} | |
var nextClass; | |
var argLength = arguments.length; | |
if (argLength > 1) { | |
for (var ii = 1; ii < argLength; ii++) { | |
nextClass = arguments[ii]; | |
if (nextClass) { | |
className = (className ? className + ' ' : '') + nextClass; | |
} | |
} | |
} | |
return className; | |
} | |
module.exports = joinClasses; | |
/***/ }, | |
/* 76 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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. | |
* | |
* This is to be used with the FixedDataTable. It is a read line | |
* that when you click on a column that is resizable appears and allows | |
* you to resize the corresponding column. | |
* | |
* @providesModule FixedDataTableColumnResizeHandle.react | |
* @typechecks | |
*/ | |
'use strict'; | |
var DOMMouseMoveTracker = __webpack_require__(51); | |
var Locale = __webpack_require__(21); | |
var React = __webpack_require__(22); | |
var ReactComponentWithPureRenderMixin = __webpack_require__(39); | |
var clamp = __webpack_require__(19); | |
var cx = __webpack_require__(56); | |
var PropTypes = React.PropTypes; | |
var FixedDataTableColumnResizeHandle = React.createClass({ | |
displayName: 'FixedDataTableColumnResizeHandle', | |
mixins: [ReactComponentWithPureRenderMixin], | |
propTypes: { | |
visible: PropTypes.bool.isRequired, | |
/** | |
* This is the height of the line | |
*/ | |
height: PropTypes.number.isRequired, | |
/** | |
* Offset from left border of the table, please note | |
* that the line is a border on diff. So this is really the | |
* offset of the column itself. | |
*/ | |
leftOffset: PropTypes.number.isRequired, | |
/** | |
* Height of the clickable region of the line. | |
* This is assumed to be at the top of the line. | |
*/ | |
knobHeight: PropTypes.number.isRequired, | |
/** | |
* The line is a border on a diff, so this is essentially | |
* the width of column. | |
*/ | |
initialWidth: PropTypes.number, | |
/** | |
* The minimum width this dragger will collapse to | |
*/ | |
minWidth: PropTypes.number, | |
/** | |
* The maximum width this dragger will collapse to | |
*/ | |
maxWidth: PropTypes.number, | |
/** | |
* Initial click event on the header cell. | |
*/ | |
initialEvent: PropTypes.object, | |
/** | |
* When resizing is complete this is called. | |
*/ | |
onColumnResizeEnd: PropTypes.func, | |
/** | |
* Column key for the column being resized. | |
*/ | |
columnKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) | |
}, | |
getInitialState: function getInitialState() /*object*/{ | |
return { | |
width: 0, | |
cursorDelta: 0 | |
}; | |
}, | |
componentWillReceiveProps: function componentWillReceiveProps( /*object*/newProps) { | |
if (newProps.initialEvent && !this._mouseMoveTracker.isDragging()) { | |
this._mouseMoveTracker.captureMouseMoves(newProps.initialEvent); | |
this.setState({ | |
width: newProps.initialWidth, | |
cursorDelta: newProps.initialWidth | |
}); | |
} | |
}, | |
componentDidMount: function componentDidMount() { | |
this._mouseMoveTracker = new DOMMouseMoveTracker(this._onMove, this._onColumnResizeEnd, document.body); | |
}, | |
componentWillUnmount: function componentWillUnmount() { | |
this._mouseMoveTracker.releaseMouseMoves(); | |
this._mouseMoveTracker = null; | |
}, | |
render: function render() /*object*/{ | |
var style = { | |
width: this.state.width, | |
height: this.props.height | |
}; | |
if (Locale.isRTL()) { | |
style.right = this.props.leftOffset; | |
} else { | |
style.left = this.props.leftOffset; | |
} | |
return React.createElement( | |
'div', | |
{ | |
className: cx({ | |
'fixedDataTableColumnResizerLine/main': true, | |
'fixedDataTableColumnResizerLine/hiddenElem': !this.props.visible | |
}), | |
style: style }, | |
React.createElement('div', { | |
className: cx('fixedDataTableColumnResizerLine/mouseArea'), | |
style: { height: this.props.height } | |
}) | |
); | |
}, | |
_onMove: function _onMove( /*number*/deltaX) { | |
if (Locale.isRTL()) { | |
deltaX = -deltaX; | |
} | |
var newWidth = this.state.cursorDelta + deltaX; | |
var newColumnWidth = clamp(this.props.minWidth, newWidth, this.props.maxWidth); | |
// Please note cursor delta is the different between the currently width | |
// and the new width. | |
this.setState({ | |
width: newColumnWidth, | |
cursorDelta: newWidth | |
}); | |
}, | |
_onColumnResizeEnd: function _onColumnResizeEnd() { | |
this._mouseMoveTracker.releaseMouseMoves(); | |
this.props.onColumnResizeEnd(this.state.width, this.props.columnKey); | |
} | |
}); | |
module.exports = FixedDataTableColumnResizeHandle; | |
/***/ }, | |
/* 77 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 FixedDataTableWidthHelper | |
* @typechecks | |
*/ | |
'use strict'; | |
var React = __webpack_require__(22); | |
var cloneWithProps = __webpack_require__(26); | |
function getTotalWidth( /*array*/columns) /*number*/{ | |
var totalWidth = 0; | |
for (var i = 0; i < columns.length; ++i) { | |
totalWidth += columns[i].props.width; | |
} | |
return totalWidth; | |
} | |
function getTotalFlexGrow( /*array*/columns) /*number*/{ | |
var totalFlexGrow = 0; | |
for (var i = 0; i < columns.length; ++i) { | |
totalFlexGrow += columns[i].props.flexGrow || 0; | |
} | |
return totalFlexGrow; | |
} | |
function distributeFlexWidth( | |
/*array*/columns, | |
/*number*/flexWidth) /*object*/{ | |
if (flexWidth <= 0) { | |
return { | |
columns: columns, | |
width: getTotalWidth(columns) | |
}; | |
} | |
var remainingFlexGrow = getTotalFlexGrow(columns); | |
var remainingFlexWidth = flexWidth; | |
var newColumns = []; | |
var totalWidth = 0; | |
for (var i = 0; i < columns.length; ++i) { | |
var column = columns[i]; | |
if (!column.props.flexGrow) { | |
totalWidth += column.props.width; | |
newColumns.push(column); | |
continue; | |
} | |
var columnFlexWidth = Math.floor(column.props.flexGrow / remainingFlexGrow * remainingFlexWidth); | |
var newColumnWidth = Math.floor(column.props.width + columnFlexWidth); | |
totalWidth += newColumnWidth; | |
remainingFlexGrow -= column.props.flexGrow; | |
remainingFlexWidth -= columnFlexWidth; | |
newColumns.push(cloneWithProps(column, { width: newColumnWidth })); | |
} | |
return { | |
columns: newColumns, | |
width: totalWidth | |
}; | |
} | |
function adjustColumnGroupWidths( | |
/*array*/columnGroups, | |
/*number*/expectedWidth) /*object*/{ | |
var allColumns = []; | |
var i; | |
for (i = 0; i < columnGroups.length; ++i) { | |
React.Children.forEach(columnGroups[i].props.children, function (column) { | |
allColumns.push(column); | |
}); | |
} | |
var columnsWidth = getTotalWidth(allColumns); | |
var remainingFlexGrow = getTotalFlexGrow(allColumns); | |
var remainingFlexWidth = Math.max(expectedWidth - columnsWidth, 0); | |
var newAllColumns = []; | |
var newColumnGroups = []; | |
for (i = 0; i < columnGroups.length; ++i) { | |
var columnGroup = columnGroups[i]; | |
var currentColumns = []; | |
React.Children.forEach(columnGroup.props.children, function (column) { | |
currentColumns.push(column); | |
}); | |
var columnGroupFlexGrow = getTotalFlexGrow(currentColumns); | |
var columnGroupFlexWidth = Math.floor(columnGroupFlexGrow / remainingFlexGrow * remainingFlexWidth); | |
var newColumnSettings = distributeFlexWidth(currentColumns, columnGroupFlexWidth); | |
remainingFlexGrow -= columnGroupFlexGrow; | |
remainingFlexWidth -= columnGroupFlexWidth; | |
for (var j = 0; j < newColumnSettings.columns.length; ++j) { | |
newAllColumns.push(newColumnSettings.columns[j]); | |
} | |
newColumnGroups.push(cloneWithProps(columnGroup, { width: newColumnSettings.width })); | |
} | |
return { | |
columns: newAllColumns, | |
columnGroups: newColumnGroups | |
}; | |
} | |
function adjustColumnWidths( | |
/*array*/columns, | |
/*number*/expectedWidth) /*array*/{ | |
var columnsWidth = getTotalWidth(columns); | |
if (columnsWidth < expectedWidth) { | |
return distributeFlexWidth(columns, expectedWidth - columnsWidth).columns; | |
} | |
return columns; | |
} | |
var FixedDataTableWidthHelper = { | |
getTotalWidth: getTotalWidth, | |
getTotalFlexGrow: getTotalFlexGrow, | |
distributeFlexWidth: distributeFlexWidth, | |
adjustColumnWidths: adjustColumnWidths, | |
adjustColumnGroupWidths: adjustColumnGroupWidths | |
}; | |
module.exports = FixedDataTableWidthHelper; | |
/***/ }, | |
/* 78 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 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 debounceCore | |
* @typechecks | |
*/ | |
/** | |
* Invokes the given callback after a specified number of milliseconds have | |
* elapsed, ignoring subsequent calls. | |
* | |
* For example, if you wanted to update a preview after the user stops typing | |
* you could do the following: | |
* | |
* elem.addEventListener('keyup', debounce(this.updatePreview, 250), false); | |
* | |
* The returned function has a reset method which can be called to cancel a | |
* pending invocation. | |
* | |
* var debouncedUpdatePreview = debounce(this.updatePreview, 250); | |
* elem.addEventListener('keyup', debouncedUpdatePreview, false); | |
* | |
* // later, to cancel pending calls | |
* debouncedUpdatePreview.reset(); | |
* | |
* @param {function} func - the function to debounce | |
* @param {number} wait - how long to wait in milliseconds | |
* @param {*} context - optional context to invoke the function in | |
* @param {?function} setTimeoutFunc - an implementation of setTimeout | |
* if nothing is passed in the default setTimeout function is used | |
* @param {?function} clearTimeoutFunc - an implementation of clearTimeout | |
* if nothing is passed in the default clearTimeout function is used | |
*/ | |
"use strict"; | |
function debounce(func, wait, context, setTimeoutFunc, clearTimeoutFunc) { | |
setTimeoutFunc = setTimeoutFunc || setTimeout; | |
clearTimeoutFunc = clearTimeoutFunc || clearTimeout; | |
var timeout; | |
function debouncer() { | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
debouncer.reset(); | |
var callback = function callback() { | |
func.apply(context, args); | |
}; | |
callback.__SMmeta = func.__SMmeta; | |
timeout = setTimeoutFunc(callback, wait); | |
} | |
debouncer.reset = function () { | |
clearTimeoutFunc(timeout); | |
}; | |
return debouncer; | |
} | |
module.exports = debounce; | |
/***/ }, | |
/* 79 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Copyright (c) 2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule shallowEqual | |
*/ | |
'use strict'; | |
/** | |
* Performs equality by iterating through keys on an object and returning | |
* false when any key has values which are not strictly equal between | |
* objA and objB. Returns true when the values of all keys are strictly equal. | |
* | |
* @return {boolean} | |
*/ | |
function shallowEqual(objA, objB) { | |
if (objA === objB) { | |
return true; | |
} | |
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { | |
return false; | |
} | |
var keysA = Object.keys(objA); | |
var keysB = Object.keys(objB); | |
if (keysA.length !== keysB.length) { | |
return false; | |
} | |
// Test for A's keys different from B. | |
var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB); | |
for (var i = 0; i < keysA.length; i++) { | |
if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { | |
return false; | |
} | |
} | |
return true; | |
} | |
module.exports = shallowEqual; | |
/***/ } | |
/******/ ]) | |
}); | |
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Fixed Data Table</title> | |
<link rel="stylesheet" type="text/css" href="https://rawgit.com/facebook/fixed-data-table/v0.3.0/dist/fixed-data-table.css"> | |
</head> | |
<body> | |
<style type="text/css"> | |
.red-color { | |
color: red; | |
} | |
</style> | |
<div id="content"></div> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react-with-addons.js"></script> | |
<script type="text/javascript" src="fixed-data-table.js"></script> | |
<script type="text/javascript" src="main.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var CustomTable = React.createClass({ | |
render: function() { | |
var Table = FixedDataTable.Table; | |
var Column = FixedDataTable.Column; | |
var ColumnGroup = FixedDataTable.ColumnGroup; | |
var data = []; | |
for (var i = 0; i < 1000; i++) { | |
data.push({ | |
column: 'value ' + i | |
}); | |
} | |
return React.createElement(Table, { | |
rowHeight: 50, | |
rowGetter: function(index) { | |
return data[index]; | |
}, | |
width: 600, | |
height: 300, | |
rowsCount: data.length, | |
headerHeight: 50, | |
groupHeaderHeight: 50 | |
}, [ | |
React.createElement( | |
ColumnGroup, { | |
label: 'Group' | |
},[ | |
React.createElement(Column, { | |
label: 'Value', | |
width: 600, | |
dataKey: 'column', | |
cellClassName: 'red-color' | |
}) | |
] | |
) | |
]); | |
} | |
}); | |
React.render( | |
React.createElement(CustomTable), | |
document.getElementById('content') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Edwin, I work on a project that is using an older version of the UserAgent_DEPRECATED script. Do you have a link to the original source of that?