/**
|
* Asynchronous every that allows asynchronous function as its predicate.
|
*
|
* @param array An array of items
|
* @param predicate Asynchronous function to determine if each of the items in the provided array satisfies the criteria
|
* @example
|
* let testArr: number[] = [10, 20, 3, 40];
|
* let isBigEnough = await asyncEvery(testArr, async (num: number) => {
|
* let threshold = await this.getThresholdNo();
|
* return num >= threshold;
|
* });
|
* // if threshold is 10, isBigEnough is false because 3 is not >= 10.
|
* // if threshold is 3, isBigEnough is true.
|
*/
|
export const asyncEvery = async <T>(array: T[], predicate: (value: T) => Promise<boolean>): Promise<boolean> => {
|
for (const item of array) {
|
if (!(await predicate(item))) {
|
return false;
|
}
|
}
|
return true;
|
};
|
|
/**
|
* Similar to `Array.prototype.filter`, but this supports async actions.
|
*
|
* @param array An array of items to be filtered
|
* @param callback Asynchronous function to perform filtering
|
* @returns `T[]` a newly filtered array.
|
*/
|
export const asyncFilter = async <T>(array: T[], callback: (value: T, index: number, array: T[]) => Promise<boolean>): Promise<T[]> => {
|
const filterMap = await asyncMap(array, callback);
|
return array.filter((_: T, index: number) => filterMap[index]);
|
};
|
|
/**
|
* Similar to `Array.prototype.map`, but this supports async actions.
|
*
|
* @template T Type of the item for the array to be mapped from.
|
* @template U Type of the item for the mapped array.
|
* @param array An array of items to be mapped from.
|
* @param callback Asynchronous function to perform an array mapping
|
* @returns `U[]` A new mapped array.
|
* @example
|
* const array = [1, 5, 7, 10];
|
* // example to simulate getting some items from online list based on the collection of ids above.
|
* const mappedArr = await asyncMap(array, async (id: number) => {
|
* const listItems = await this.getItemsFromList(id);
|
* return listItems;
|
* })
|
*/
|
export const asyncMap = async <T, U>(array: T[], callback: (value: T, index: number, array: T[]) => Promise<U>): Promise<U[]> => Promise.all(array.map(callback));
|
|
/**
|
* Find all the HTML elements by HTML tag name from a HTML string
|
*
|
* @param htmlString Target HTML string to retrieve HTML elements
|
* @param tagName Target tag name to find
|
* @example this.findHtmlElementByTag(tooltip, 'tr');
|
*
|
* @return All the html elements found
|
*/
|
export const findHtmlElementByTag = (htmlString: string, tagName: string): string[] | null => {
|
const htmlElregex = new RegExp(`<${tagName}.*?>(.*?)<\/${tagName}>`, 'g');
|
const htmlElements = htmlString.match(htmlElregex);
|
|
return htmlElements;
|
};
|
|
/**
|
* Obtains key entries from a given enumerator.
|
*
|
* @param e `EnumLike`: EnumLike object / enumerator.
|
* @returns `string[]`: which consists of key entries.
|
* @example
|
* enum Example {
|
* A,
|
* B,
|
* C = 'ccc',
|
* D = 1,
|
* }
|
*
|
* getEnumKeyEntries(Example); // returns ['A', 'B', 'C', 'D']
|
*/
|
export const getEnumKeyEntries: (e: EnumLike) => string[] = (e: EnumLike): string[] => Object.keys(e).filter((key: string) => isNaN(Number(key)));
|
|
/**
|
* Obtains value entries from a given enumerator.
|
*
|
* @param e `EnumLike`: EnumLike object / enumerator.
|
* @returns `(string | number)[]`: array which contains string and/or number, which are thee value entries.
|
* @example
|
* enum Example {
|
* A,
|
* B,
|
* C = 'ccc',
|
* D = 1,
|
* }
|
*
|
* getEnumValueEntries(Example); // returns ['AAA', 'BBB', 'ccc', 1]
|
*
|
* @summary As per example, if a key is assigned a number value, this method will also returns it.
|
*
|
* Please filter it yourself to obtain pure string array. :)
|
*/
|
export const getEnumValueEntries: (e: EnumLike) => (string | number)[] = (e: EnumLike): (string | number)[] =>
|
getEnumKeyEntries(e).map((key: string) => e[key]) as (string | number)[];
|
|
/**
|
* Get all string element by removing all tag element in HTML string
|
*
|
* @param htmlString Target HTML string to retrieve only string element
|
* @returns Array of string
|
*/
|
export const getHtmlContent = (htmlString: string): string[] => {
|
const plaintText = htmlString.replace(/((\s+<|<)[^>]+>)|&[^;]+;/g, '~');
|
const split = plaintText.split('~');
|
const result = split.filter((el: string) => el !== '');
|
return result;
|
};
|
|
/**
|
* Convert pass-in HTML table formatted tooltip to a Map object with title map to value
|
*
|
* @param htmlTableFormattedTooltip Target GC Node tooltip which it html table formatted to be convert into Map object
|
*/
|
export const getValuePairsFromHtmlTable = (htmlTableFormattedTooltip: string): Map<string, string> => {
|
const titleValuePairs: Map<string, string> = new Map();
|
const trElements = findHtmlElementByTag(htmlTableFormattedTooltip, 'tr');
|
if (trElements) {
|
for (const trElement of trElements) {
|
const trContents = getHtmlContent(trElement);
|
let valueIndex: number;
|
|
if (trContents.length > 0) {
|
let indexOfSeperator = trContents.indexOf(':');
|
if (indexOfSeperator === -1) {
|
const seperator = trContents.filter((trContent: string) => trContent.includes(':'))[0];
|
indexOfSeperator = trContents.indexOf(seperator) + 1;
|
valueIndex = indexOfSeperator;
|
} else {
|
valueIndex = indexOfSeperator + 1;
|
}
|
const title = trContents.slice(0, indexOfSeperator).join('').trim().replace(':', '');
|
const value = trContents.slice(valueIndex).join('').trim();
|
titleValuePairs.set(title, value);
|
}
|
}
|
}
|
return titleValuePairs;
|
};
|
|
/**
|
* Get key-value pairs from a HTML table formatted tooltip
|
*
|
* @param tooltip Target GC Node tooltip with HTML table formatted
|
*/
|
export const getTooltipValuePairs = (tooltip: string): Map<string, string> => {
|
const trElements = findHtmlElementByTag(tooltip, 'tr');
|
const keyValuePairs: Map<string, string> = new Map();
|
if (trElements) {
|
for (const trElement of trElements) {
|
const rowContents = getHtmlContent(trElement);
|
if (rowContents.length > 0) {
|
const title = rowContents[0].replace(':', '');
|
const value = rowContents.length === 2 ? rowContents[1] : '';
|
keyValuePairs.set(title, value);
|
}
|
}
|
}
|
return keyValuePairs;
|
};
|
|
export const lowercaseFirstLetter = (value: string): string => value.charAt(0).toLowerCase() + value.slice(1);
|
|
export enum ActionTriggerType {
|
Button,
|
ContextMenu,
|
Key,
|
}
|
|
/**
|
* EnumLike interface that emulates an enumerator.
|
*/
|
export interface EnumLike {
|
[key: number]: string | number;
|
}
|