props.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { isStrictObject } from '../utils/helper';
  2. function defineValueProp(Node, { name, key = name }) {
  3. Node.prototype[name] = function (value) {
  4. if (arguments.length === 0)
  5. return this.attr(key);
  6. return this.attr(key, value);
  7. };
  8. }
  9. function defineArrayProp(Node, { name, key = name }) {
  10. Node.prototype[name] = function (value) {
  11. if (arguments.length === 0)
  12. return this.attr(key);
  13. if (Array.isArray(value))
  14. return this.attr(key, value);
  15. const array = [...(this.attr(key) || []), value];
  16. return this.attr(key, array);
  17. };
  18. }
  19. function defineObjectProp(Node, { name, key: k = name }) {
  20. Node.prototype[name] = function (key, value) {
  21. if (arguments.length === 0)
  22. return this.attr(k);
  23. if (arguments.length === 1 && typeof key !== 'string') {
  24. return this.attr(k, key);
  25. }
  26. const obj = this.attr(k) || {};
  27. obj[key] = arguments.length === 1 ? true : value;
  28. return this.attr(k, obj);
  29. };
  30. }
  31. function defineMixProp(Node, { name }) {
  32. Node.prototype[name] = function (key) {
  33. if (arguments.length === 0)
  34. return this.attr(name);
  35. if (Array.isArray(key))
  36. return this.attr(name, { items: key });
  37. if (isStrictObject(key) &&
  38. (key.title !== undefined || key.items !== undefined)) {
  39. return this.attr(name, key);
  40. }
  41. if (key === null || key === false)
  42. return this.attr(name, key);
  43. const obj = this.attr(name) || {};
  44. const { items = [] } = obj;
  45. items.push(key);
  46. obj.items = items;
  47. return this.attr(name, obj);
  48. };
  49. }
  50. function defineNodeProp(Node, { name, ctor }) {
  51. Node.prototype[name] = function (hocMark) {
  52. const node = this.append(ctor);
  53. if (name === 'mark') {
  54. node.type = hocMark;
  55. }
  56. return node;
  57. };
  58. }
  59. function defineContainerProp(Node, { name, ctor }) {
  60. Node.prototype[name] = function () {
  61. this.type = null;
  62. return this.append(ctor);
  63. };
  64. }
  65. /**
  66. * A decorator to define different type of attribute setter or
  67. * getter for current node.
  68. */
  69. export function defineProps(descriptors) {
  70. return (Node) => {
  71. for (const descriptor of descriptors) {
  72. const { type } = descriptor;
  73. if (type === 'value')
  74. defineValueProp(Node, descriptor);
  75. else if (type === 'array')
  76. defineArrayProp(Node, descriptor);
  77. else if (type === 'object')
  78. defineObjectProp(Node, descriptor);
  79. else if (type === 'node')
  80. defineNodeProp(Node, descriptor);
  81. else if (type === 'container')
  82. defineContainerProp(Node, descriptor);
  83. else if (type === 'mix')
  84. defineMixProp(Node, descriptor);
  85. }
  86. return Node;
  87. };
  88. }
  89. export function nodeProps(node) {
  90. return Object.entries(node).map(([name, ctor]) => ({
  91. type: 'node',
  92. name,
  93. ctor,
  94. }));
  95. }
  96. export function containerProps(node) {
  97. return Object.entries(node).map(([name, ctor]) => ({
  98. type: 'container',
  99. name,
  100. ctor,
  101. }));
  102. }
  103. //# sourceMappingURL=props.js.map