mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 13:32:54 +08:00
173 lines
4.7 KiB
TypeScript
173 lines
4.7 KiB
TypeScript
|
|
/**
|
|
* Given a min and max, restrict the given number
|
|
* to the range.
|
|
* @param min the minimum
|
|
* @param n the value
|
|
* @param max the maximum
|
|
*/
|
|
export function clamp(min: number, n: number, max: number) {
|
|
return Math.max(min, Math.min(n, max));
|
|
}
|
|
|
|
/**
|
|
* The assign() method is used to copy the values of all enumerable own
|
|
* properties from one or more source objects to a target object. It will
|
|
* return the target object. When available, this method will use
|
|
* `Object.assign()` under-the-hood.
|
|
* @param target The target object
|
|
* @param source(s) The source object
|
|
*/
|
|
export function assign(...args: any[]): any {
|
|
if (typeof Object.assign !== 'function') {
|
|
// use the old-school shallow extend method
|
|
return _baseExtend(args[0], [].slice.call(args, 1), false);
|
|
}
|
|
|
|
// use the built in ES6 Object.assign method
|
|
return Object.assign.apply(null, args);
|
|
}
|
|
|
|
/**
|
|
* Do a deep extend (merge).
|
|
* @param dst the destination
|
|
* @param ... the param objects
|
|
*/
|
|
export function merge(dst: any, ...args: any[]) {
|
|
return _baseExtend(dst, [].slice.call(arguments, 1), true);
|
|
}
|
|
|
|
function _baseExtend(dst: any, objs: any, deep: boolean) {
|
|
for (var i = 0, ii = objs.length; i < ii; ++i) {
|
|
var obj = objs[i];
|
|
if (!obj || !isObject(obj) && !isFunction(obj)) continue;
|
|
var keys = Object.keys(obj);
|
|
for (var j = 0, jj = keys.length; j < jj; j++) {
|
|
var key = keys[j];
|
|
var src = obj[key];
|
|
|
|
if (deep && isObject(src)) {
|
|
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
|
|
_baseExtend(dst[key], [src], true);
|
|
} else {
|
|
dst[key] = src;
|
|
}
|
|
}
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
export function debounce(fn: Function, wait: number, immediate: boolean = false): any {
|
|
var timeout: number, args: any, context: any, timestamp: number, result: any;
|
|
return function() {
|
|
context = this;
|
|
args = arguments;
|
|
timestamp = Date.now();
|
|
var later: any = function() {
|
|
var last: any = Date.now() - timestamp;
|
|
if (last < wait) {
|
|
timeout = setTimeout(later, wait - last);
|
|
} else {
|
|
timeout = null;
|
|
if (!immediate) result = fn.apply(context, args);
|
|
}
|
|
};
|
|
var callNow = immediate && !timeout;
|
|
if (!timeout) {
|
|
timeout = setTimeout(later, wait);
|
|
}
|
|
if (callNow) result = fn.apply(context, args);
|
|
return result;
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
* Apply default arguments if they don't exist in
|
|
* the first object.
|
|
* @param the destination to apply defaults to.
|
|
*/
|
|
export function defaults(dest: any, ...args: any[]) {
|
|
for (var i = arguments.length - 1; i >= 1; i--) {
|
|
var source = arguments[i];
|
|
if (source) {
|
|
for (var key in source) {
|
|
if (source.hasOwnProperty(key) && !dest.hasOwnProperty(key)) {
|
|
dest[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
export const isBoolean = (val: any) => typeof val === 'boolean';
|
|
export const isString = (val: any) => typeof val === 'string';
|
|
export const isNumber = (val: any) => typeof val === 'number';
|
|
export const isFunction = (val: any) => typeof val === 'function';
|
|
export const isDefined = (val: any) => typeof val !== 'undefined';
|
|
export const isUndefined = (val: any) => typeof val === 'undefined';
|
|
export const isPresent = (val: any) => val !== undefined && val !== null;
|
|
export const isBlank = (val: any) => val === undefined || val === null;
|
|
export const isObject = (val: any) => typeof val === 'object';
|
|
export const isArray = Array.isArray;
|
|
|
|
export const isPrimitive = function(val: any) {
|
|
return isString(val) || isBoolean(val) || (isNumber(val) && !isNaN(val));
|
|
};
|
|
|
|
export const isTrueProperty = function(val: any): boolean {
|
|
if (typeof val === 'string') {
|
|
val = val.toLowerCase().trim();
|
|
return (val === 'true' || val === 'on' || val === '');
|
|
}
|
|
return !!val;
|
|
};
|
|
|
|
export const isCheckedProperty = function(a: any, b: any): boolean {
|
|
if (a === undefined || a === null || a === '') {
|
|
return (b === undefined || b === null || b === '');
|
|
|
|
} else if (a === true || a === 'true') {
|
|
return (b === true || b === 'true');
|
|
|
|
} else if (a === false || a === 'false') {
|
|
return (b === false || b === 'false');
|
|
|
|
} else if (a === 0 || a === '0') {
|
|
return (b === 0 || b === '0');
|
|
}
|
|
|
|
// not using strict comparison on purpose
|
|
/* tslint:disable */
|
|
return (a == b);
|
|
/* tslint:enable */
|
|
};
|
|
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
export function reorderArray(array: any[], indexes: {from: number, to: number}): any[] {
|
|
let element = array[indexes.from];
|
|
array.splice(indexes.from, 1);
|
|
array.splice(indexes.to, 0, element);
|
|
return array;
|
|
}
|
|
|
|
|
|
const ASSERT_ENABLED = true;
|
|
/**
|
|
* @private
|
|
*/
|
|
function _assert(actual: any, reason?: string) {
|
|
if (!actual && ASSERT_ENABLED === true) {
|
|
let message = 'IONIC ASSERT: ' + reason;
|
|
console.error(message);
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
export { _assert as assert};
|