@blueprintjs/core
Version:
Core styles & components
143 lines (142 loc) • 4.96 kB
JavaScript
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the terms of the LICENSE file distributed with this project.
*/
import { CLAMP_MIN_MAX } from "./errors";
export * from "./utils/compareUtils";
/** Returns whether `process.env.NODE_ENV` exists and equals `env`. */
export function isNodeEnv(env) {
return typeof process !== "undefined" && process.env && process.env.NODE_ENV === env;
}
/** Returns whether the value is a function. Acts as a type guard. */
// tslint:disable-next-line:ban-types
export function isFunction(value) {
return typeof value === "function";
}
// tslint:disable-next-line:ban-types
export function safeInvoke(func) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (isFunction(func)) {
return func.apply(void 0, args);
}
}
// tslint:disable-next-line:ban-types
export function safeInvokeOrValue(funcOrValue) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return isFunction(funcOrValue) ? funcOrValue.apply(void 0, args) : funcOrValue;
}
export function elementIsOrContains(element, testElement) {
return element === testElement || element.contains(testElement);
}
/**
* Returns the difference in length between two arrays. A `null` argument is
* considered an empty list. The return value will be positive if `a` is longer
* than `b`, negative if the opposite is true, and zero if their lengths are
* equal.
*/
export function arrayLengthCompare(a, b) {
if (a === void 0) { a = []; }
if (b === void 0) { b = []; }
return a.length - b.length;
}
/**
* Returns true if the two numbers are within the given tolerance of each other.
* This is useful to correct for floating point precision issues, less useful
* for integers.
*/
export function approxEqual(a, b, tolerance) {
if (tolerance === void 0) { tolerance = 0.00001; }
return Math.abs(a - b) <= tolerance;
}
/**
* Clamps the given number between min and max values. Returns value if within
* range, or closest bound.
*/
export function clamp(val, min, max) {
if (val == null) {
return val;
}
if (max < min) {
throw new Error(CLAMP_MIN_MAX);
}
return Math.min(Math.max(val, min), max);
}
/** Returns the number of decimal places in the given number. */
export function countDecimalPlaces(num) {
if (typeof num !== "number" || Math.floor(num) === num) {
return 0;
}
return num.toString().split(".")[1].length;
}
/**
* Throttle an event on an EventTarget by wrapping it in a
* `requestAnimationFrame` call. Returns the event handler that was bound to
* given eventName so you can clean up after yourself.
* @see https://developer.mozilla.org/en-US/docs/Web/Events/scroll
*/
export function throttleEvent(target, eventName, newEventName) {
var throttledFunc = _throttleHelper(undefined, undefined, function (event) {
target.dispatchEvent(new CustomEvent(newEventName, event));
});
target.addEventListener(eventName, throttledFunc);
return throttledFunc;
}
/**
* Throttle a callback by wrapping it in a `requestAnimationFrame` call. Returns
* the throttled function.
* @see https://www.html5rocks.com/en/tutorials/speed/animations/
*/
export function throttleReactEventCallback(callback, options) {
if (options === void 0) { options = {}; }
var throttledFunc = _throttleHelper(function (event2) {
if (options.preventDefault) {
event2.preventDefault();
}
}, function (event2) {
// prevent React from reclaiming the event object before we
// reference it
event2.persist();
}, function (event2) {
var otherArgs2 = [];
for (var _i = 1; _i < arguments.length; _i++) {
otherArgs2[_i - 1] = arguments[_i];
}
callback.apply(void 0, [event2].concat(otherArgs2));
});
return throttledFunc;
}
function _throttleHelper(onBeforeIsRunningCheck, onAfterIsRunningCheck, onAnimationFrameRequested) {
var isRunning = false;
var func = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// don't use safeInvoke, because we might have more than its max number
// of typed params
if (isFunction(onBeforeIsRunningCheck)) {
onBeforeIsRunningCheck.apply(void 0, args);
}
if (isRunning) {
return;
}
isRunning = true;
if (isFunction(onAfterIsRunningCheck)) {
onAfterIsRunningCheck.apply(void 0, args);
}
requestAnimationFrame(function () {
if (isFunction(onAnimationFrameRequested)) {
onAnimationFrameRequested.apply(void 0, args);
}
isRunning = false;
});
};
return func;
}