react-flexbox-layout
Version:
Simple flexible layouts for IE9+
130 lines (98 loc) • 3.98 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.register = register;
exports.deregister = deregister;
exports.update = update;
exports.updateOnWindowResize = updateOnWindowResize;
exports.requestNextLayoutMinDelay = requestNextLayoutMinDelay;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _lodashIncludes = require('lodash/includes');
var _lodashIncludes2 = _interopRequireDefault(_lodashIncludes);
var _lodashDebounce = require('lodash/debounce');
var _lodashDebounce2 = _interopRequireDefault(_lodashDebounce);
var _lodashInvokeMap = require('lodash/invokeMap');
var _lodashInvokeMap2 = _interopRequireDefault(_lodashInvokeMap);
/**
* UpdateEngineIE9
*
* Singleton that handles updating *LayoutIE9 components outside of the React's update flow
*/
// array of mounted *LayoutiE9 components
// invariant: parent Layout components will have lower index than child Layout components
var components = [];
/**
* register registers a Layout component with the UpdateEngine
* @param {LayoutComponent} component
*/
function register(component) {
if (!(0, _lodashIncludes2['default'])(components, component)) {
components.push(component);
}
}
/**
* deregister removes a Layout component from the UpdateEngine
* @param {LayoutComponent} component
*/
function deregister(component) {
var i = components.indexOf(component);
if (i !== -1) {
components.splice(i, 1);
}
}
/**
* update synchronously updates all registered Layout components
*/
function update() {
// first unset all styles, since existing styles will mess with measurements
(0, _lodashInvokeMap2['default'])(components, '_unsetLayoutStyles');
// NOTE: batch measurements and style application as much as possible to prevent excessive reflows
// apply widths first because heights are dependent on widths (e.g., text wrap), but not the other way around
(0, _lodashInvokeMap2['default'])(components, '_measureInheritedStyles');
(0, _lodashInvokeMap2['default'])(components, '_measureWidths');
(0, _lodashInvokeMap2['default'])(components, '_applyInheritedStyles');
(0, _lodashInvokeMap2['default'])(components, '_applyWidths');
// apply heights now that widths have been set
(0, _lodashInvokeMap2['default'])(components, '_measureItemHeights');
(0, _lodashInvokeMap2['default'])(components, '_applyFlexHeights');
// NOTE: each container must be set sequentially instead of batched because child Layout heights can depend on
// parent Layout heights (e.g., child is vertical flexGrow on parent). In-order traversal of array works because of the
// invariant described above: parent Layout components will have lower index than child Layout components.
(0, _lodashInvokeMap2['default'])(components, '_setContainerHeights');
(0, _lodashInvokeMap2['default'])(components, '_callDidLayout');
}
/**
* requestAsyncUpdate guarantees that `update` will be run sometime in the future
*/
var requestAsyncUpdate = (0, _lodashDebounce2['default'])(updateAfterDelay, 0);
exports.requestAsyncUpdate = requestAsyncUpdate;
function updateOnWindowResize() {
window.addEventListener('resize', (0, _lodashDebounce2['default'])(requestAsyncUpdate, 16));
}
var nextDelay = 0;
/**
* Request that the next re-layout be at least @delay ms from now.
* @param {Number} delay
*/
function requestNextLayoutMinDelay(delay) {
nextDelay = Math.max(nextDelay, delay);
}
var delayedUpdate, delayedUpdateTime;
function updateAfterDelay() {
if (nextDelay === 0 && !delayedUpdate) {
update();
return;
}
var potentialUpdateTime = Date.now() + nextDelay;
if (!delayedUpdate || potentialUpdateTime > delayedUpdateTime) {
clearTimeout(delayedUpdate);
delayedUpdateTime = potentialUpdateTime;
delayedUpdate = setTimeout(performDelayedUpdate, nextDelay);
}
nextDelay = 0;
}
function performDelayedUpdate() {
delayedUpdate = null;
update();
}