clone-ast.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use strict';
  2. var isArray = require('core-js/library/fn/array/is-array');
  3. var objectKeys = require('core-js/library/fn/object/keys');
  4. var indexOf = require('core-js/library/fn/array/index-of');
  5. var Map = require('core-js/library/fn/map');
  6. var reduce = require('core-js/library/fn/array/reduce');
  7. module.exports = function cloneWithWhitelist (astWhiteList) {
  8. var whitelist = reduce(objectKeys(astWhiteList), function (props, key) {
  9. var propNames = astWhiteList[key];
  10. var prepend = (indexOf(propNames, 'type') === -1) ? ['type'] : [];
  11. props[key] = prepend.concat(propNames || []);
  12. return props;
  13. }, {});
  14. function cloneNodeOrObject (obj, seen) {
  15. var props = obj.type ? whitelist[obj.type] : null;
  16. if (props) {
  17. return cloneNode(obj, props, seen);
  18. } else {
  19. return cloneObject(obj, seen);
  20. }
  21. }
  22. function cloneArray (ary, seen) {
  23. var i = ary.length;
  24. var clone = [];
  25. while (i--) {
  26. clone[i] = cloneOf(ary[i], seen);
  27. }
  28. return clone;
  29. }
  30. function cloneNode (node, props, seen) {
  31. var i, len, key;
  32. var clone = {};
  33. for (i = 0, len = props.length; i < len; i += 1) {
  34. key = props[i];
  35. if (node.hasOwnProperty(key)) {
  36. clone[key] = cloneOf(node[key], seen);
  37. }
  38. }
  39. return clone;
  40. }
  41. function cloneObject (obj, seen) {
  42. var props = objectKeys(obj);
  43. var i, len, key, value;
  44. var clone = {};
  45. for (i = 0, len = props.length; i < len; i += 1) {
  46. key = props[i];
  47. value = obj[key];
  48. if (seen.has(value)) {
  49. continue;
  50. }
  51. clone[key] = cloneOf(value, seen);
  52. }
  53. return clone;
  54. }
  55. function cloneOf (val, seen) {
  56. if (typeof val === 'object' && val !== null) {
  57. seen.set(val, true);
  58. if (val instanceof RegExp) {
  59. return new RegExp(val);
  60. } else if (isArray(val)) {
  61. return cloneArray(val, seen);
  62. } else {
  63. return cloneNodeOrObject(val, seen);
  64. }
  65. } else {
  66. return val;
  67. }
  68. }
  69. function cloneRoot (obj) {
  70. var seen = new Map();
  71. seen.set(obj, true);
  72. return cloneNodeOrObject(obj, seen);
  73. }
  74. return cloneRoot;
  75. };