All files / src/core/compatibility vendors.ts

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

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      20x 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) => str.charAt(0).toUpperCase() + str.slice(1);
const getDummyStyle: () => CSSStyleDeclaration = () => 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 = `${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;
};