dedupe.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*!
  2. Copyright (c) 2018 Jed Watson.
  3. Licensed under the MIT License (MIT), see
  4. http://jedwatson.github.io/classnames
  5. */
  6. /* global define */
  7. (function () {
  8. 'use strict';
  9. var classNames = (function () {
  10. // don't inherit from Object so we can skip hasOwnProperty check later
  11. // http://stackoverflow.com/questions/15518328/creating-js-object-with-object-createnull#answer-21079232
  12. function StorageObject() {}
  13. StorageObject.prototype = Object.create(null);
  14. function _parseArray (resultSet, array) {
  15. var length = array.length;
  16. for (var i = 0; i < length; ++i) {
  17. _parse(resultSet, array[i]);
  18. }
  19. }
  20. var hasOwn = {}.hasOwnProperty;
  21. function _parseNumber (resultSet, num) {
  22. resultSet[num] = true;
  23. }
  24. function _parseObject (resultSet, object) {
  25. if (object.toString !== Object.prototype.toString && !object.toString.toString().includes('[native code]')) {
  26. resultSet[object.toString()] = true;
  27. return;
  28. }
  29. for (var k in object) {
  30. if (hasOwn.call(object, k)) {
  31. // set value to false instead of deleting it to avoid changing object structure
  32. // https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#de-referencing-misconceptions
  33. resultSet[k] = !!object[k];
  34. }
  35. }
  36. }
  37. var SPACE = /\s+/;
  38. function _parseString (resultSet, str) {
  39. var array = str.split(SPACE);
  40. var length = array.length;
  41. for (var i = 0; i < length; ++i) {
  42. resultSet[array[i]] = true;
  43. }
  44. }
  45. function _parse (resultSet, arg) {
  46. if (!arg) return;
  47. var argType = typeof arg;
  48. // 'foo bar'
  49. if (argType === 'string') {
  50. _parseString(resultSet, arg);
  51. // ['foo', 'bar', ...]
  52. } else if (Array.isArray(arg)) {
  53. _parseArray(resultSet, arg);
  54. // { 'foo': true, ... }
  55. } else if (argType === 'object') {
  56. _parseObject(resultSet, arg);
  57. // '130'
  58. } else if (argType === 'number') {
  59. _parseNumber(resultSet, arg);
  60. }
  61. }
  62. function _classNames () {
  63. // don't leak arguments
  64. // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
  65. var len = arguments.length;
  66. var args = Array(len);
  67. for (var i = 0; i < len; i++) {
  68. args[i] = arguments[i];
  69. }
  70. var classSet = new StorageObject();
  71. _parseArray(classSet, args);
  72. var list = [];
  73. for (var k in classSet) {
  74. if (classSet[k]) {
  75. list.push(k)
  76. }
  77. }
  78. return list.join(' ');
  79. }
  80. return _classNames;
  81. })();
  82. if (typeof module !== 'undefined' && module.exports) {
  83. classNames.default = classNames;
  84. module.exports = classNames;
  85. } else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
  86. // register as 'classnames', consistent with npm package name
  87. define('classnames', [], function () {
  88. return classNames;
  89. });
  90. } else {
  91. window.classNames = classNames;
  92. }
  93. }());