Last active
October 24, 2020 10:38
-
-
Save bonniss/f9e6af9032f820398148aaaadd17457b to your computer and use it in GitHub Desktop.
Useful snippets in Javascript for up and running project. @link: https://github.com/bootstrap-vue/bootstrap-vue/tree/dev/src/utils
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
// @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/array.js | |
const from = (...args) => Array.from(...args) | |
const isArray = val => Array.isArray(val) | |
const arrayIncludes = (array, value) => array.indexOf(value) !== -1 | |
const concat = (...args) => Array.prototype.concat.apply([], args) | |
export const createAndFillArray = (size, value) => Array(size).fill(value) |
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
/** | |
* Utilities to get information about the current environment | |
*/ | |
// --- Constants --- | |
export const hasWindowSupport = typeof window !== 'undefined' | |
export const hasDocumentSupport = typeof document !== 'undefined' | |
export const hasNavigatorSupport = typeof navigator !== 'undefined' | |
export const hasPromiseSupport = typeof Promise !== 'undefined' | |
/* istanbul ignore next: JSDOM always returns false */ | |
export const hasMutationObserverSupport = | |
typeof MutationObserver !== 'undefined' || | |
typeof WebKitMutationObserver !== 'undefined' || | |
typeof MozMutationObserver !== 'undefined' | |
export const isBrowser = hasWindowSupport && hasDocumentSupport && hasNavigatorSupport | |
// Browser type sniffing | |
export const userAgent = isBrowser ? window.navigator.userAgent.toLowerCase() : '' | |
export const isJSDOM = userAgent.indexOf('jsdom') > 0 | |
export const isIE = /msie|trident/.test(userAgent) | |
// Determine if the browser supports the option passive for events | |
export const hasPassiveEventSupport = (() => { | |
let passiveEventSupported = false | |
if (isBrowser) { | |
try { | |
const options = { | |
get passive() { | |
// This function will be called when the browser | |
// attempts to access the passive property. | |
/* istanbul ignore next: will never be called in JSDOM */ | |
passiveEventSupported = true | |
} | |
} | |
window.addEventListener('test', options, options) | |
window.removeEventListener('test', options, options) | |
} catch (err) { | |
/* istanbul ignore next: will never be called in JSDOM */ | |
passiveEventSupported = false | |
} | |
} | |
return passiveEventSupported | |
})() | |
export const hasTouchSupport = | |
isBrowser && ('ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0) | |
export const hasPointerEventSupport = | |
isBrowser && Boolean(window.PointerEvent || window.MSPointerEvent) | |
/* istanbul ignore next: JSDOM only checks for 'IntersectionObserver' */ | |
export const hasIntersectionObserverSupport = | |
isBrowser && | |
'IntersectionObserver' in window && | |
'IntersectionObserverEntry' in window && | |
// Edge 15 and UC Browser lack support for `isIntersecting` | |
// but we an use intersectionRatio > 0 instead | |
// 'isIntersecting' in window.IntersectionObserverEntry.prototype && | |
'intersectionRatio' in window.IntersectionObserverEntry.prototype | |
// --- Getters --- | |
export const getEnv = (key, fallback = null) => { | |
const env = typeof process !== 'undefined' && process ? process.env || {} : {} | |
if (!key) { | |
/* istanbul ignore next */ | |
return env | |
} | |
return env[key] || fallback | |
} |
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
import identity from './identity' | |
import { isArray, isNull, isObject, isUndefinedOrNull } from './inspect' | |
const RX_ARRAY_NOTATION = /\[(\d+)]/g | |
/** | |
* Get property defined by dot/array notation in string, returns undefined if not found | |
* | |
* @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 | |
* | |
* @param {Object} obj | |
* @param {string|Array} path | |
* @return {*} | |
*/ | |
export const getRaw = (obj, path, defaultValue = undefined) => { | |
// Handle array of path values | |
path = isArray(path) ? path.join('.') : path | |
// If no path or no object passed | |
if (!path || !isObject(obj)) { | |
return defaultValue | |
} | |
// Handle edge case where user has dot(s) in top-level item field key | |
// See https://github.com/bootstrap-vue/bootstrap-vue/issues/2762 | |
// Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters | |
// https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 | |
if (path in obj) { | |
return obj[path] | |
} | |
// Handle string array notation (numeric indices only) | |
path = String(path).replace(RX_ARRAY_NOTATION, '.$1') | |
const steps = path.split('.').filter(identity) | |
// Handle case where someone passes a string of only dots | |
if (steps.length === 0) { | |
return defaultValue | |
} | |
// Traverse path in object to find result | |
// Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters | |
// https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 | |
return steps.every(step => isObject(obj) && step in obj && !isUndefinedOrNull((obj = obj[step]))) | |
? obj | |
: isNull(obj) | |
? null | |
: defaultValue | |
} | |
/** | |
* Get property defined by dot/array notation in string. | |
* | |
* @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 | |
* | |
* @param {Object} obj | |
* @param {string|Array} path | |
* @param {*} defaultValue (optional) | |
* @return {*} | |
*/ | |
export const get = (obj, path, defaultValue = null) => { | |
const val = getRaw(obj, path) | |
return isUndefinedOrNull(val) ? defaultValue : val | |
} | |
export default get |
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
/* @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/html.js */ | |
const RX_HTML_TAGS = /(<([^>]+)>)/gi | |
// Removes anything that looks like an HTML tag from the supplied string | |
export const stripTags = (text = '') => String(text).replace(RX_HTML_TAGS, '') |
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
/* https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/math.js */ | |
export const mathMin = Math.min | |
export const mathMax = Math.max | |
export const mathAbs = Math.abs | |
export const mathCeil = Math.ceil | |
export const mathFloor = Math.floor | |
export const mathPow = Math.pow | |
export const mathRound = Math.round |
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
const noop = () => {} | |
export default noop |
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
/* @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/number.js */ | |
// Converts a value (string, number, etc) to an integer number | |
// Assumes radix base 10 | |
export const toInteger = (value, defaultValue = NaN) => { | |
const integer = parseInt(value, 10) | |
return isNaN(integer) ? defaultValue : integer | |
} | |
// Converts a value (string, number, etc) to a number | |
export const toFloat = (value, defaultValue = NaN) => { | |
const float = parseFloat(value) | |
return isNaN(float) ? defaultValue : float | |
} | |
// Converts a value (string, number, etc) to a string | |
// representation with `precision` digits after the decimal | |
// Returns the string 'NaN' if the value cannot be converted | |
export const toFixed = (val, precision) => toFloat(val).toFixed(toInteger(precision, 0)) |
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
// @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/object.js | |
const isObject = obj => obj !== null && typeof obj === 'object' | |
const isPlainObject = obj => Object.prototype.toString.call(obj) === '[object Object]' | |
const keys = obj => Object.keys(obj) | |
const toString = obj => Object.prototype.toString.call(obj) | |
/** | |
* Return a shallow copy of object with the specified properties only | |
* @link https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc | |
*/ | |
export const pick = (obj, props) => | |
keys(obj) | |
.filter(key => props.indexOf(key) !== -1) | |
.reduce((result, key) => ({ ...result, [key]: obj[key] }), {}) | |
/** | |
* Return a shallow copy of object with the specified properties omitted | |
* @link https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc | |
*/ | |
export const omit = (obj, props) => | |
keys(obj) | |
.filter(key => props.indexOf(key) === -1) | |
.reduce((result, key) => ({ ...result, [key]: obj[key] }), {}) | |
/** | |
* Shallow copy an object. If the passed in object | |
* is null or undefined, returns an empty object | |
*/ | |
export const clone = obj => ({ ...obj }) |
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
const RX_URL = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; |
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
/* | |
* Consistent and stable sort function across JavaScript platforms | |
* | |
* Inconsistent sorts can cause SSR problems between client and server | |
* such as in <b-table> if sortBy is applied to the data on server side render. | |
* Chrome and V8 native sorts are inconsistent/unstable | |
* | |
* This function uses native sort with fallback to index compare when the a and b | |
* compare returns 0 | |
* | |
* Algorithm based on: | |
* https://stackoverflow.com/questions/1427608/fast-stable-sorting-algorithm-implementation-in-javascript/45422645#45422645 | |
* | |
* @param {array} array to sort | |
* @param {function} sort compare function | |
* @return {array} | |
*/ | |
const stableSort = (array, compareFn) => { | |
// Using `.bind(compareFn)` on the wrapped anonymous function improves | |
// performance by avoiding the function call setup. We don't use an arrow | |
// function here as it binds `this` to the `stableSort` context rather than | |
// the `compareFn` context, which wouldn't give us the performance increase. | |
return array | |
.map((a, index) => [index, a]) | |
.sort( | |
function(a, b) { | |
return this(a[1], b[1]) || a[0] - b[0] | |
}.bind(compareFn) | |
) | |
.map(e => e[1]) | |
} |
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
/* @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/string.js */ | |
// String utilities | |
import { isArray, isPlainObject, isString, isUndefinedOrNull } from './inspect' | |
// --- Constants --- | |
const RX_TRIM_LEFT = /^\s+/ | |
const RX_TRIM_RIGHT = /\s+$/ | |
const RX_REGEXP_REPLACE = /[-/\\^$*+?.()|[\]{}]/g | |
const RX_UN_KEBAB = /-(\w)/g | |
const RX_HYPHENATE = /\B([A-Z])/g | |
// --- Utilities --- | |
// Converts PascalCase or camelCase to kebab-case | |
export const kebabCase = str => { | |
return str.replace(RX_HYPHENATE, '-$1').toLowerCase() | |
} | |
// Converts a kebab-case or camelCase string to PascalCase | |
export const pascalCase = str => { | |
str = kebabCase(str).replace(RX_UN_KEBAB, (_, c) => (c ? c.toUpperCase() : '')) | |
return str.charAt(0).toUpperCase() + str.slice(1) | |
} | |
// Lowercases the first letter of a string and returns a new string | |
export const lowerFirst = str => { | |
str = isString(str) ? str.trim() : String(str) | |
return str.charAt(0).toLowerCase() + str.slice(1) | |
} | |
// Uppercases the first letter of a string and returns a new string | |
export const upperFirst = str => { | |
str = isString(str) ? str.trim() : String(str) | |
return str.charAt(0).toUpperCase() + str.slice(1) | |
} | |
// Escape characters to be used in building a regular expression | |
export const escapeRegExp = str => str.replace(RX_REGEXP_REPLACE, '\\$&') | |
// Convert a value to a string that can be rendered | |
// `undefined`/`null` will be converted to `''` | |
// Plain objects and arrays will be JSON stringified | |
export const toString = (val, spaces = 2) => { | |
return isUndefinedOrNull(val) | |
? '' | |
: isArray(val) || (isPlainObject(val) && val.toString === Object.prototype.toString) | |
? JSON.stringify(val, null, spaces) | |
: String(val) | |
} | |
// Remove leading white space from a string | |
export const trimLeft = str => toString(str).replace(RX_TRIM_LEFT, '') | |
// Remove Trailing white space from a string | |
export const trimRight = str => toString(str).replace(RX_TRIM_RIGHT, '') | |
// Remove leading and trailing white space from a string | |
export const trim = str => toString(str).trim() | |
// Lower case a string | |
export const lowerCase = str => toString(str).toLowerCase() | |
// Upper case a string | |
export const upperCase = str => toString(str).toUpperCase() |
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
/* @link: https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/utils/inspect.js */ | |
import { isArray } from './array' | |
import { isObject, isPlainObject } from './object' | |
import { File } from './safe-types' | |
// --- Convenience inspection utilities --- | |
export const toType = val => typeof val | |
export const toRawType = val => Object.prototype.toString.call(val).slice(8, -1) | |
export const toRawTypeLC = val => toRawType(val).toLowerCase() | |
export const isUndefined = val => val === undefined | |
export const isNull = val => val === null | |
export const isEmptyString = val => val === '' | |
export const isUndefinedOrNull = val => isUndefined(val) || isNull(val) | |
export const isUndefinedOrNullOrEmpty = val => isUndefinedOrNull(val) || isEmptyString(val) | |
export const isFunction = val => toType(val) === 'function' | |
export const isBoolean = val => toType(val) === 'boolean' | |
export const isString = val => toType(val) === 'string' | |
export const isNumber = val => toType(val) === 'number' | |
export const isPrimitive = val => isBoolean(val) || isString(val) || isNumber(val) | |
export const isDate = val => val instanceof Date | |
export const isEvent = val => val instanceof Event | |
export const isFile = val => val instanceof File | |
export const isRegExp = val => toRawType(val) === 'RegExp' | |
export const isPromise = val => | |
!isUndefinedOrNull(val) && isFunction(val.then) && isFunction(val.catch) | |
// Extra convenience named re-exports | |
export { isArray, isObject, isPlainObject } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment