@gravity-ui/markdown-editor 15.3.1 → 15.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js +7 -3
  2. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js.map +1 -1
  3. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.d.ts +1 -0
  4. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.js +19 -2
  5. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.js.map +1 -1
  6. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.d.ts +3 -0
  7. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.js +7 -1
  8. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.js.map +1 -1
  9. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.d.ts +1 -1
  10. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.js +8 -2
  11. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.js.map +1 -1
  12. package/build/cjs/extensions/additional/Mermaid/actions.js +12 -5
  13. package/build/cjs/extensions/additional/Mermaid/actions.js.map +1 -1
  14. package/build/cjs/extensions/additional/Mermaid/types.d.ts +3 -0
  15. package/build/cjs/extensions/additional/Mermaid/types.js +3 -0
  16. package/build/cjs/extensions/additional/Mermaid/types.js.map +1 -0
  17. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +1 -0
  18. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +14 -5
  19. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js.map +1 -1
  20. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +13 -12
  21. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js.map +1 -1
  22. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +3 -0
  23. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +7 -1
  24. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js.map +1 -1
  25. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +1 -1
  26. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +8 -2
  27. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js.map +1 -1
  28. package/build/cjs/extensions/additional/YfmHtmlBlock/actions.js +9 -2
  29. package/build/cjs/extensions/additional/YfmHtmlBlock/actions.js.map +1 -1
  30. package/build/cjs/extensions/additional/YfmHtmlBlock/types.d.ts +3 -0
  31. package/build/cjs/extensions/additional/YfmHtmlBlock/types.js +3 -0
  32. package/build/cjs/extensions/additional/YfmHtmlBlock/types.js.map +1 -0
  33. package/build/cjs/extensions/behavior/Autocomplete/index.d.ts +1 -0
  34. package/build/cjs/extensions/behavior/Autocomplete/index.js +5 -3
  35. package/build/cjs/extensions/behavior/Autocomplete/index.js.map +1 -1
  36. package/build/cjs/extensions/behavior/Autocomplete/types.d.ts +1 -1
  37. package/build/cjs/extensions/behavior/Autocomplete/types.js.map +1 -1
  38. package/build/cjs/extensions/behavior/Autocomplete/utils.d.ts +3 -0
  39. package/build/cjs/extensions/behavior/Autocomplete/utils.js +8 -0
  40. package/build/cjs/extensions/behavior/Autocomplete/utils.js.map +1 -0
  41. package/build/cjs/extensions/behavior/Clipboard/code.d.ts +7 -1
  42. package/build/cjs/extensions/behavior/Clipboard/code.js +60 -0
  43. package/build/cjs/extensions/behavior/Clipboard/code.js.map +1 -1
  44. package/build/cjs/extensions/behavior/Clipboard/index.js +2 -0
  45. package/build/cjs/extensions/behavior/Clipboard/index.js.map +1 -1
  46. package/build/cjs/extensions/behavior/CommandMenu/handler.js +6 -6
  47. package/build/cjs/extensions/behavior/CommandMenu/handler.js.map +1 -1
  48. package/build/cjs/extensions/behavior/SharedState/SharedState.d.ts +7 -0
  49. package/build/cjs/extensions/behavior/SharedState/SharedState.js +16 -0
  50. package/build/cjs/extensions/behavior/SharedState/SharedState.js.map +1 -0
  51. package/build/cjs/extensions/behavior/SharedState/index.d.ts +1 -0
  52. package/build/cjs/extensions/behavior/SharedState/index.js +5 -0
  53. package/build/cjs/extensions/behavior/SharedState/index.js.map +1 -0
  54. package/build/cjs/extensions/behavior/SharedState/plugin.d.ts +3 -0
  55. package/build/cjs/extensions/behavior/SharedState/plugin.js +62 -0
  56. package/build/cjs/extensions/behavior/SharedState/plugin.js.map +1 -0
  57. package/build/cjs/extensions/behavior/SharedState/types.d.ts +1 -0
  58. package/build/cjs/extensions/behavior/SharedState/types.js +3 -0
  59. package/build/cjs/extensions/behavior/SharedState/types.js.map +1 -0
  60. package/build/cjs/extensions/behavior/SharedState/utils.d.ts +29 -0
  61. package/build/cjs/extensions/behavior/SharedState/utils.js +60 -0
  62. package/build/cjs/extensions/behavior/SharedState/utils.js.map +1 -0
  63. package/build/cjs/extensions/behavior/index.d.ts +2 -0
  64. package/build/cjs/extensions/behavior/index.js +4 -0
  65. package/build/cjs/extensions/behavior/index.js.map +1 -1
  66. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.d.ts +0 -1
  67. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +7 -6
  68. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  69. package/build/cjs/react-utils/index.d.ts +1 -0
  70. package/build/cjs/react-utils/index.js +1 -0
  71. package/build/cjs/react-utils/index.js.map +1 -1
  72. package/build/cjs/react-utils/useSharedEditingState.d.ts +5 -0
  73. package/build/cjs/react-utils/useSharedEditingState.js +25 -0
  74. package/build/cjs/react-utils/useSharedEditingState.js.map +1 -0
  75. package/build/cjs/utils/descedants.d.ts +8 -0
  76. package/build/cjs/utils/descedants.js +15 -0
  77. package/build/cjs/utils/descedants.js.map +1 -0
  78. package/build/cjs/utils/entity-id.d.ts +11 -0
  79. package/build/cjs/utils/entity-id.js +21 -0
  80. package/build/cjs/utils/entity-id.js.map +1 -0
  81. package/build/cjs/utils/index.d.ts +2 -0
  82. package/build/cjs/utils/index.js +2 -0
  83. package/build/cjs/utils/index.js.map +1 -1
  84. package/build/cjs/version.js +1 -1
  85. package/build/cjs/version.js.map +1 -1
  86. package/build/cjs/view/hocs/withYfmHtml/index.d.ts +2 -0
  87. package/build/cjs/view/hocs/withYfmHtml/index.js +2 -2
  88. package/build/cjs/view/hocs/withYfmHtml/index.js.map +1 -1
  89. package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +3 -1
  90. package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js.map +1 -1
  91. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js +8 -4
  92. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js.map +1 -1
  93. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.d.ts +1 -0
  94. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.js +18 -1
  95. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.js.map +1 -1
  96. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.d.ts +3 -0
  97. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.js +6 -0
  98. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.js.map +1 -1
  99. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.d.ts +2 -2
  100. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.js +8 -3
  101. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.js.map +1 -1
  102. package/build/esm/extensions/additional/Mermaid/actions.js +12 -5
  103. package/build/esm/extensions/additional/Mermaid/actions.js.map +1 -1
  104. package/build/esm/extensions/additional/Mermaid/types.d.ts +3 -0
  105. package/build/esm/extensions/additional/Mermaid/types.js +2 -0
  106. package/build/esm/extensions/additional/Mermaid/types.js.map +1 -0
  107. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +1 -0
  108. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +14 -5
  109. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js.map +1 -1
  110. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +13 -11
  111. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js.map +1 -1
  112. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +3 -0
  113. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +6 -0
  114. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js.map +1 -1
  115. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +2 -2
  116. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +8 -3
  117. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js.map +1 -1
  118. package/build/esm/extensions/additional/YfmHtmlBlock/actions.js +9 -2
  119. package/build/esm/extensions/additional/YfmHtmlBlock/actions.js.map +1 -1
  120. package/build/esm/extensions/additional/YfmHtmlBlock/types.d.ts +3 -0
  121. package/build/esm/extensions/additional/YfmHtmlBlock/types.js +2 -0
  122. package/build/esm/extensions/additional/YfmHtmlBlock/types.js.map +1 -0
  123. package/build/esm/extensions/behavior/Autocomplete/index.d.ts +1 -0
  124. package/build/esm/extensions/behavior/Autocomplete/index.js +2 -1
  125. package/build/esm/extensions/behavior/Autocomplete/index.js.map +1 -1
  126. package/build/esm/extensions/behavior/Autocomplete/types.d.ts +1 -1
  127. package/build/esm/extensions/behavior/Autocomplete/types.js.map +1 -1
  128. package/build/esm/extensions/behavior/Autocomplete/utils.d.ts +3 -0
  129. package/build/esm/extensions/behavior/Autocomplete/utils.js +5 -0
  130. package/build/esm/extensions/behavior/Autocomplete/utils.js.map +1 -0
  131. package/build/esm/extensions/behavior/Clipboard/code.d.ts +7 -1
  132. package/build/esm/extensions/behavior/Clipboard/code.js +57 -0
  133. package/build/esm/extensions/behavior/Clipboard/code.js.map +1 -1
  134. package/build/esm/extensions/behavior/Clipboard/index.js +2 -0
  135. package/build/esm/extensions/behavior/Clipboard/index.js.map +1 -1
  136. package/build/esm/extensions/behavior/CommandMenu/handler.js +7 -7
  137. package/build/esm/extensions/behavior/CommandMenu/handler.js.map +1 -1
  138. package/build/esm/extensions/behavior/SharedState/SharedState.d.ts +7 -0
  139. package/build/esm/extensions/behavior/SharedState/SharedState.js +11 -0
  140. package/build/esm/extensions/behavior/SharedState/SharedState.js.map +1 -0
  141. package/build/esm/extensions/behavior/SharedState/index.d.ts +1 -0
  142. package/build/esm/extensions/behavior/SharedState/index.js +2 -0
  143. package/build/esm/extensions/behavior/SharedState/index.js.map +1 -0
  144. package/build/esm/extensions/behavior/SharedState/plugin.d.ts +3 -0
  145. package/build/esm/extensions/behavior/SharedState/plugin.js +59 -0
  146. package/build/esm/extensions/behavior/SharedState/plugin.js.map +1 -0
  147. package/build/esm/extensions/behavior/SharedState/types.d.ts +1 -0
  148. package/build/esm/extensions/behavior/SharedState/types.js +2 -0
  149. package/build/esm/extensions/behavior/SharedState/types.js.map +1 -0
  150. package/build/esm/extensions/behavior/SharedState/utils.d.ts +29 -0
  151. package/build/esm/extensions/behavior/SharedState/utils.js +56 -0
  152. package/build/esm/extensions/behavior/SharedState/utils.js.map +1 -0
  153. package/build/esm/extensions/behavior/index.d.ts +2 -0
  154. package/build/esm/extensions/behavior/index.js +4 -0
  155. package/build/esm/extensions/behavior/index.js.map +1 -1
  156. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.d.ts +0 -1
  157. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +8 -7
  158. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  159. package/build/esm/react-utils/index.d.ts +1 -0
  160. package/build/esm/react-utils/index.js +1 -0
  161. package/build/esm/react-utils/index.js.map +1 -1
  162. package/build/esm/react-utils/useSharedEditingState.d.ts +5 -0
  163. package/build/esm/react-utils/useSharedEditingState.js +22 -0
  164. package/build/esm/react-utils/useSharedEditingState.js.map +1 -0
  165. package/build/esm/utils/descedants.d.ts +8 -0
  166. package/build/esm/utils/descedants.js +12 -0
  167. package/build/esm/utils/descedants.js.map +1 -0
  168. package/build/esm/utils/entity-id.d.ts +11 -0
  169. package/build/esm/utils/entity-id.js +16 -0
  170. package/build/esm/utils/entity-id.js.map +1 -0
  171. package/build/esm/utils/index.d.ts +2 -0
  172. package/build/esm/utils/index.js +2 -0
  173. package/build/esm/utils/index.js.map +1 -1
  174. package/build/esm/version.js +1 -1
  175. package/build/esm/version.js.map +1 -1
  176. package/build/esm/view/hocs/withYfmHtml/index.d.ts +2 -0
  177. package/build/esm/view/hocs/withYfmHtml/index.js +2 -2
  178. package/build/esm/view/hocs/withYfmHtml/index.js.map +1 -1
  179. package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +3 -1
  180. package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js.map +1 -1
  181. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/CommandMenu/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage} from '../../../core';\nimport {isFunction} from '../../../lodash';\nimport {type Logger2, globalLogger} from '../../../logger';\nimport {AutocompletePopupCloser} from '../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../utils/carousel';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n type FromTo,\n closeAutocomplete,\n} from '../Autocomplete';\nimport {type RendererItem, getReactRendererFromState} from '../ReactRenderer';\n\nimport {type CommandMenuComponentProps, render} from './component';\nimport type {CommandAction, Config} from './types';\nimport {findDecoElem} from './utils';\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n commandMenu?: boolean;\n }\n}\n\nexport type CommandHandlerParams = {\n logger: Logger2.ILogger;\n actions: Config;\n storage: ActionStorage;\n nodesIgnoreList?: readonly string[];\n};\n\nexport class CommandHandler implements AutocompleteHandler {\n readonly #logger: Logger2.ILogger;\n readonly #actions: readonly CommandAction[];\n readonly #actionStorage: ActionStorage;\n readonly #nodesIgnoreList: readonly string[];\n #filteredActionsCarousel?: ArrayCarousel<CommandAction>;\n\n #view?: EditorView;\n #anchor: Element | null = null;\n #range?: FromTo;\n #filterText?: string;\n #popupCloser?: AutocompletePopupCloser;\n\n #menuProps?: CommandMenuComponentProps;\n #menuRenderItem?: RendererItem;\n\n constructor({logger, actions, storage, nodesIgnoreList = []}: CommandHandlerParams) {\n this.#logger = logger;\n this.#actions = actions;\n this.#actionStorage = storage;\n this.#nodesIgnoreList = nodesIgnoreList;\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this.#anchor || this.shouldIgnore(action)) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.#popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action) || action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n this.#filterText = action.filter?.trim().toLowerCase();\n const needToClose = this.filterActions();\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action)) {\n closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n if (!this.#filteredActionsCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this.#filteredActionsCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this.#filteredActionsCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action)) {\n closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private shouldIgnore(action: AutocompleteAction): boolean {\n const parentType = action.view.state.doc.resolve(action.range.from).parent.type;\n return (\n parentType.spec.commandMenu === false || this.#nodesIgnoreList.includes(parentType.name)\n );\n }\n\n private select() {\n if (!this.#view || !this.#range) return;\n\n const action = this.#filteredActionsCarousel?.currentItem;\n if (!action) return;\n\n const view = this.#view;\n const range = this.#range;\n\n view.dispatch(view.state.tr.deleteRange(range.from, range.to).scrollIntoView());\n action.exec(this.#actionStorage);\n view.focus();\n\n globalLogger.action({mode: 'wysiwyg', source: 'command-menu', action: action.id});\n this.#logger.action({source: 'command-menu', action: action.id});\n }\n\n private filterActions(): boolean {\n const currentItem = this.#filteredActionsCarousel?.currentItem;\n const inputText = this.#filterText;\n\n const enabledActions = this.#actions.filter((action) =>\n action.isEnable(this.#actionStorage),\n );\n\n let filteredActions = enabledActions;\n let needToClose = false;\n\n if (inputText) {\n filteredActions = filterActions(enabledActions, inputText);\n needToClose = !filteredActions.length && needToHide(enabledActions, inputText);\n }\n\n this.#filteredActionsCarousel = new ArrayCarousel(filteredActions);\n\n if (currentItem) {\n const newIndex = this.#filteredActionsCarousel.array.findIndex(\n (item) => item === currentItem,\n );\n if (newIndex !== -1) {\n this.#filteredActionsCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this.#filteredActionsCarousel?.array ?? [];\n this.#menuProps = {\n anchorElement: this.#anchor,\n currentIndex: this.#filteredActionsCarousel?.currentIndex,\n items: viewItems,\n onItemClick: this.onItemClick,\n onOpenChange: this.#popupCloser?.popupOpenChangeHandler,\n };\n this.#menuRenderItem = this.#menuRenderItem ?? this.createMenuRenderItem();\n this.#menuRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this.#filteredActionsCarousel) {\n this.#filteredActionsCarousel.currentIndex = index;\n this.select();\n }\n this.#view?.focus();\n };\n\n private updateState({view, range}: AutocompleteAction) {\n this.#view = view;\n this.#range = range;\n }\n\n private clear() {\n this.#view = undefined;\n this.#range = undefined;\n this.#anchor = null;\n this.#filterText = undefined;\n this.#filteredActionsCarousel = undefined;\n this.#popupCloser?.cancelTimer();\n this.#popupCloser = undefined;\n this.#menuProps = undefined;\n this.#menuRenderItem?.remove();\n this.#menuRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this.#view!.state).createItem('command_menu', () =>\n this.#menuProps ? render(this.#menuProps) : null,\n );\n }\n\n private findAnchor() {\n this.#anchor = findDecoElem(this.#view?.dom);\n }\n}\n\nfunction filterActions(actions: readonly CommandAction[], text: string): CommandAction[] {\n return actions.filter(\n (action) =>\n action.id.toLowerCase().includes(text) ||\n (isFunction(action.title) ? action.title() : action.title).toLowerCase().includes(text),\n );\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(actions: readonly CommandAction[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterActions(actions, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
1
+ {"version":3,"file":"handler.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/CommandMenu/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage} from '../../../core';\nimport {isFunction} from '../../../lodash';\nimport {type Logger2, globalLogger} from '../../../logger';\nimport {AutocompletePopupCloser} from '../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../utils/carousel';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n closeAutocomplete,\n getAutocompleteState,\n} from '../Autocomplete';\nimport {type RendererItem, getReactRendererFromState} from '../ReactRenderer';\n\nimport {type CommandMenuComponentProps, render} from './component';\nimport type {CommandAction, Config} from './types';\nimport {findDecoElem} from './utils';\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n commandMenu?: boolean;\n }\n}\n\nexport type CommandHandlerParams = {\n logger: Logger2.ILogger;\n actions: Config;\n storage: ActionStorage;\n nodesIgnoreList?: readonly string[];\n};\n\nexport class CommandHandler implements AutocompleteHandler {\n readonly #logger: Logger2.ILogger;\n readonly #actions: readonly CommandAction[];\n readonly #actionStorage: ActionStorage;\n readonly #nodesIgnoreList: readonly string[];\n #filteredActionsCarousel?: ArrayCarousel<CommandAction>;\n\n #view?: EditorView;\n #anchor: Element | null = null;\n #filterText?: string;\n #popupCloser?: AutocompletePopupCloser;\n\n #menuProps?: CommandMenuComponentProps;\n #menuRenderItem?: RendererItem;\n\n constructor({logger, actions, storage, nodesIgnoreList = []}: CommandHandlerParams) {\n this.#logger = logger;\n this.#actions = actions;\n this.#actionStorage = storage;\n this.#nodesIgnoreList = nodesIgnoreList;\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this.#anchor || this.shouldIgnore(action)) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.#popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action) || action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n this.#filterText = action.filter?.trim().toLowerCase();\n const needToClose = this.filterActions();\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action)) {\n closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n if (!this.#filteredActionsCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this.#filteredActionsCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this.#filteredActionsCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n if (this.shouldIgnore(action)) {\n closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private shouldIgnore(action: AutocompleteAction): boolean {\n const parentType = action.view.state.doc.resolve(action.range.from).parent.type;\n return (\n parentType.spec.commandMenu === false || this.#nodesIgnoreList.includes(parentType.name)\n );\n }\n\n private select() {\n if (!this.#view) return;\n\n const action = this.#filteredActionsCarousel?.currentItem;\n if (!action) return;\n\n const autocompleteState = getAutocompleteState(this.#view.state);\n if (!autocompleteState || !autocompleteState.active) return;\n\n const view = this.#view;\n const {range} = autocompleteState;\n\n view.dispatch(view.state.tr.deleteRange(range.from, range.to).scrollIntoView());\n action.exec(this.#actionStorage);\n view.focus();\n\n globalLogger.action({mode: 'wysiwyg', source: 'command-menu', action: action.id});\n this.#logger.action({source: 'command-menu', action: action.id});\n }\n\n private filterActions(): boolean {\n const currentItem = this.#filteredActionsCarousel?.currentItem;\n const inputText = this.#filterText;\n\n const enabledActions = this.#actions.filter((action) =>\n action.isEnable(this.#actionStorage),\n );\n\n let filteredActions = enabledActions;\n let needToClose = false;\n\n if (inputText) {\n filteredActions = filterActions(enabledActions, inputText);\n needToClose = !filteredActions.length && needToHide(enabledActions, inputText);\n }\n\n this.#filteredActionsCarousel = new ArrayCarousel(filteredActions);\n\n if (currentItem) {\n const newIndex = this.#filteredActionsCarousel.array.findIndex(\n (item) => item === currentItem,\n );\n if (newIndex !== -1) {\n this.#filteredActionsCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this.#filteredActionsCarousel?.array ?? [];\n this.#menuProps = {\n anchorElement: this.#anchor,\n currentIndex: this.#filteredActionsCarousel?.currentIndex,\n items: viewItems,\n onItemClick: this.onItemClick,\n onOpenChange: this.#popupCloser?.popupOpenChangeHandler,\n };\n this.#menuRenderItem = this.#menuRenderItem ?? this.createMenuRenderItem();\n this.#menuRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this.#filteredActionsCarousel) {\n this.#filteredActionsCarousel.currentIndex = index;\n this.select();\n }\n this.#view?.focus();\n };\n\n private updateState({view}: AutocompleteAction) {\n this.#view = view;\n }\n\n private clear() {\n this.#view = undefined;\n this.#anchor = null;\n this.#filterText = undefined;\n this.#filteredActionsCarousel = undefined;\n this.#popupCloser?.cancelTimer();\n this.#popupCloser = undefined;\n this.#menuProps = undefined;\n this.#menuRenderItem?.remove();\n this.#menuRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this.#view!.state).createItem('command_menu', () =>\n this.#menuProps ? render(this.#menuProps) : null,\n );\n }\n\n private findAnchor() {\n this.#anchor = findDecoElem(this.#view?.dom);\n }\n}\n\nfunction filterActions(actions: readonly CommandAction[], text: string): CommandAction[] {\n return actions.filter(\n (action) =>\n action.id.toLowerCase().includes(text) ||\n (isFunction(action.title) ? action.title() : action.title).toLowerCase().includes(text),\n );\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(actions: readonly CommandAction[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterActions(actions, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { Extension } from "../../../core/index.js";
2
+ export { SharedStateKey, type SharedStateKeySpec } from "./utils.js";
3
+ /**
4
+ * This extension enables a plugin that stores internal state and handles its changes via meta-information in transactions.
5
+ * You can get, change and subscribe to state changes using a SharedStateKey instance.
6
+ */
7
+ export declare const SharedState: Extension;
@@ -0,0 +1,11 @@
1
+ import { Plugin } from "../../../pm/state.js";
2
+ import { pluginSpec } from "./plugin.js";
3
+ export { SharedStateKey } from "./utils.js";
4
+ /**
5
+ * This extension enables a plugin that stores internal state and handles its changes via meta-information in transactions.
6
+ * You can get, change and subscribe to state changes using a SharedStateKey instance.
7
+ */
8
+ export const SharedState = (builder) => {
9
+ builder.addPlugin(() => new Plugin(pluginSpec));
10
+ };
11
+ //# sourceMappingURL=SharedState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SharedState.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SharedState/SharedState.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,6BAAkB;AAEjC,OAAO,EAAC,UAAU,EAAC,oBAAiB;AAEpC,OAAO,EAAC,cAAc,EAA0B,mBAAgB;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAc,CAAC,OAAO,EAAE,EAAE;IAC9C,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC","sourcesContent":["import type {Extension} from '#core';\nimport {Plugin} from '#pm/state';\n\nimport {pluginSpec} from './plugin';\n\nexport {SharedStateKey, type SharedStateKeySpec} from './utils';\n\n/**\n * This extension enables a plugin that stores internal state and handles its changes via meta-information in transactions.\n * You can get, change and subscribe to state changes using a SharedStateKey instance.\n */\nexport const SharedState: Extension = (builder) => {\n builder.addPlugin(() => new Plugin(pluginSpec));\n};\n"]}
@@ -0,0 +1 @@
1
+ export * from "./SharedState.js";
@@ -0,0 +1,2 @@
1
+ export * from "./SharedState.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SharedState/index.ts"],"names":[],"mappings":"AAAA,iCAA8B","sourcesContent":["export * from './SharedState';\n"]}
@@ -0,0 +1,3 @@
1
+ import { type PluginSpec } from "../../../pm/state.js";
2
+ import type { SharedPluginState } from "./types.js";
3
+ export declare const pluginSpec: PluginSpec<SharedPluginState>;
@@ -0,0 +1,59 @@
1
+ import { PluginKey } from "../../../pm/state.js";
2
+ import { EventEmitter } from "../../../utils/event-emitter.js";
3
+ /** @internal */
4
+ export const pluginKey = new PluginKey('shared-state');
5
+ export const pluginSpec = {
6
+ key: pluginKey,
7
+ state: {
8
+ init() {
9
+ return {
10
+ map: new Map(),
11
+ changedKeys: null,
12
+ notifyBus: new EventEmitter(),
13
+ };
14
+ },
15
+ apply(tr, { map, notifyBus }) {
16
+ const meta = tr.getMeta(pluginKey);
17
+ if (!meta || !meta.actions.length)
18
+ return { changedKeys: null, map, notifyBus };
19
+ const changedKeys = new Set();
20
+ for (const action of meta.actions) {
21
+ switch (action.type) {
22
+ case 'delete': {
23
+ map.delete(action.key);
24
+ break;
25
+ }
26
+ case 'update': {
27
+ let value = map.get(action.key);
28
+ value = { ...value, ...action.data };
29
+ map.set(action.key, value);
30
+ break;
31
+ }
32
+ case 'set': {
33
+ map.set(action.key, action.data);
34
+ break;
35
+ }
36
+ default: {
37
+ continue;
38
+ }
39
+ }
40
+ changedKeys.add(action.key);
41
+ }
42
+ return { changedKeys, map, notifyBus };
43
+ },
44
+ },
45
+ view: () => {
46
+ return {
47
+ update(view) {
48
+ const state = pluginKey.getState(view.state);
49
+ if (!state || !state.changedKeys || !state.changedKeys.size)
50
+ return;
51
+ for (const key of state.changedKeys) {
52
+ const value = state.map.get(key);
53
+ state.notifyBus.emit(key, value);
54
+ }
55
+ },
56
+ };
57
+ },
58
+ };
59
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SharedState/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAkB,6BAAkB;AACrD,OAAO,EAAC,YAAY,EAAC,wCAAgC;AAIrD,gBAAgB;AAChB,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAoB,cAAc,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,UAAU,GAAkC;IACrD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE;QACH,IAAI;YACA,OAAO;gBACH,GAAG,EAAE,IAAI,GAAG,EAAE;gBACd,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI,YAAY,EAAE;aAChC,CAAC;QACN,CAAC;QACD,KAAK,CAAC,EAAE,EAAE,EAAC,GAAG,EAAE,SAAS,EAAC;YACtB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAuB,CAAC;YACzD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,EAAC,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAC,CAAC;YAE9E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;YACtC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAChC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;oBAClB,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACZ,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBACvB,MAAM;oBACV,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACZ,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBAChC,KAAK,GAAG,EAAC,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,EAAC,CAAC;wBACnC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;wBAC3B,MAAM;oBACV,CAAC;oBACD,KAAK,KAAK,CAAC,CAAC,CAAC;wBACT,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;wBACjC,MAAM;oBACV,CAAC;oBACD,OAAO,CAAC,CAAC,CAAC;wBACN,SAAS;oBACb,CAAC;gBACL,CAAC;gBACD,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;YAED,OAAO,EAAC,WAAW,EAAE,GAAG,EAAE,SAAS,EAAC,CAAC;QACzC,CAAC;KACJ;IACD,IAAI,EAAE,GAAG,EAAE;QACP,OAAO;YACH,MAAM,CAAC,IAAI;gBACP,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7C,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI;oBAAE,OAAO;gBAEpE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;oBAClC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACjC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACrC,CAAC;YACL,CAAC;SACJ,CAAC;IACN,CAAC;CACJ,CAAC","sourcesContent":["import {PluginKey, type PluginSpec} from '#pm/state';\nimport {EventEmitter} from 'src/utils/event-emitter';\n\nimport type {SharedPluginState, TrMeta} from './types';\n\n/** @internal */\nexport const pluginKey = new PluginKey<SharedPluginState>('shared-state');\n\nexport const pluginSpec: PluginSpec<SharedPluginState> = {\n key: pluginKey,\n state: {\n init() {\n return {\n map: new Map(),\n changedKeys: null,\n notifyBus: new EventEmitter(),\n };\n },\n apply(tr, {map, notifyBus}) {\n const meta = tr.getMeta(pluginKey) as TrMeta | undefined;\n if (!meta || !meta.actions.length) return {changedKeys: null, map, notifyBus};\n\n const changedKeys = new Set<string>();\n for (const action of meta.actions) {\n switch (action.type) {\n case 'delete': {\n map.delete(action.key);\n break;\n }\n case 'update': {\n let value = map.get(action.key);\n value = {...value, ...action.data};\n map.set(action.key, value);\n break;\n }\n case 'set': {\n map.set(action.key, action.data);\n break;\n }\n default: {\n continue;\n }\n }\n changedKeys.add(action.key);\n }\n\n return {changedKeys, map, notifyBus};\n },\n },\n view: () => {\n return {\n update(view) {\n const state = pluginKey.getState(view.state);\n if (!state || !state.changedKeys || !state.changedKeys.size) return;\n\n for (const key of state.changedKeys) {\n const value = state.map.get(key);\n state.notifyBus.emit(key, value);\n }\n },\n };\n },\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SharedState/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {EventEmitter} from 'src/utils/event-emitter';\n\n/** @internal */\nexport type SharedPluginState = {\n map: Map<string, object>;\n changedKeys: Set<string> | null;\n notifyBus: EventEmitter<{[key: string]: object | undefined}>;\n};\n\n/** @internal */\nexport type TrMeta = {\n actions: SharedStateAction<object>[];\n};\n\n/** @internal */\nexport type SharedStateAction<T extends object> =\n | {\n type: 'set';\n key: string;\n data: T;\n }\n | {\n type: 'update';\n key: string;\n data: Partial<T>;\n }\n | {\n type: 'delete';\n key: string;\n };\n"]}
@@ -0,0 +1,29 @@
1
+ import type { EditorState, Transaction } from "../../../pm/state.js";
2
+ export type SharedStateKeySpec = {
3
+ name?: string;
4
+ };
5
+ export declare class SharedStateKey<T extends object> {
6
+ #private;
7
+ /**
8
+ * Define a new key.
9
+ * If you create two keys with the same name, they will refer to the same value from the state.
10
+ * If name not passed, a unique one will be generated.
11
+ */
12
+ static define<T extends object>(spec?: SharedStateKeySpec): SharedStateKey<T>;
13
+ /** Add metadata to transaction to change data in state */
14
+ readonly appendTransaction: Readonly<{
15
+ /** Set or replace data stored by current key */
16
+ set: (tr: Transaction, data: T) => Transaction;
17
+ /** Update (patch) data stored by current key */
18
+ update: (tr: Transaction, data: Partial<T>) => Transaction;
19
+ /** Delete data stored by current key */
20
+ delete: (tr: Transaction) => Transaction;
21
+ }>;
22
+ private constructor();
23
+ getNotifier(state: EditorState): {
24
+ subscribe(fn: (data: T | undefined) => void): () => void;
25
+ unsubscribe(fn: (data: T | undefined) => void): void;
26
+ };
27
+ getValue(state: EditorState): T | undefined;
28
+ private appendTrMeta;
29
+ }
@@ -0,0 +1,56 @@
1
+ import { uniqueId } from "../../../lodash.js";
2
+ import { pluginKey } from "./plugin.js";
3
+ export class SharedStateKey {
4
+ /**
5
+ * Define a new key.
6
+ * If you create two keys with the same name, they will refer to the same value from the state.
7
+ * If name not passed, a unique one will be generated.
8
+ */
9
+ static define(spec = {}) {
10
+ const key = spec.name ?? uniqueId('shared_state_key');
11
+ return new this(key);
12
+ }
13
+ #key;
14
+ /** Add metadata to transaction to change data in state */
15
+ appendTransaction = Object.freeze({
16
+ /** Set or replace data stored by current key */
17
+ set: (tr, data) => {
18
+ return this.appendTrMeta(tr, { type: 'set', data });
19
+ },
20
+ /** Update (patch) data stored by current key */
21
+ update: (tr, data) => {
22
+ return this.appendTrMeta(tr, { type: 'update', data });
23
+ },
24
+ /** Delete data stored by current key */
25
+ delete: (tr) => {
26
+ return this.appendTrMeta(tr, { type: 'delete' });
27
+ },
28
+ });
29
+ constructor(key) {
30
+ this.#key = key;
31
+ }
32
+ getNotifier(state) {
33
+ const self = this;
34
+ const notifyBus = pluginKey.getState(state)?.notifyBus;
35
+ return {
36
+ subscribe(fn) {
37
+ notifyBus?.on(self.#key, fn);
38
+ return () => {
39
+ this.unsubscribe(fn);
40
+ };
41
+ },
42
+ unsubscribe(fn) {
43
+ notifyBus?.off(self.#key, fn);
44
+ },
45
+ };
46
+ }
47
+ getValue(state) {
48
+ return pluginKey.getState(state)?.map.get(this.#key);
49
+ }
50
+ appendTrMeta(tr, action) {
51
+ const meta = tr.getMeta(pluginKey) || { actions: [] };
52
+ meta.actions.push({ ...action, key: this.#key });
53
+ return tr.setMeta(pluginKey, meta);
54
+ }
55
+ }
56
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SharedState/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,2BAAmB;AAEpC,OAAO,EAAC,SAAS,EAAC,oBAAiB;AAOnC,MAAM,OAAO,cAAc;IACvB;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAmB,OAA2B,EAAE;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QACtD,OAAO,IAAI,IAAI,CAAI,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,CAAS;IAEb,0DAA0D;IACjD,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;QACvC,gDAAgD;QAChD,GAAG,EAAE,CAAC,EAAe,EAAE,IAAO,EAAe,EAAE;YAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;QACtD,CAAC;QACD,gDAAgD;QAChD,MAAM,EAAE,CAAC,EAAe,EAAE,IAAgB,EAAe,EAAE;YACvD,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;QACzD,CAAC;QACD,wCAAwC;QACxC,MAAM,EAAE,CAAC,EAAe,EAAe,EAAE;YACrC,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAC;QACnD,CAAC;KACJ,CAAC,CAAC;IAEH,YAAoB,GAAW;QAC3B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IACpB,CAAC;IAED,WAAW,CAAC,KAAkB;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;QACvD,OAAO;YACH,SAAS,CAAC,EAAiC;gBACvC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAA4B,CAAC,CAAC;gBACvD,OAAO,GAAG,EAAE;oBACR,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBACzB,CAAC,CAAC;YACN,CAAC;YACD,WAAW,CAAC,EAAiC;gBACzC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAA4B,CAAC,CAAC;YAC5D,CAAC;SACJ,CAAC;IACN,CAAC;IAED,QAAQ,CAAC,KAAkB;QACvB,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAC;IAC1E,CAAC;IAEO,YAAY,CAAC,EAAe,EAAE,MAAiB;QACnD,MAAM,IAAI,GAAW,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAC,OAAO,EAAE,EAAE,EAAC,CAAC;QAC5D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;CACJ","sourcesContent":["import type {EditorState, Transaction} from '#pm/state';\nimport {uniqueId} from 'src/lodash';\n\nimport {pluginKey} from './plugin';\nimport type {TrMeta} from './types';\n\nexport type SharedStateKeySpec = {\n name?: string;\n};\n\nexport class SharedStateKey<T extends object> {\n /**\n * Define a new key.\n * If you create two keys with the same name, they will refer to the same value from the state.\n * If name not passed, a unique one will be generated.\n */\n static define<T extends object>(spec: SharedStateKeySpec = {}) {\n const key = spec.name ?? uniqueId('shared_state_key');\n return new this<T>(key);\n }\n\n #key: string;\n\n /** Add metadata to transaction to change data in state */\n readonly appendTransaction = Object.freeze({\n /** Set or replace data stored by current key */\n set: (tr: Transaction, data: T): Transaction => {\n return this.appendTrMeta(tr, {type: 'set', data});\n },\n /** Update (patch) data stored by current key */\n update: (tr: Transaction, data: Partial<T>): Transaction => {\n return this.appendTrMeta(tr, {type: 'update', data});\n },\n /** Delete data stored by current key */\n delete: (tr: Transaction): Transaction => {\n return this.appendTrMeta(tr, {type: 'delete'});\n },\n });\n\n private constructor(key: string) {\n this.#key = key;\n }\n\n getNotifier(state: EditorState) {\n const self = this;\n const notifyBus = pluginKey.getState(state)?.notifyBus;\n return {\n subscribe(fn: (data: T | undefined) => void) {\n notifyBus?.on(self.#key, fn as (arg: unknown) => void);\n return () => {\n this.unsubscribe(fn);\n };\n },\n unsubscribe(fn: (data: T | undefined) => void) {\n notifyBus?.off(self.#key, fn as (arg: unknown) => void);\n },\n };\n }\n\n getValue(state: EditorState): T | undefined {\n return pluginKey.getState(state)?.map.get(this.#key) as T | undefined;\n }\n\n private appendTrMeta(tr: Transaction, action: Action<T>) {\n const meta: TrMeta = tr.getMeta(pluginKey) || {actions: []};\n meta.actions.push({...action, key: this.#key});\n return tr.setMeta(pluginKey, meta);\n }\n}\n\n/** @internal */\ntype Action<T extends object> =\n | {\n type: 'set';\n data: T;\n }\n | {\n type: 'update';\n data: Partial<T>;\n }\n | {\n type: 'delete';\n };\n"]}
@@ -6,6 +6,7 @@ import { type CursorOptions } from "./Cursor/index.js";
6
6
  import { type HistoryOptions } from "./History/index.js";
7
7
  import { type ReactRenderer } from "./ReactRenderer/index.js";
8
8
  import { type SelectionContextOptions } from "./SelectionContext/index.js";
9
+ export * from "./Autocomplete/index.js";
9
10
  export * from "./ClicksOnEdges/index.js";
10
11
  export * from "./Clipboard/index.js";
11
12
  export * from "./CommandMenu/index.js";
@@ -16,6 +17,7 @@ export * from "./Placeholder/index.js";
16
17
  export * from "./ReactRenderer/index.js";
17
18
  export * from "./Selection/index.js";
18
19
  export * from "./SelectionContext/index.js";
20
+ export * from "./SharedState/index.js";
19
21
  export * from "./WidgetDecoration/index.js";
20
22
  export type BehaviorPresetOptions = {
21
23
  cursor?: CursorOptions;
@@ -8,7 +8,9 @@ import { Placeholder } from "./Placeholder/index.js";
8
8
  import { ReactRendererExtension } from "./ReactRenderer/index.js";
9
9
  import { Selection } from "./Selection/index.js";
10
10
  import { SelectionContext } from "./SelectionContext/index.js";
11
+ import { SharedState } from "./SharedState/index.js";
11
12
  import { WidgetDecoration } from "./WidgetDecoration/index.js";
13
+ export * from "./Autocomplete/index.js";
12
14
  export * from "./ClicksOnEdges/index.js";
13
15
  export * from "./Clipboard/index.js";
14
16
  export * from "./CommandMenu/index.js";
@@ -19,10 +21,12 @@ export * from "./Placeholder/index.js";
19
21
  export * from "./ReactRenderer/index.js";
20
22
  export * from "./Selection/index.js";
21
23
  export * from "./SelectionContext/index.js";
24
+ export * from "./SharedState/index.js";
22
25
  export * from "./WidgetDecoration/index.js";
23
26
  export const BehaviorPreset = (builder, opts) => {
24
27
  builder
25
28
  .use(Selection)
29
+ .use(SharedState)
26
30
  .use(Placeholder, opts.placeholder ?? {})
27
31
  .use(Cursor, opts.cursor ?? {})
28
32
  .use(History, opts.history ?? {})
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../src","sources":["extensions/behavior/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,aAAa,EAAC,iCAAwB;AAC9C,OAAO,EAAC,SAAS,EAAwB,6BAAoB;AAC7D,OAAO,EAAC,WAAW,EAA0B,+BAAsB;AACnE,OAAO,EAAC,MAAM,EAAqB,0BAAiB;AACpD,OAAO,EAAC,SAAS,EAAC,6BAAoB;AACtC,OAAO,EAAC,OAAO,EAAsB,2BAAkB;AACvD,OAAO,EAAC,WAAW,EAAC,+BAAsB;AAC1C,OAAO,EAAqB,sBAAsB,EAAC,iCAAwB;AAC3E,OAAO,EAAC,SAAS,EAAC,6BAAoB;AACtC,OAAO,EAAC,gBAAgB,EAA+B,oCAA2B;AAClF,OAAO,EAAC,gBAAgB,EAAC,oCAA2B;AAEpD,yCAAgC;AAChC,qCAA4B;AAC5B,uCAA8B;AAC9B,kCAAyB;AACzB,qCAA4B;AAC5B,mCAA0B;AAC1B,uCAA8B;AAC9B,yCAAgC;AAChC,qCAA4B;AAC5B,4CAAmC;AACnC,4CAAmC;AAanC,MAAM,CAAC,MAAM,cAAc,GAAyC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAClF,OAAO;SACF,GAAG,CAAC,SAAS,CAAC;SACd,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;SACxC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;SAC9B,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;SAChC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;SACpC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,aAAa,CAAC;SAC/C,GAAG,CAAC,gBAAgB,CAAC;SACrB,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["import type {ExtensionAuto} from '../../core';\nimport type {PlaceholderOptions} from '../../utils/placeholder';\n\nimport {ClicksOnEdges} from './ClicksOnEdges';\nimport {Clipboard, type ClipboardOptions} from './Clipboard';\nimport {CommandMenu, type CommandMenuOptions} from './CommandMenu';\nimport {Cursor, type CursorOptions} from './Cursor';\nimport {FilePaste} from './FilePaste';\nimport {History, type HistoryOptions} from './History';\nimport {Placeholder} from './Placeholder';\nimport {type ReactRenderer, ReactRendererExtension} from './ReactRenderer';\nimport {Selection} from './Selection';\nimport {SelectionContext, type SelectionContextOptions} from './SelectionContext';\nimport {WidgetDecoration} from './WidgetDecoration';\n\nexport * from './ClicksOnEdges';\nexport * from './Clipboard';\nexport * from './CommandMenu';\nexport * from './Cursor';\nexport * from './FilePaste';\nexport * from './History';\nexport * from './Placeholder';\nexport * from './ReactRenderer';\nexport * from './Selection';\nexport * from './SelectionContext';\nexport * from './WidgetDecoration';\n\nexport type BehaviorPresetOptions = {\n cursor?: CursorOptions;\n history?: HistoryOptions;\n clipboard?: ClipboardOptions;\n placeholder?: PlaceholderOptions;\n reactRenderer: ReactRenderer;\n selectionContext?: SelectionContextOptions;\n\n commandMenu?: CommandMenuOptions;\n};\n\nexport const BehaviorPreset: ExtensionAuto<BehaviorPresetOptions> = (builder, opts) => {\n builder\n .use(Selection)\n .use(Placeholder, opts.placeholder ?? {})\n .use(Cursor, opts.cursor ?? {})\n .use(History, opts.history ?? {})\n .use(Clipboard, opts.clipboard ?? {})\n .use(ReactRendererExtension, opts.reactRenderer)\n .use(WidgetDecoration)\n .use(SelectionContext, opts.selectionContext ?? {});\n\n if (opts.commandMenu) builder.use(CommandMenu, opts.commandMenu);\n builder.use(FilePaste);\n builder.use(ClicksOnEdges);\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../src","sources":["extensions/behavior/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,aAAa,EAAC,iCAAwB;AAC9C,OAAO,EAAC,SAAS,EAAwB,6BAAoB;AAC7D,OAAO,EAAC,WAAW,EAA0B,+BAAsB;AACnE,OAAO,EAAC,MAAM,EAAqB,0BAAiB;AACpD,OAAO,EAAC,SAAS,EAAC,6BAAoB;AACtC,OAAO,EAAC,OAAO,EAAsB,2BAAkB;AACvD,OAAO,EAAC,WAAW,EAAC,+BAAsB;AAC1C,OAAO,EAAqB,sBAAsB,EAAC,iCAAwB;AAC3E,OAAO,EAAC,SAAS,EAAC,6BAAoB;AACtC,OAAO,EAAC,gBAAgB,EAA+B,oCAA2B;AAClF,OAAO,EAAC,WAAW,EAAC,+BAAsB;AAC1C,OAAO,EAAC,gBAAgB,EAAC,oCAA2B;AAEpD,wCAA+B;AAC/B,yCAAgC;AAChC,qCAA4B;AAC5B,uCAA8B;AAC9B,kCAAyB;AACzB,qCAA4B;AAC5B,mCAA0B;AAC1B,uCAA8B;AAC9B,yCAAgC;AAChC,qCAA4B;AAC5B,4CAAmC;AACnC,uCAA8B;AAC9B,4CAAmC;AAanC,MAAM,CAAC,MAAM,cAAc,GAAyC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAClF,OAAO;SACF,GAAG,CAAC,SAAS,CAAC;SACd,GAAG,CAAC,WAAW,CAAC;SAChB,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;SACxC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;SAC9B,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;SAChC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;SACpC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,aAAa,CAAC;SAC/C,GAAG,CAAC,gBAAgB,CAAC;SACrB,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["import type {ExtensionAuto} from '../../core';\nimport type {PlaceholderOptions} from '../../utils/placeholder';\n\nimport {ClicksOnEdges} from './ClicksOnEdges';\nimport {Clipboard, type ClipboardOptions} from './Clipboard';\nimport {CommandMenu, type CommandMenuOptions} from './CommandMenu';\nimport {Cursor, type CursorOptions} from './Cursor';\nimport {FilePaste} from './FilePaste';\nimport {History, type HistoryOptions} from './History';\nimport {Placeholder} from './Placeholder';\nimport {type ReactRenderer, ReactRendererExtension} from './ReactRenderer';\nimport {Selection} from './Selection';\nimport {SelectionContext, type SelectionContextOptions} from './SelectionContext';\nimport {SharedState} from './SharedState';\nimport {WidgetDecoration} from './WidgetDecoration';\n\nexport * from './Autocomplete';\nexport * from './ClicksOnEdges';\nexport * from './Clipboard';\nexport * from './CommandMenu';\nexport * from './Cursor';\nexport * from './FilePaste';\nexport * from './History';\nexport * from './Placeholder';\nexport * from './ReactRenderer';\nexport * from './Selection';\nexport * from './SelectionContext';\nexport * from './SharedState';\nexport * from './WidgetDecoration';\n\nexport type BehaviorPresetOptions = {\n cursor?: CursorOptions;\n history?: HistoryOptions;\n clipboard?: ClipboardOptions;\n placeholder?: PlaceholderOptions;\n reactRenderer: ReactRenderer;\n selectionContext?: SelectionContextOptions;\n\n commandMenu?: CommandMenuOptions;\n};\n\nexport const BehaviorPreset: ExtensionAuto<BehaviorPresetOptions> = (builder, opts) => {\n builder\n .use(Selection)\n .use(SharedState)\n .use(Placeholder, opts.placeholder ?? {})\n .use(Cursor, opts.cursor ?? {})\n .use(History, opts.history ?? {})\n .use(Clipboard, opts.clipboard ?? {})\n .use(ReactRendererExtension, opts.reactRenderer)\n .use(WidgetDecoration)\n .use(SelectionContext, opts.selectionContext ?? {});\n\n if (opts.commandMenu) builder.use(CommandMenu, opts.commandMenu);\n builder.use(FilePaste);\n builder.use(ClicksOnEdges);\n};\n"]}
@@ -8,7 +8,6 @@ export declare class EmojiHandler implements AutocompleteHandler {
8
8
  private _emojiCarousel?;
9
9
  private _view?;
10
10
  private _anchor;
11
- private _range?;
12
11
  private _popupCloser?;
13
12
  private _suggestProps?;
14
13
  private _suggestRenderItem?;
@@ -1,7 +1,7 @@
1
1
  import { AutocompletePopupCloser } from "../../../../utils/autocomplete-popup.js";
2
2
  import { ArrayCarousel } from "../../../../utils/carousel/index.js";
3
3
  import { getReactRendererFromState } from "../../../behavior/index.js";
4
- import { AutocompleteActionKind, closeAutocomplete, } from "../../../behavior/Autocomplete/index.js";
4
+ import { AutocompleteActionKind, closeAutocomplete, getAutocompleteState, } from "../../../behavior/Autocomplete/index.js";
5
5
  import { EmojiConsts } from "../EmojiSpecs/index.js";
6
6
  import { render } from "./EmojiSuggestComponent.js";
7
7
  import { findDecoElem } from "./utils.js";
@@ -11,7 +11,6 @@ export class EmojiHandler {
11
11
  _emojiCarousel;
12
12
  _view;
13
13
  _anchor = null;
14
- _range;
15
14
  _popupCloser;
16
15
  _suggestProps;
17
16
  _suggestRenderItem;
@@ -89,12 +88,16 @@ export class EmojiHandler {
89
88
  });
90
89
  }
91
90
  select() {
92
- const { _view: view, _range: range } = this;
93
- if (!view || !range)
91
+ const { _view: view } = this;
92
+ if (!view)
94
93
  return;
95
94
  const emojiDef = this._emojiCarousel?.currentItem;
96
95
  if (!emojiDef)
97
96
  return;
97
+ const autocompleteState = getAutocompleteState(view.state);
98
+ if (!autocompleteState || !autocompleteState.active)
99
+ return;
100
+ const { range } = autocompleteState;
98
101
  const { tr, schema } = view.state;
99
102
  view.dispatch(tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView());
100
103
  view.focus();
@@ -136,13 +139,11 @@ export class EmojiHandler {
136
139
  }
137
140
  this._view?.focus();
138
141
  };
139
- updateState({ view, range }) {
142
+ updateState({ view }) {
140
143
  this._view = view;
141
- this._range = range;
142
144
  }
143
145
  clear() {
144
146
  this._view = undefined;
145
- this._range = undefined;
146
147
  this._anchor = null;
147
148
  this._emojiCarousel = undefined;
148
149
  this._popupCloser?.cancelTimer();
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n type FromTo,\n closeAutocomplete,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _range?: FromTo;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view, _range: range} = this;\n if (!view || !range) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view, range}: AutocompleteAction) {\n this._view = view;\n this._range = range;\n }\n\n private clear() {\n this._view = undefined;\n this._range = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
1
+ {"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n closeAutocomplete,\n getAutocompleteState,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view} = this;\n if (!view) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const autocompleteState = getAutocompleteState(view.state);\n if (!autocompleteState || !autocompleteState.active) return;\n\n const {range} = autocompleteState;\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view}: AutocompleteAction) {\n this._view = view;\n }\n\n private clear() {\n this._view = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
@@ -3,4 +3,5 @@ export * from "./hooks.js";
3
3
  export * from "./react-node-view.js";
4
4
  export * from "./useNodeEditing.js";
5
5
  export * from "./useNodeHovered.js";
6
+ export * from "./useSharedEditingState.js";
6
7
  export * from "./useSticky.js";
@@ -3,5 +3,6 @@ export * from "./hooks.js";
3
3
  export * from "./react-node-view.js";
4
4
  export * from "./useNodeEditing.js";
5
5
  export * from "./useNodeHovered.js";
6
+ export * from "./useSharedEditingState.js";
6
7
  export * from "./useSticky.js";
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["react-utils/index.ts"],"names":[],"mappings":"AAAA,mCAAgC;AAChC,2BAAwB;AACxB,qCAAkC;AAClC,oCAAiC;AACjC,oCAAiC;AACjC,+BAA4B","sourcesContent":["export * from './ErrorBoundary';\nexport * from './hooks';\nexport * from './react-node-view';\nexport * from './useNodeEditing';\nexport * from './useNodeHovered';\nexport * from './useSticky';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["react-utils/index.ts"],"names":[],"mappings":"AAAA,mCAAgC;AAChC,2BAAwB;AACxB,qCAAkC;AAClC,oCAAiC;AACjC,oCAAiC;AACjC,2CAAwC;AACxC,+BAA4B","sourcesContent":["export * from './ErrorBoundary';\nexport * from './hooks';\nexport * from './react-node-view';\nexport * from './useNodeEditing';\nexport * from './useNodeHovered';\nexport * from './useSharedEditingState';\nexport * from './useSticky';\n"]}
@@ -0,0 +1,5 @@
1
+ import type { EditorView } from "../pm/view.js";
2
+ import type { SharedStateKey } from "../extensions/behavior/SharedState/index.js";
3
+ export declare function useSharedEditingState(view: EditorView, key: SharedStateKey<{
4
+ editing: boolean;
5
+ }>): readonly [Boolean, () => void, () => void, () => void];
@@ -0,0 +1,22 @@
1
+ import { useLayoutEffect, useMemo, useState } from 'react';
2
+ import { useLatest } from 'react-use';
3
+ export function useSharedEditingState(view, key) {
4
+ const [value, setValue] = useState(false);
5
+ const valueRef = useLatest(value);
6
+ useLayoutEffect(() => {
7
+ setValue(key.getValue(view.state)?.editing || false);
8
+ return key.getNotifier(view.state).subscribe((data) => setValue(data?.editing || false));
9
+ }, [key, view]);
10
+ const { set, unset, toggle } = useMemo(() => {
11
+ const dispatch = (value) => {
12
+ view.dispatch(key.appendTransaction.update(view.state.tr, { editing: value }));
13
+ };
14
+ return {
15
+ set: () => dispatch(true),
16
+ unset: () => dispatch(false),
17
+ toggle: () => dispatch(!valueRef.current),
18
+ };
19
+ }, [key, view, valueRef]);
20
+ return [value, set, unset, toggle];
21
+ }
22
+ //# sourceMappingURL=useSharedEditingState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSharedEditingState.js","sourceRoot":"../../../src","sources":["react-utils/useSharedEditingState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AAKpC,MAAM,UAAU,qBAAqB,CAAC,IAAgB,EAAE,GAAuC;IAC3F,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAElC,eAAe,CAAC,GAAG,EAAE;QACjB,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC;IAC7F,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAEhB,MAAM,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE;QACtC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAE,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;QACjF,CAAC,CAAC;QACF,OAAO;YACH,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACzB,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC5B,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC5C,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1B,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAChD,CAAC","sourcesContent":["import {useLayoutEffect, useMemo, useState} from 'react';\n\nimport {useLatest} from 'react-use';\n\nimport type {EditorView} from '#pm/view';\nimport type {SharedStateKey} from 'src/extensions/behavior/SharedState';\n\nexport function useSharedEditingState(view: EditorView, key: SharedStateKey<{editing: boolean}>) {\n const [value, setValue] = useState<Boolean>(false);\n const valueRef = useLatest(value);\n\n useLayoutEffect(() => {\n setValue(key.getValue(view.state)?.editing || false);\n return key.getNotifier(view.state).subscribe((data) => setValue(data?.editing || false));\n }, [key, view]);\n\n const {set, unset, toggle} = useMemo(() => {\n const dispatch = (value: boolean) => {\n view.dispatch(key.appendTransaction.update(view.state.tr, {editing: value}));\n };\n return {\n set: () => dispatch(true),\n unset: () => dispatch(false),\n toggle: () => dispatch(!valueRef.current),\n };\n }, [key, view, valueRef]);\n\n return [value, set, unset, toggle] as const;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { Node } from "../pm/model.js";
2
+ export type FindDescedantItem = {
3
+ node: Node;
4
+ pos: number;
5
+ index: number;
6
+ parent: Node | null;
7
+ };
8
+ export declare function findFirstDescedantNode(doc: Node, predicate: (node: Node) => boolean): FindDescedantItem | null;
@@ -0,0 +1,12 @@
1
+ export function findFirstDescedantNode(doc, predicate) {
2
+ let found = null;
3
+ doc.descendants((node, pos, parent, index) => {
4
+ if (found)
5
+ return false;
6
+ if (predicate(node))
7
+ found = { node, pos, parent, index };
8
+ return true;
9
+ });
10
+ return found;
11
+ }
12
+ //# sourceMappingURL=descedants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descedants.js","sourceRoot":"../../../src","sources":["utils/descedants.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,sBAAsB,CAClC,GAAS,EACT,SAAkC;IAElC,IAAI,KAAK,GAA6B,IAAI,CAAC;IAE3C,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QACzC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,IAAI,SAAS,CAAC,IAAI,CAAC;YAAE,KAAK,GAAG,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC;QAExD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import type {Node} from '#pm/model';\n\nexport type FindDescedantItem = {\n node: Node;\n pos: number;\n index: number;\n parent: Node | null;\n};\n\nexport function findFirstDescedantNode(\n doc: Node,\n predicate: (node: Node) => boolean,\n): FindDescedantItem | null {\n let found: FindDescedantItem | null = null;\n\n doc.descendants((node, pos, parent, index) => {\n if (found) return false;\n\n if (predicate(node)) found = {node, pos, parent, index};\n\n return true;\n });\n\n return found;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { Node } from "../pm/model.js";
2
+ export declare const entityIdAttr = "data-entity-id";
3
+ export declare function generateEntityId(name?: string): string;
4
+ /**
5
+ * Returns true when entityId is not set, is set to default value, or is duplicated (other node already has this entityId)
6
+ */
7
+ export declare function isInvalidEntityId({ doc, node, defaultId, }: {
8
+ doc: Node;
9
+ node: Node;
10
+ defaultId: string;
11
+ }): boolean;
@@ -0,0 +1,16 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { findFirstDescedantNode } from "./descedants.js";
3
+ export const entityIdAttr = 'data-entity-id';
4
+ export function generateEntityId(name = 'entity') {
5
+ return name + '-' + uuidv4();
6
+ }
7
+ /**
8
+ * Returns true when entityId is not set, is set to default value, or is duplicated (other node already has this entityId)
9
+ */
10
+ export function isInvalidEntityId({ doc, node, defaultId, }) {
11
+ const entityId = node.attrs[entityIdAttr];
12
+ if (!entityId || entityId === defaultId)
13
+ return true;
14
+ return Boolean(findFirstDescedantNode(doc, (dNode) => node !== dNode && dNode.attrs[entityIdAttr] === entityId));
15
+ }
16
+ //# sourceMappingURL=entity-id.js.map