9e7d3f0b44d4125902fe0b0d5021ee314fd025484d8bc9cf0cd6b483bd6092ee952c86a651d8d7ea62525a5daff3e4392081ff516b1becca02d1712b38ef98 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import type LinkedList from '../../collection/linked-list.js';
  2. import type LinkedNode from '../../collection/linked-node.js';
  3. import type { RegistryDefinition } from '../../registry.js';
  4. import Scope from '../../scope.js';
  5. export interface BlotConstructor {
  6. new (...args: any[]): Blot;
  7. /**
  8. * Creates corresponding DOM node
  9. */
  10. create(value?: any): Node;
  11. blotName: string;
  12. tagName: string | string[];
  13. scope: Scope;
  14. className?: string;
  15. requiredContainer?: BlotConstructor;
  16. allowedChildren?: BlotConstructor[];
  17. defaultChild?: BlotConstructor;
  18. }
  19. /**
  20. * Blots are the basic building blocks of a Parchment document.
  21. *
  22. * Several basic implementations such as Block, Inline, and Embed are provided.
  23. * In general you will want to extend one of these, instead of building from scratch.
  24. * After implementation, blots need to be registered before usage.
  25. *
  26. * At the very minimum a Blot must be named with a static blotName and associated with either a tagName or className.
  27. * If a Blot is defined with both a tag and class, the class takes precedence, but the tag may be used as a fallback.
  28. * Blots must also have a scope, which determine if it is inline or block.
  29. */
  30. export interface Blot extends LinkedNode {
  31. scroll: Root;
  32. parent: Parent;
  33. prev: Blot | null;
  34. next: Blot | null;
  35. domNode: Node;
  36. statics: BlotConstructor;
  37. attach(): void;
  38. clone(): Blot;
  39. detach(): void;
  40. isolate(index: number, length: number): Blot;
  41. /**
  42. * For leaves, length of blot's value()
  43. * For parents, sum of children's values
  44. */
  45. length(): number;
  46. /**
  47. * Returns offset between this blot and an ancestor's
  48. */
  49. offset(root?: Blot): number;
  50. remove(): void;
  51. replaceWith(name: string, value: any): Blot;
  52. replaceWith(replacement: Blot): Blot;
  53. split(index: number, force?: boolean): Blot | null;
  54. wrap(name: string, value?: any): Parent;
  55. wrap(wrapper: Parent): Parent;
  56. deleteAt(index: number, length: number): void;
  57. formatAt(index: number, length: number, name: string, value: any): void;
  58. insertAt(index: number, value: string, def?: any): void;
  59. /**
  60. * Called after update cycle completes. Cannot change the value or length
  61. * of the document, and any DOM operation must reduce complexity of the DOM
  62. * tree. A shared context object is passed through all blots.
  63. */
  64. optimize(context: { [key: string]: any }): void;
  65. optimize(mutations: MutationRecord[], context: { [key: string]: any }): void;
  66. /**
  67. * Called when blot changes, with the mutation records of its change.
  68. * Internal records of the blot values can be updated, and modifications of
  69. * the blot itself is permitted. Can be trigger from user change or API call.
  70. * A shared context object is passed through all blots.
  71. */
  72. update(mutations: MutationRecord[], context: { [key: string]: any }): void;
  73. }
  74. export interface Parent extends Blot {
  75. children: LinkedList<Blot>;
  76. domNode: HTMLElement;
  77. appendChild(child: Blot): void;
  78. descendant<T>(type: new () => T, index: number): [T, number];
  79. descendant<T>(matcher: (blot: Blot) => boolean, index: number): [T, number];
  80. descendants<T>(type: new () => T, index: number, length: number): T[];
  81. descendants<T>(
  82. matcher: (blot: Blot) => boolean,
  83. index: number,
  84. length: number,
  85. ): T[];
  86. insertBefore(child: Blot, refNode?: Blot | null): void;
  87. moveChildren(parent: Parent, refNode?: Blot | null): void;
  88. path(index: number, inclusive?: boolean): [Blot, number][];
  89. removeChild(child: Blot): void;
  90. unwrap(): void;
  91. }
  92. export interface Root extends Parent {
  93. create(input: Node | string | Scope, value?: any): Blot;
  94. find(node: Node | null, bubble?: boolean): Blot | null;
  95. query(query: string | Node | Scope, scope?: Scope): RegistryDefinition | null;
  96. }
  97. export interface Formattable extends Blot {
  98. /**
  99. * Apply format to blot. Should not pass onto child or other blot.
  100. */
  101. format(name: string, value: any): void;
  102. /**
  103. * Return formats represented by blot, including from Attributors.
  104. */
  105. formats(): { [index: string]: any };
  106. }
  107. export interface Leaf extends Blot {
  108. index(node: Node, offset: number): number;
  109. position(index: number, inclusive: boolean): [Node, number];
  110. value(): any;
  111. }