All files / src/core/compatibility vendors.ts

100% Statements 50/50
100% Branches 14/14
100% Functions 10/10
100% Lines 49/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100      1x 20x   1x 10x         1x 1x   1x 1x           1x 4x   4x 1x   3x 3x   3x 9x 9x           33x 9x     3x 3x                 1x 11x 11x   11x 4x   7x 7x 7x 7x   7x 10x 42x 42x 42x 2x 2x     10x     7x 7x             1x 5x   5x 1x   4x 11x 11x     4x 4x    
import { each } from 'core/utils';
import { createDiv } from 'core/dom';
 
const firstLetterToUpper: (str: string) => string = (str) => {
    return str.charAt(0).toUpperCase() + str.slice(1);
}
const getDummyStyle: () => CSSStyleDeclaration = () => {
    return createDiv().style;
}
 
//https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix
 
export const cssPrefixes: ReadonlyArray<string> = ['-webkit-', '-moz-', '-o-', '-ms-'];
export const jsPrefixes: ReadonlyArray<string> = ['WebKit', 'Moz', 'O', 'MS', 'webkit', 'moz', 'o', 'ms'];
 
export const jsCache: { [key: string]: any } = {};
export const cssCache: { [key: string]: string } = {};
 
/**
 * Gets the name of the given CSS property with vendor prefix if it isn't supported without, or undefined if unsupported.
 * @param name The name of the CSS property which shall be get.
 */
export const cssProperty: (name: string) => string | undefined = (name) => {
    let result: string | undefined = cssCache[name];
 
    if (cssCache.hasOwnProperty(name))
        return result;
 
    const uppercasedName: string = firstLetterToUpper(name);
    const elmStyle: CSSStyleDeclaration = getDummyStyle();
 
    each(cssPrefixes, (prefix: string) => {
        const prefixWithoutDashes: string = prefix.replace(/-/g, '');
        const resultPossibilities: Array<string> = [
            name, //transition
            prefix + name, //-webkit-transition
            prefixWithoutDashes + uppercasedName, //webkitTransition
            firstLetterToUpper(prefixWithoutDashes) + uppercasedName //WebkitTransition
        ];
        result = resultPossibilities.find((resultPossibility: string) => elmStyle[resultPossibility] !== undefined);
        return !result;
    });
 
    cssCache[name] = result;
    return result;
}
 
/**
 * Get the name of the given CSS property value(s), with vendor prefix if it isn't supported wuthout, or undefined if no value is supported. 
 * @param property The CSS property to which the CSS property value(s) belong.
 * @param values The value(s) separated by spaces which shall be get.
 * @param suffix A suffix which is added to each value in case the value is a function or something else more advanced.
 */
export const cssPropertyValue: (property: string, values: string, suffix?: string) => string | undefined = (property, values, suffix) => {
    const name: string = property + ' ' + values;
    let result: string | undefined = cssCache[name];
 
    if (cssCache.hasOwnProperty(name))
        return result;
 
    const dummyStyle: CSSStyleDeclaration = getDummyStyle();
    const possbleValues: Array<string> = values.split(' ');
    const preparedSuffix: string = suffix || '';
    const cssPrefixesWithFirstEmpty = [''].concat(cssPrefixes);
 
    each(possbleValues, (possibleValue: string) => {
        each(cssPrefixesWithFirstEmpty, (prefix: string) => {
            const prop = prefix + possibleValue;
            dummyStyle.cssText = property + ':' + prop + preparedSuffix;
            if (dummyStyle.length) {
                result = prop;
                return false;
            }
        });
        return !result;
    });
 
    cssCache[name] = result;
    return result;
}
 
/**
 * Get the requested JS function, object or constructor with vendor prefix if it isn't supported without or undefined if unsupported.
 * @param name The name of the JS function, object or constructor.
 */
export const jsAPI: (name: string) => any = (name) => {
    let result: any = jsCache[name] || window[name];
 
    if (jsCache.hasOwnProperty(name))
        return result;
 
    each(jsPrefixes, (prefix: string) => {
        result = result || window[prefix + firstLetterToUpper(name)];
        return !result;
    });
 
    jsCache[name] = result;
    return result;
}