# all files / src/js/base/core/ func.js

94.83% Statements 55/58
64.29% Branches 9/14
95.65% Functions 22/23
94.83% Lines 55/58

    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174

    1×
    386×
    663×

    1×
    2×

    1×
    10×
    2×

    1×
    2306×

    1×
    258×

    1×
    35×
    231×

    1×
    5×
    12×

    1×
    3×

    1×
    578×
    2×

    1×

    1×
    3×
    3×

    1×

    1×
    98×
    98×
    2628×
    2628×

    98×

    1×
    200×
    200×
    267×

    1×
    99×
    99×
    22×
    22×
    22×
    19×
    19×
    19×

    22×
    22×
    22×
    22×

    1×
    4×
    4×

    1×

     /**
     * @class core.func
     *
     * func utils (for high-order func's arg)
     *
     * @singleton
     * @alternateClassName func
     */
    function eq(itemA) {
      return function(itemB) {
        return itemA === itemB;
      };
    }

    function eq2(itemA, itemB) {
      return itemA === itemB;
    }

    function peq2(propName) {
      return function(itemA, itemB) {
        return itemA[propName] === itemB[propName];
      };
    }

    function ok() {
      return true;
    }

    function fail() {
      return false;
    }

    function not(f) {
      return function() {
        return !f.apply(f, arguments);
      };
    }

    function and(fA, fB) {
      return function(item) {
        return fA(item) && fB(item);
      };
    }

    function self(a) {
      return a;
    }

    function invoke(obj, method) {
      return function() {
        return obj[method].apply(obj, arguments);
      };
    }

    let idCounter = 0;

    /**
     * generate a globally-unique id
     *
     * @param {String} [prefix]
     */
    function uniqueId(prefix) {
      const id = ++idCounter + '';
      return prefix ? prefix + id : id;
    }

    /**
     * returns bnd (bounds) from rect
     *
     * - IE Compatibility Issue: http://goo.gl/sRLOAo
     * - Scroll Issue: http://goo.gl/sNjUc
     *
     * @param {Rect} rect
     * @return {Object} bounds
     * @return {Number} bounds.top
     * @return {Number} bounds.left
     * @return {Number} bounds.width
     * @return {Number} bounds.height
     */
    function rect2bnd(rect) {
      const $document = $(document);
      return {
        top: rect.top + $document.scrollTop(),
        left: rect.left + $document.scrollLeft(),
        width: rect.right - rect.left,
        height: rect.bottom - rect.top,
      };
    }

    /**
     * returns a copy of the object where the keys have become the values and the values the keys.
     * @param {Object} obj
     * @return {Object}
     */
    function invertObject(obj) {
      const inverted = {};
      for (const key in obj) {
        Eif (obj.hasOwnProperty(key)) {
          inverted[obj[key]] = key;
        }
      }
      return inverted;
    }

    /**
     * @param {String} namespace
     * @param {String} [prefix]
     * @return {String}
     */
    function namespaceToCamel(namespace, prefix) {
      prefix = prefix || '';
      return prefix + namespace.split('.').map(function(name) {
        return name.substring(0, 1).toUpperCase() + name.substring(1);
      }).join('');
    }

    /**
     * Returns a function, that, as long as it continues to be invoked, will not
     * be triggered. The function will be called after it stops being called for
     * N milliseconds. If `immediate` is passed, trigger the function on the
     * leading edge, instead of the trailing.
     * @param {Function} func
     * @param {Number} wait
     * @param {Boolean} immediate
     * @return {Function}
     */
    function debounce(func, wait, immediate) {
      let timeout;
      return function() {
        const context = this;
        const args = arguments;
        const later = () => {
          timeout = null;
          Eif (!immediate) {
            func.apply(context, args);
          }
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        Iif (callNow) {
          func.apply(context, args);
        }
      };
    }

    /**
     *
     * @param {String} url
     * @return {Boolean}
     */
    function isValidUrl(url) {
      const expression = /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/gi;
      return expression.test(url);
    }

    export default {
      eq,
      eq2,
      peq2,
      ok,
      fail,
      self,
      not,
      and,
      invoke,
      uniqueId,
      rect2bnd,
      invertObject,
      namespaceToCamel,
      debounce,
      isValidUrl,
    };