@gravity-ui/markdown-editor 15.29.0 → 15.30.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 (96) hide show
  1. package/build/cjs/core/types/serializer.d.ts +5 -0
  2. package/build/cjs/core/types/serializer.js.map +1 -1
  3. package/build/cjs/extensions/behavior/Search/SearchViewPlugin.js +24 -0
  4. package/build/cjs/extensions/behavior/Search/SearchViewPlugin.js.map +1 -1
  5. package/build/cjs/extensions/markdown/Breaks/index.d.ts +2 -0
  6. package/build/cjs/extensions/markdown/Breaks/index.js +7 -4
  7. package/build/cjs/extensions/markdown/Breaks/index.js.map +1 -1
  8. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +3 -0
  9. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.js +5 -1
  10. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.js.map +1 -1
  11. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +2 -6
  12. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
  13. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js.map +1 -1
  14. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/parser.js +27 -1
  15. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/parser.js.map +1 -1
  16. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +8 -2
  17. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +3 -1
  18. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.js.map +1 -1
  19. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +14 -2
  20. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js.map +1 -1
  21. package/build/cjs/extensions/yfm/Checkbox/index.css +5 -9
  22. package/build/cjs/extensions/yfm/Checkbox/index.d.ts +8 -1
  23. package/build/cjs/extensions/yfm/Checkbox/index.js +1 -1
  24. package/build/cjs/extensions/yfm/Checkbox/index.js.map +1 -1
  25. package/build/cjs/extensions/yfm/Checkbox/plugin.d.ts +5 -1
  26. package/build/cjs/extensions/yfm/Checkbox/plugin.js +8 -3
  27. package/build/cjs/extensions/yfm/Checkbox/plugin.js.map +1 -1
  28. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +5 -1
  29. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  30. package/build/cjs/markup/codemirror/search-plugin/plugin.js +10 -0
  31. package/build/cjs/markup/codemirror/search-plugin/plugin.js.map +1 -1
  32. package/build/cjs/modules/search/components/SearchPopup.d.ts +2 -0
  33. package/build/cjs/modules/search/components/SearchPopup.js +11 -2
  34. package/build/cjs/modules/search/components/SearchPopup.js.map +1 -1
  35. package/build/cjs/modules/search/components/hooks/useObserveIntersection.d.ts +10 -0
  36. package/build/cjs/modules/search/components/hooks/useObserveIntersection.js +44 -0
  37. package/build/cjs/modules/search/components/hooks/useObserveIntersection.js.map +1 -0
  38. package/build/cjs/react-utils/hooks/useRAF.d.ts +1 -0
  39. package/build/cjs/react-utils/hooks/useRAF.js +24 -0
  40. package/build/cjs/react-utils/hooks/useRAF.js.map +1 -0
  41. package/build/cjs/react-utils/useSticky.js +3 -12
  42. package/build/cjs/react-utils/useSticky.js.map +1 -1
  43. package/build/cjs/utils/dom.d.ts +3 -0
  44. package/build/cjs/utils/dom.js +32 -0
  45. package/build/cjs/utils/dom.js.map +1 -0
  46. package/build/cjs/version.js +1 -1
  47. package/build/cjs/version.js.map +1 -1
  48. package/build/esm/core/types/serializer.d.ts +5 -0
  49. package/build/esm/core/types/serializer.js.map +1 -1
  50. package/build/esm/extensions/behavior/Search/SearchViewPlugin.js +25 -1
  51. package/build/esm/extensions/behavior/Search/SearchViewPlugin.js.map +1 -1
  52. package/build/esm/extensions/markdown/Breaks/index.d.ts +2 -0
  53. package/build/esm/extensions/markdown/Breaks/index.js +7 -5
  54. package/build/esm/extensions/markdown/Breaks/index.js.map +1 -1
  55. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +3 -0
  56. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.js +4 -0
  57. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.js.map +1 -1
  58. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +2 -6
  59. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
  60. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js.map +1 -1
  61. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/parser.js +28 -2
  62. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/parser.js.map +1 -1
  63. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +8 -2
  64. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +3 -1
  65. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.js.map +1 -1
  66. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +14 -2
  67. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js.map +1 -1
  68. package/build/esm/extensions/yfm/Checkbox/index.css +5 -9
  69. package/build/esm/extensions/yfm/Checkbox/index.d.ts +8 -1
  70. package/build/esm/extensions/yfm/Checkbox/index.js +1 -1
  71. package/build/esm/extensions/yfm/Checkbox/index.js.map +1 -1
  72. package/build/esm/extensions/yfm/Checkbox/plugin.d.ts +5 -1
  73. package/build/esm/extensions/yfm/Checkbox/plugin.js +8 -3
  74. package/build/esm/extensions/yfm/Checkbox/plugin.js.map +1 -1
  75. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +5 -1
  76. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  77. package/build/esm/markup/codemirror/search-plugin/plugin.js +10 -0
  78. package/build/esm/markup/codemirror/search-plugin/plugin.js.map +1 -1
  79. package/build/esm/modules/search/components/SearchPopup.d.ts +2 -0
  80. package/build/esm/modules/search/components/SearchPopup.js +11 -2
  81. package/build/esm/modules/search/components/SearchPopup.js.map +1 -1
  82. package/build/esm/modules/search/components/hooks/useObserveIntersection.d.ts +10 -0
  83. package/build/esm/modules/search/components/hooks/useObserveIntersection.js +41 -0
  84. package/build/esm/modules/search/components/hooks/useObserveIntersection.js.map +1 -0
  85. package/build/esm/react-utils/hooks/useRAF.d.ts +1 -0
  86. package/build/esm/react-utils/hooks/useRAF.js +21 -0
  87. package/build/esm/react-utils/hooks/useRAF.js.map +1 -0
  88. package/build/esm/react-utils/useSticky.js +3 -12
  89. package/build/esm/react-utils/useSticky.js.map +1 -1
  90. package/build/esm/utils/dom.d.ts +3 -0
  91. package/build/esm/utils/dom.js +27 -0
  92. package/build/esm/utils/dom.js.map +1 -0
  93. package/build/esm/version.js +1 -1
  94. package/build/esm/version.js.map +1 -1
  95. package/build/styles.css +5 -9
  96. package/package.json +3 -3
@@ -3,5 +3,10 @@ declare module 'prosemirror-model' {
3
3
  interface NodeSpec {
4
4
  /** Default false */
5
5
  isBreak?: boolean;
6
+ /**
7
+ * For non default textblocks.
8
+ * Set true if textblock can contain line breaks (soft-break or/and hard-break).
9
+ */
10
+ canContainBreaks?: boolean;
6
11
  }
7
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.js","sourceRoot":"../../../../src","sources":["core/types/serializer.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MarkdownSerializerState as SerializerState,\n SerializerNodeToken,\n SerializerMarkToken,\n MarkdownSerializer as Serializer,\n} from '../markdown/MarkdownSerializer';\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Default false */\n isBreak?: boolean;\n }\n}\n"]}
1
+ {"version":3,"file":"serializer.js","sourceRoot":"../../../../src","sources":["core/types/serializer.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MarkdownSerializerState as SerializerState,\n SerializerNodeToken,\n SerializerMarkToken,\n MarkdownSerializer as Serializer,\n} from '../markdown/MarkdownSerializer';\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Default false */\n isBreak?: boolean;\n /**\n * For non default textblocks.\n * Set true if textblock can contain line breaks (soft-break or/and hard-break).\n */\n canContainBreaks?: boolean;\n }\n}\n"]}
@@ -5,6 +5,7 @@ const prosemirror_search_1 = require("prosemirror-search");
5
5
  const state_1 = require("../../../pm/state.js");
6
6
  const utils_1 = require("../../../pm/utils.js");
7
7
  const search_1 = require("../../../modules/search/index.js");
8
+ const dom_1 = require("../../../utils/dom.js");
8
9
  const ReactRenderer_1 = require("../ReactRenderer/index.js");
9
10
  const commands_1 = require("./commands.js");
10
11
  const const_1 = require("./const.js");
@@ -102,6 +103,16 @@ class SeachPluginView {
102
103
  onSearchNext: this._onSearchNext,
103
104
  onReplaceNext: this._onReplaceNext,
104
105
  onReplaceAll: this._onReplaceAll,
106
+ intersectionTracking: {
107
+ container: this._view.dom,
108
+ selector: `.${const_1.SearchClassName.ActiveMatch}`,
109
+ observerOptions: {
110
+ childList: true,
111
+ subtree: true,
112
+ attributes: true,
113
+ attributeFilter: ['class'],
114
+ },
115
+ },
105
116
  });
106
117
  });
107
118
  }
@@ -137,9 +148,11 @@ class SeachPluginView {
137
148
  };
138
149
  _onSearchPrev = () => {
139
150
  this._preserveFocus(commands_1.findPrev);
151
+ requestAnimationFrame(() => this._scrollToActiveIfNeeded());
140
152
  };
141
153
  _onSearchNext = () => {
142
154
  this._preserveFocus(commands_1.findNext);
155
+ requestAnimationFrame(() => this._scrollToActiveIfNeeded());
143
156
  };
144
157
  _onReplaceNext = () => {
145
158
  this._preserveFocus(commands_1.replaceNext);
@@ -153,5 +166,16 @@ class SeachPluginView {
153
166
  command(this._view.state, this._view.dispatch, this._view);
154
167
  this._focusManager.restoreFocus({ preventScroll: true });
155
168
  }
169
+ _scrollToActiveIfNeeded = () => {
170
+ const activeElem = this._view.dom
171
+ .getElementsByClassName(const_1.SearchClassName.ActiveMatch)
172
+ .item(0);
173
+ if (activeElem && !(0, dom_1.isElementInViewport)(activeElem)) {
174
+ activeElem.scrollIntoView({
175
+ block: 'nearest',
176
+ inline: 'nearest',
177
+ });
178
+ }
179
+ };
156
180
  }
157
181
  //# sourceMappingURL=SearchViewPlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchViewPlugin.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Search/SearchViewPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {SearchQuery, type SearchResult, getSearchState, setSearchState} from 'prosemirror-search';\n\nimport type {Node} from '#pm/model';\nimport {type Command, Plugin, type PluginView, TextSelection} from '#pm/state';\nimport {findParentNodeClosestToPos} from '#pm/utils';\nimport type {EditorView} from '#pm/view';\nimport {type SearchCounter, type SearchState, renderSearchPopup} from 'src/modules/search';\n\nimport {getReactRendererFromState} from '../ReactRenderer';\n\nimport {closeSearch, findNext, findPrev, replaceAll, replaceNext} from './commands';\nimport {pluginKey} from './const';\nimport {searchKeyHandler} from './key-handler';\nimport type {SearchViewState} from './types';\nimport {startTracking} from './utils/connect-tracker';\nimport {FocusManager} from './utils/focus-manager';\nimport {getCounter} from './utils/search-counter';\n\nimport './search-plugin.scss';\n\nexport interface SearchViewPluginParams {\n anchorSelector: string;\n}\n\nexport const searchViewPlugin = (params: SearchViewPluginParams) => {\n return new Plugin<SearchViewState>({\n key: pluginKey,\n props: {\n handleKeyDown: searchKeyHandler,\n },\n state: {\n init: () => ({open: false}),\n apply(tr, value, _oldState, _newState) {\n const newValue = tr.getMeta(pluginKey) as SearchViewState | undefined;\n if (typeof newValue === 'object') return newValue;\n return value;\n },\n },\n view(view) {\n return new SeachPluginView(view, params);\n },\n });\n};\n\nclass SeachPluginView implements PluginView {\n private readonly _view: EditorView;\n private readonly _renderer;\n private readonly _focusManager: FocusManager;\n private readonly _viewDomTrackerDispose;\n\n private _counter: SearchCounter;\n private _isDomConnected: boolean;\n private _viewState: SearchViewState | undefined;\n private _searchState: SearchQuery | undefined;\n\n constructor(view: EditorView, params: SearchViewPluginParams) {\n this._view = view;\n this._viewState = pluginKey.getState(view.state);\n this._searchState = getSearchState(view.state)?.query;\n this._counter = getCounter(view.state);\n this._isDomConnected = view.dom.ownerDocument.contains(view.dom);\n\n this._renderer = this._createRenderer(params);\n this._focusManager = new FocusManager(view.dom.ownerDocument);\n\n // uses MutationObserver to detect when view.dom is disconnected from the DOM tree\n // TODO: replace with eventBus (subscribe to change-editor-mode event) to track when to hide the search bar\n // see https://github.com/gravity-ui/markdown-editor/issues/884\n this._viewDomTrackerDispose = startTracking(view.dom, {\n onConnect: this._onEditorViewDomConnected,\n onDisconnect: this._onEditorViewDomDisconnected,\n });\n }\n\n update() {\n const newCounter = getCounter(this._view.state);\n const newViewState = pluginKey.getState(this._view.state);\n const newSearchState = getSearchState(this._view.state)?.query;\n\n if (\n newViewState !== this._viewState ||\n newSearchState !== this._searchState ||\n newCounter.total !== this._counter.total ||\n newCounter.current !== this._counter.current\n ) {\n this._counter = newCounter;\n this._viewState = newViewState;\n this._searchState = newSearchState;\n this._renderer.rerender();\n }\n }\n\n destroy() {\n this._renderer.remove();\n this._viewDomTrackerDispose();\n }\n\n private _onEditorViewDomConnected = () => {\n this._isDomConnected = true;\n this._renderer.rerender();\n };\n\n private _onEditorViewDomDisconnected = () => {\n this._isDomConnected = false;\n this._onClose();\n };\n\n private _createRenderer(params: Pick<SearchViewPluginParams, 'anchorSelector'>) {\n return getReactRendererFromState(this._view.state).createItem('search-view', () => {\n const {\n _viewState: viewState,\n _searchState: searchState,\n _isDomConnected: domConnected,\n } = this;\n\n if (!domConnected || !viewState?.open || !searchState) return null;\n\n const anchor = this._view.dom.ownerDocument.querySelector(params.anchorSelector);\n\n return renderSearchPopup({\n anchor,\n open: viewState.open,\n counter: this._counter,\n state: searchState,\n onClose: this._onClose,\n onChange: this._onChange,\n onSearchPrev: this._onSearchPrev,\n onSearchNext: this._onSearchNext,\n onReplaceNext: this._onReplaceNext,\n onReplaceAll: this._onReplaceAll,\n });\n });\n }\n\n private _onChange = (config: SearchState) => {\n const {state, dispatch} = this._view;\n\n const query = new SearchQuery({\n search: config.search,\n replace: config.replace,\n caseSensitive: config.caseSensitive,\n wholeWord: config.wholeWord,\n });\n\n const tr = setSearchState(state.tr, query);\n const {$from, $to} = tr.selection;\n const parent = findParentNodeClosestToPos($from, (node: Node) => node.type.isTextblock);\n\n let result: SearchResult | null = null;\n // find match in [sel.$from, parent.$end]\n if (parent) result = query.findNext(state, $from.pos, parent.pos + parent.node.nodeSize);\n // find match in [parent.$start or sel.$from, doc.$end]\n if (!result) result = query.findNext(state, parent?.pos || $from.pos);\n // find match in [doc.$start, parent.$start or sel.$to]\n if (!result) result = query.findPrev(state, parent?.pos || $to.pos);\n // update text selection\n if (result) tr.setSelection(TextSelection.create(tr.doc, result.from, result.to));\n\n dispatch(tr);\n };\n\n private _onClose = () => {\n closeSearch(this._view.state, this._view.dispatch);\n this._view.focus();\n };\n\n private _onSearchPrev = () => {\n this._preserveFocus(findPrev);\n };\n\n private _onSearchNext = () => {\n this._preserveFocus(findNext);\n };\n\n private _onReplaceNext = () => {\n this._preserveFocus(replaceNext);\n };\n\n private _onReplaceAll = () => {\n this._preserveFocus(replaceAll);\n };\n\n private _preserveFocus(command: Command) {\n this._focusManager.storeFocus();\n this._view.focus();\n command(this._view.state, this._view.dispatch, this._view);\n this._focusManager.restoreFocus({preventScroll: true});\n }\n}\n"]}
1
+ {"version":3,"file":"SearchViewPlugin.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Search/SearchViewPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {SearchQuery, type SearchResult, getSearchState, setSearchState} from 'prosemirror-search';\n\nimport type {Node} from '#pm/model';\nimport {type Command, Plugin, type PluginView, TextSelection} from '#pm/state';\nimport {findParentNodeClosestToPos} from '#pm/utils';\nimport type {EditorView} from '#pm/view';\nimport {type SearchCounter, type SearchState, renderSearchPopup} from 'src/modules/search';\nimport {isElementInViewport} from 'src/utils/dom';\n\nimport {getReactRendererFromState} from '../ReactRenderer';\n\nimport {closeSearch, findNext, findPrev, replaceAll, replaceNext} from './commands';\nimport {SearchClassName, pluginKey} from './const';\nimport {searchKeyHandler} from './key-handler';\nimport type {SearchViewState} from './types';\nimport {startTracking} from './utils/connect-tracker';\nimport {FocusManager} from './utils/focus-manager';\nimport {getCounter} from './utils/search-counter';\n\nimport './search-plugin.scss';\n\nexport interface SearchViewPluginParams {\n anchorSelector: string;\n}\n\nexport const searchViewPlugin = (params: SearchViewPluginParams) => {\n return new Plugin<SearchViewState>({\n key: pluginKey,\n props: {\n handleKeyDown: searchKeyHandler,\n },\n state: {\n init: () => ({open: false}),\n apply(tr, value, _oldState, _newState) {\n const newValue = tr.getMeta(pluginKey) as SearchViewState | undefined;\n if (typeof newValue === 'object') return newValue;\n return value;\n },\n },\n view(view) {\n return new SeachPluginView(view, params);\n },\n });\n};\n\nclass SeachPluginView implements PluginView {\n private readonly _view: EditorView;\n private readonly _renderer;\n private readonly _focusManager: FocusManager;\n private readonly _viewDomTrackerDispose;\n\n private _counter: SearchCounter;\n private _isDomConnected: boolean;\n private _viewState: SearchViewState | undefined;\n private _searchState: SearchQuery | undefined;\n\n constructor(view: EditorView, params: SearchViewPluginParams) {\n this._view = view;\n this._viewState = pluginKey.getState(view.state);\n this._searchState = getSearchState(view.state)?.query;\n this._counter = getCounter(view.state);\n this._isDomConnected = view.dom.ownerDocument.contains(view.dom);\n\n this._renderer = this._createRenderer(params);\n this._focusManager = new FocusManager(view.dom.ownerDocument);\n\n // uses MutationObserver to detect when view.dom is disconnected from the DOM tree\n // TODO: replace with eventBus (subscribe to change-editor-mode event) to track when to hide the search bar\n // see https://github.com/gravity-ui/markdown-editor/issues/884\n this._viewDomTrackerDispose = startTracking(view.dom, {\n onConnect: this._onEditorViewDomConnected,\n onDisconnect: this._onEditorViewDomDisconnected,\n });\n }\n\n update() {\n const newCounter = getCounter(this._view.state);\n const newViewState = pluginKey.getState(this._view.state);\n const newSearchState = getSearchState(this._view.state)?.query;\n\n if (\n newViewState !== this._viewState ||\n newSearchState !== this._searchState ||\n newCounter.total !== this._counter.total ||\n newCounter.current !== this._counter.current\n ) {\n this._counter = newCounter;\n this._viewState = newViewState;\n this._searchState = newSearchState;\n this._renderer.rerender();\n }\n }\n\n destroy() {\n this._renderer.remove();\n this._viewDomTrackerDispose();\n }\n\n private _onEditorViewDomConnected = () => {\n this._isDomConnected = true;\n this._renderer.rerender();\n };\n\n private _onEditorViewDomDisconnected = () => {\n this._isDomConnected = false;\n this._onClose();\n };\n\n private _createRenderer(params: Pick<SearchViewPluginParams, 'anchorSelector'>) {\n return getReactRendererFromState(this._view.state).createItem('search-view', () => {\n const {\n _viewState: viewState,\n _searchState: searchState,\n _isDomConnected: domConnected,\n } = this;\n\n if (!domConnected || !viewState?.open || !searchState) return null;\n\n const anchor = this._view.dom.ownerDocument.querySelector(params.anchorSelector);\n\n return renderSearchPopup({\n anchor,\n open: viewState.open,\n counter: this._counter,\n state: searchState,\n onClose: this._onClose,\n onChange: this._onChange,\n onSearchPrev: this._onSearchPrev,\n onSearchNext: this._onSearchNext,\n onReplaceNext: this._onReplaceNext,\n onReplaceAll: this._onReplaceAll,\n intersectionTracking: {\n container: this._view.dom,\n selector: `.${SearchClassName.ActiveMatch}`,\n observerOptions: {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n },\n },\n });\n });\n }\n\n private _onChange = (config: SearchState) => {\n const {state, dispatch} = this._view;\n\n const query = new SearchQuery({\n search: config.search,\n replace: config.replace,\n caseSensitive: config.caseSensitive,\n wholeWord: config.wholeWord,\n });\n\n const tr = setSearchState(state.tr, query);\n const {$from, $to} = tr.selection;\n const parent = findParentNodeClosestToPos($from, (node: Node) => node.type.isTextblock);\n\n let result: SearchResult | null = null;\n // find match in [sel.$from, parent.$end]\n if (parent) result = query.findNext(state, $from.pos, parent.pos + parent.node.nodeSize);\n // find match in [parent.$start or sel.$from, doc.$end]\n if (!result) result = query.findNext(state, parent?.pos || $from.pos);\n // find match in [doc.$start, parent.$start or sel.$to]\n if (!result) result = query.findPrev(state, parent?.pos || $to.pos);\n // update text selection\n if (result) tr.setSelection(TextSelection.create(tr.doc, result.from, result.to));\n\n dispatch(tr);\n };\n\n private _onClose = () => {\n closeSearch(this._view.state, this._view.dispatch);\n this._view.focus();\n };\n\n private _onSearchPrev = () => {\n this._preserveFocus(findPrev);\n requestAnimationFrame(() => this._scrollToActiveIfNeeded());\n };\n\n private _onSearchNext = () => {\n this._preserveFocus(findNext);\n requestAnimationFrame(() => this._scrollToActiveIfNeeded());\n };\n\n private _onReplaceNext = () => {\n this._preserveFocus(replaceNext);\n };\n\n private _onReplaceAll = () => {\n this._preserveFocus(replaceAll);\n };\n\n private _preserveFocus(command: Command) {\n this._focusManager.storeFocus();\n this._view.focus();\n command(this._view.state, this._view.dispatch, this._view);\n this._focusManager.restoreFocus({preventScroll: true});\n }\n\n private _scrollToActiveIfNeeded = () => {\n const activeElem = this._view.dom\n .getElementsByClassName(SearchClassName.ActiveMatch)\n .item(0);\n\n if (activeElem && !isElementInViewport(activeElem)) {\n activeElem.scrollIntoView({\n block: 'nearest',\n inline: 'nearest',\n });\n }\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import type { Node } from 'prosemirror-model';
1
2
  import type { ExtensionAuto } from "../../../core/index.js";
2
3
  export { BreaksSpecs, BreakNodeName, hbType, sbType } from "./BreaksSpecs/index.js";
3
4
  export type BreaksOptions = {
@@ -18,3 +19,4 @@ declare global {
18
19
  }
19
20
  }
20
21
  }
22
+ export declare function isBreakNode(node: Node | null | undefined): boolean;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Breaks = exports.sbType = exports.hbType = exports.BreakNodeName = exports.BreaksSpecs = void 0;
4
+ exports.isBreakNode = isBreakNode;
4
5
  const prosemirror_commands_1 = require("prosemirror-commands");
5
6
  const prosemirror_state_1 = require("prosemirror-state");
6
7
  const logger_1 = require("../../../logger.js");
@@ -38,10 +39,7 @@ const Breaks = (builder, opts) => {
38
39
  exports.Breaks = Breaks;
39
40
  const addBr = (br) => (0, prosemirror_commands_1.chainCommands)(prosemirror_commands_1.exitCode, (state, dispatch) => {
40
41
  const { selection: sel, schema } = state;
41
- if (!(0, selection_1.isTextSelection)(sel) ||
42
- !sel.empty ||
43
- // breaks can only be in the paragraph
44
- sel.$cursor?.parent.type !== (0, BaseSchemaSpecs_1.pType)(schema))
42
+ if (!(0, selection_1.isTextSelection)(sel) || !sel.$cursor || !canContainBreaks(sel.$cursor.parent))
45
43
  return false;
46
44
  if (isBreakNode(sel.$cursor.nodeBefore)) {
47
45
  if (dispatch) {
@@ -63,6 +61,11 @@ const addBr = (br) => (0, prosemirror_commands_1.chainCommands)(prosemirror_comm
63
61
  dispatch?.(state.tr.replaceSelectionWith(br.create()).scrollIntoView());
64
62
  return true;
65
63
  });
64
+ function canContainBreaks(node) {
65
+ return (Boolean(node.type.spec.canContainBreaks) ||
66
+ // always allow breaks in paragraph
67
+ node.type === (0, BaseSchemaSpecs_1.pType)(node.type.schema));
68
+ }
66
69
  function isBreakNode(node) {
67
70
  return Boolean(node?.type.spec.isBreak);
68
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Breaks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {chainCommands, exitCode} from 'prosemirror-commands';\nimport type {Node, NodeType} from 'prosemirror-model';\nimport {TextSelection} from 'prosemirror-state';\n\nimport type {ExtensionAuto, Keymap} from '../../../core';\nimport {globalLogger} from '../../../logger';\nimport {isMac} from '../../../utils/platform';\nimport {isTextSelection} from '../../../utils/selection';\nimport {pType} from '../../base/BaseSchema/BaseSchemaSpecs';\n\nimport {BreaksSpecs, type BreaksSpecsOptions, hbType, sbType} from './BreaksSpecs';\n\nexport {BreaksSpecs, BreakNodeName, hbType, sbType} from './BreaksSpecs';\n\nexport type BreaksOptions = {\n /**\n * This option is used if the 'breaks' parameter is not specified via the context\n * @default 'hard'\n */\n // TODO: [context] make this deprecated\n preferredBreak?: 'hard' | 'soft';\n};\n\nexport const Breaks: ExtensionAuto<BreaksOptions> = (builder, opts) => {\n let preferredBreak: 'hard' | 'soft';\n if (builder.context.has('breaks')) {\n preferredBreak = builder.context.get('breaks') ? 'soft' : 'hard';\n } else {\n preferredBreak = opts.preferredBreak ?? 'hard';\n globalLogger.info(\n \"[Breaks extension]: Parameter 'breaks' is not defined in context; value from options is used\",\n );\n builder.logger.log(\n \"[Breaks extension]: Parameter 'breaks' is not defined in context; value from options is used\",\n );\n }\n\n builder.use<BreaksSpecsOptions>(BreaksSpecs, {preferredBreak});\n\n builder.addKeymap(({schema}) => {\n const cmd = addBr((preferredBreak === 'soft' ? sbType : hbType)(schema));\n const keys: Keymap = {\n 'Shift-Enter': cmd,\n };\n\n if (isMac()) {\n keys['Ctrl-Enter'] = cmd;\n }\n\n return keys;\n });\n};\n\nconst addBr = (br: NodeType) =>\n chainCommands(exitCode, (state, dispatch) => {\n const {selection: sel, schema} = state;\n if (\n !isTextSelection(sel) ||\n !sel.empty ||\n // breaks can only be in the paragraph\n sel.$cursor?.parent.type !== pType(schema)\n )\n return false;\n\n if (isBreakNode(sel.$cursor.nodeBefore)) {\n if (dispatch) {\n const {\n $cursor,\n $cursor: {pos},\n } = sel;\n const from = isBreakNode($cursor.nodeAfter) ? pos + 1 : pos;\n const posEnd = $cursor.end();\n const posAfter = $cursor.after();\n\n const contentAfter = state.doc.slice(from, posEnd, false).content;\n\n let tr = state.tr.insert(posAfter, pType(schema).create(null, contentAfter));\n tr = tr\n .setSelection(TextSelection.create(tr.doc, posAfter + 1))\n .scrollIntoView()\n .delete(pos, posEnd) // remove content after current pos (it's moved to next para)\n .delete(pos - 1, pos); // remove break before current pos ($cursor.nodeBefore)\n dispatch(tr);\n }\n return true;\n }\n\n dispatch?.(state.tr.replaceSelectionWith(br.create()).scrollIntoView());\n return true;\n });\n\ndeclare global {\n namespace WysiwygEditor {\n interface Context {\n /**\n * Same as @type {MarkdownIt.Options.breaks}\n */\n breaks: boolean;\n }\n }\n}\n\nfunction isBreakNode(node?: Node | null | undefined): boolean {\n return Boolean(node?.type.spec.isBreak);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Breaks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {chainCommands, exitCode} from 'prosemirror-commands';\nimport type {Node, NodeType} from 'prosemirror-model';\nimport {TextSelection} from 'prosemirror-state';\n\nimport type {ExtensionAuto, Keymap} from '../../../core';\nimport {globalLogger} from '../../../logger';\nimport {isMac} from '../../../utils/platform';\nimport {isTextSelection} from '../../../utils/selection';\nimport {pType} from '../../base/BaseSchema/BaseSchemaSpecs';\n\nimport {BreaksSpecs, type BreaksSpecsOptions, hbType, sbType} from './BreaksSpecs';\n\nexport {BreaksSpecs, BreakNodeName, hbType, sbType} from './BreaksSpecs';\n\nexport type BreaksOptions = {\n /**\n * This option is used if the 'breaks' parameter is not specified via the context\n * @default 'hard'\n */\n // TODO: [context] make this deprecated\n preferredBreak?: 'hard' | 'soft';\n};\n\nexport const Breaks: ExtensionAuto<BreaksOptions> = (builder, opts) => {\n let preferredBreak: 'hard' | 'soft';\n if (builder.context.has('breaks')) {\n preferredBreak = builder.context.get('breaks') ? 'soft' : 'hard';\n } else {\n preferredBreak = opts.preferredBreak ?? 'hard';\n globalLogger.info(\n \"[Breaks extension]: Parameter 'breaks' is not defined in context; value from options is used\",\n );\n builder.logger.log(\n \"[Breaks extension]: Parameter 'breaks' is not defined in context; value from options is used\",\n );\n }\n\n builder.use<BreaksSpecsOptions>(BreaksSpecs, {preferredBreak});\n\n builder.addKeymap(({schema}) => {\n const cmd = addBr((preferredBreak === 'soft' ? sbType : hbType)(schema));\n const keys: Keymap = {\n 'Shift-Enter': cmd,\n };\n\n if (isMac()) {\n keys['Ctrl-Enter'] = cmd;\n }\n\n return keys;\n });\n};\n\nconst addBr = (br: NodeType) =>\n chainCommands(exitCode, (state, dispatch) => {\n const {selection: sel, schema} = state;\n if (!isTextSelection(sel) || !sel.$cursor || !canContainBreaks(sel.$cursor.parent))\n return false;\n\n if (isBreakNode(sel.$cursor.nodeBefore)) {\n if (dispatch) {\n const {\n $cursor,\n $cursor: {pos},\n } = sel;\n const from = isBreakNode($cursor.nodeAfter) ? pos + 1 : pos;\n const posEnd = $cursor.end();\n const posAfter = $cursor.after();\n\n const contentAfter = state.doc.slice(from, posEnd, false).content;\n\n let tr = state.tr.insert(posAfter, pType(schema).create(null, contentAfter));\n tr = tr\n .setSelection(TextSelection.create(tr.doc, posAfter + 1))\n .scrollIntoView()\n .delete(pos, posEnd) // remove content after current pos (it's moved to next para)\n .delete(pos - 1, pos); // remove break before current pos ($cursor.nodeBefore)\n dispatch(tr);\n }\n return true;\n }\n\n dispatch?.(state.tr.replaceSelectionWith(br.create()).scrollIntoView());\n return true;\n });\n\ndeclare global {\n namespace WysiwygEditor {\n interface Context {\n /**\n * Same as @type {MarkdownIt.Options.breaks}\n */\n breaks: boolean;\n }\n }\n}\n\nfunction canContainBreaks(node: Node): boolean {\n return (\n Boolean(node.type.spec.canContainBreaks) ||\n // always allow breaks in paragraph\n node.type === pType(node.type.schema)\n );\n}\n\nexport function isBreakNode(node: Node | null | undefined): boolean {\n return Boolean(node?.type.spec.isBreak);\n}\n"]}
@@ -10,9 +10,12 @@ export declare const CheckboxAttr: {
10
10
  readonly Checked: "checked";
11
11
  readonly For: "for";
12
12
  readonly Line: "data-line";
13
+ readonly Tight: "data-tight";
13
14
  };
14
15
  export declare const idPrefix = "yfm-editor-checkbox";
15
16
  export declare const b: import("@bem-react/classname").ClassNameFormatter;
16
17
  export declare const checkboxType: (schema: import("prosemirror-model").Schema) => import("prosemirror-model").NodeType;
17
18
  export declare const checkboxLabelType: (schema: import("prosemirror-model").Schema) => import("prosemirror-model").NodeType;
18
19
  export declare const checkboxInputType: (schema: import("prosemirror-model").Schema) => import("prosemirror-model").NodeType;
20
+ export declare const CHECKBOX_OPEN_TOKEN = "checkbox_open";
21
+ export declare const CHECKBOX_CLOSE_TOKEN = "checkbox_close";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkboxInputType = exports.checkboxLabelType = exports.checkboxType = exports.b = exports.idPrefix = exports.CheckboxAttr = exports.CheckboxNode = void 0;
3
+ exports.CHECKBOX_CLOSE_TOKEN = exports.CHECKBOX_OPEN_TOKEN = exports.checkboxInputType = exports.checkboxLabelType = exports.checkboxType = exports.b = exports.idPrefix = exports.CheckboxAttr = exports.CheckboxNode = void 0;
4
4
  const classname_1 = require("../../../../classname.js");
5
5
  const schema_1 = require("../../../../utils/schema.js");
6
6
  var CheckboxNode;
@@ -16,10 +16,14 @@ exports.CheckboxAttr = {
16
16
  Checked: 'checked',
17
17
  For: 'for',
18
18
  Line: 'data-line',
19
+ Tight: 'data-tight',
19
20
  };
20
21
  exports.idPrefix = 'yfm-editor-checkbox';
22
+ // TODO [MAJOR]: remove custom classname
21
23
  exports.b = (0, classname_1.cn)('checkbox');
22
24
  exports.checkboxType = (0, schema_1.nodeTypeFactory)(CheckboxNode.Checkbox);
23
25
  exports.checkboxLabelType = (0, schema_1.nodeTypeFactory)(CheckboxNode.Label);
24
26
  exports.checkboxInputType = (0, schema_1.nodeTypeFactory)(CheckboxNode.Input);
27
+ exports.CHECKBOX_OPEN_TOKEN = 'checkbox_open';
28
+ exports.CHECKBOX_CLOSE_TOKEN = 'checkbox_close';
25
29
  //# sourceMappingURL=const.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"const.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/const.ts"],"names":[],"mappings":";;;AAAA,wDAAyC;AACzC,wDAAyD;AAEzD,IAAY,YAIX;AAJD,WAAY,YAAY;IACpB,qCAAqB,CAAA;IACrB,wCAAwB,CAAA;IACxB,wCAAwB,CAAA;AAC5B,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB;AAEY,QAAA,YAAY,GAAG;IACxB,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,IAAI;IACR,OAAO,EAAE,SAAS;IAClB,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,WAAW;CACX,CAAC;AAEE,QAAA,QAAQ,GAAG,qBAAqB,CAAC;AAEjC,QAAA,CAAC,GAAG,IAAA,cAAE,EAAC,UAAU,CAAC,CAAC;AAEnB,QAAA,YAAY,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACtD,QAAA,iBAAiB,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACxD,QAAA,iBAAiB,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC","sourcesContent":["import {cn} from '../../../../classname';\nimport {nodeTypeFactory} from '../../../../utils/schema';\n\nexport enum CheckboxNode {\n Checkbox = 'checkbox',\n Input = 'checkbox_input',\n Label = 'checkbox_label',\n}\n\nexport const CheckboxAttr = {\n Class: 'class',\n Type: 'type',\n Id: 'id',\n Checked: 'checked',\n For: 'for',\n Line: 'data-line',\n} as const;\n\nexport const idPrefix = 'yfm-editor-checkbox';\n\nexport const b = cn('checkbox');\n\nexport const checkboxType = nodeTypeFactory(CheckboxNode.Checkbox);\nexport const checkboxLabelType = nodeTypeFactory(CheckboxNode.Label);\nexport const checkboxInputType = nodeTypeFactory(CheckboxNode.Input);\n"]}
1
+ {"version":3,"file":"const.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/const.ts"],"names":[],"mappings":";;;AAAA,wDAAyC;AACzC,wDAAyD;AAEzD,IAAY,YAIX;AAJD,WAAY,YAAY;IACpB,qCAAqB,CAAA;IACrB,wCAAwB,CAAA;IACxB,wCAAwB,CAAA;AAC5B,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB;AAEY,QAAA,YAAY,GAAG;IACxB,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,IAAI;IACR,OAAO,EAAE,SAAS;IAClB,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;CACb,CAAC;AAEE,QAAA,QAAQ,GAAG,qBAAqB,CAAC;AAE9C,wCAAwC;AAC3B,QAAA,CAAC,GAAG,IAAA,cAAE,EAAC,UAAU,CAAC,CAAC;AAEnB,QAAA,YAAY,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACtD,QAAA,iBAAiB,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACxD,QAAA,iBAAiB,GAAG,IAAA,wBAAe,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AAExD,QAAA,mBAAmB,GAAG,eAAe,CAAC;AACtC,QAAA,oBAAoB,GAAG,gBAAgB,CAAC","sourcesContent":["import {cn} from '../../../../classname';\nimport {nodeTypeFactory} from '../../../../utils/schema';\n\nexport enum CheckboxNode {\n Checkbox = 'checkbox',\n Input = 'checkbox_input',\n Label = 'checkbox_label',\n}\n\nexport const CheckboxAttr = {\n Class: 'class',\n Type: 'type',\n Id: 'id',\n Checked: 'checked',\n For: 'for',\n Line: 'data-line',\n Tight: 'data-tight',\n} as const;\n\nexport const idPrefix = 'yfm-editor-checkbox';\n\n// TODO [MAJOR]: remove custom classname\nexport const b = cn('checkbox');\n\nexport const checkboxType = nodeTypeFactory(CheckboxNode.Checkbox);\nexport const checkboxLabelType = nodeTypeFactory(CheckboxNode.Label);\nexport const checkboxInputType = nodeTypeFactory(CheckboxNode.Input);\n\nexport const CHECKBOX_OPEN_TOKEN = 'checkbox_open';\nexport const CHECKBOX_CLOSE_TOKEN = 'checkbox_close';\n"]}
@@ -1,11 +1,7 @@
1
- import type { NodeSpec } from 'prosemirror-model';
2
1
  import type { ExtensionAuto, ExtensionNodeSpec } from "../../../../core/index.js";
2
+ import { type GetSchemaSpecsOptions } from "./schema.js";
3
3
  export { CheckboxAttr, CheckboxNode, checkboxType, checkboxLabelType, checkboxInputType, } from "./const.js";
4
- export type CheckboxSpecsOptions = {
5
- /**
6
- * @deprecated use placeholder option in BehaviorPreset instead.
7
- */
8
- checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
4
+ export type CheckboxSpecsOptions = GetSchemaSpecsOptions & {
9
5
  inputView?: ExtensionNodeSpec['view'];
10
6
  labelView?: ExtensionNodeSpec['view'];
11
7
  checkboxView?: ExtensionNodeSpec['view'];
@@ -16,7 +16,7 @@ Object.defineProperty(exports, "checkboxInputType", { enumerable: true, get: fun
16
16
  const CheckboxSpecs = (builder, opts) => {
17
17
  const schemaSpecs = (0, schema_1.getSchemaSpecs)(opts, builder.context.get('placeholder'));
18
18
  builder
19
- .configureMd((md) => md.use(index_js_1.default, { idPrefix: const_1.idPrefix, divClass: (0, const_1.b)() }))
19
+ .configureMd((md) => md.use(index_js_1.default, { idPrefix: const_1.idPrefix, divClass: (0, const_1.b)(null, 'checkbox') }))
20
20
  .addNode(const_1.CheckboxNode.Checkbox, () => ({
21
21
  spec: schemaSpecs[const_1.CheckboxNode.Checkbox],
22
22
  toMd: serializer_1.serializerTokens[const_1.CheckboxNode.Checkbox],
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/index.ts"],"names":[],"mappings":";;;;AAAA,yGAA+E;AAK/E,sCAAkD;AAClD,wCAAsC;AACtC,wCAAwC;AACxC,gDAA8C;AAE9C,oCAMiB;AALb,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AACZ,0GAAA,iBAAiB,OAAA;AACjB,0GAAA,iBAAiB,OAAA;AAad,MAAM,aAAa,GAAwC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,IAAA,uBAAc,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAE7E,OAAO;SACF,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAc,EAAE,EAAC,QAAQ,EAAR,gBAAQ,EAAE,QAAQ,EAAE,IAAA,SAAC,GAAE,EAAC,CAAC,CAAC;SACtE,OAAO,CAAC,oBAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACnC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,QAAQ,CAAC;QACxC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,QAAQ,CAAC;QAC7C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,QAAQ,CAAC;SACjD;QACD,IAAI,EAAE,IAAI,CAAC,YAAY;KAC1B,CAAC,CAAC;SACF,OAAO,CAAC,oBAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAChC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,KAAK,CAAC;QACrC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,KAAK,CAAC;QAC1C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,KAAK,CAAC;SAC9C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS;KACvB,CAAC,CAAC;SACF,OAAO,CAAC,oBAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAChC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,KAAK,CAAC;QACrC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,KAAK,CAAC;QAC1C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,KAAK,CAAC;YAC3C,SAAS,EAAE,gBAAgB;SAC9B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS;KACvB,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AA9BW,QAAA,aAAa,iBA8BxB","sourcesContent":["import checkboxPlugin from '@diplodoc/transform/lib/plugins/checkbox/index.js';\nimport type {NodeSpec} from 'prosemirror-model';\n\nimport type {ExtensionAuto, ExtensionNodeSpec} from '../../../../core';\n\nimport {CheckboxNode, b, idPrefix} from './const';\nimport {parserTokens} from './parser';\nimport {getSchemaSpecs} from './schema';\nimport {serializerTokens} from './serializer';\n\nexport {\n CheckboxAttr,\n CheckboxNode,\n checkboxType,\n checkboxLabelType,\n checkboxInputType,\n} from './const';\n\nexport type CheckboxSpecsOptions = {\n /**\n * @deprecated use placeholder option in BehaviorPreset instead.\n */\n checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];\n inputView?: ExtensionNodeSpec['view'];\n labelView?: ExtensionNodeSpec['view'];\n checkboxView?: ExtensionNodeSpec['view'];\n};\n\nexport const CheckboxSpecs: ExtensionAuto<CheckboxSpecsOptions> = (builder, opts) => {\n const schemaSpecs = getSchemaSpecs(opts, builder.context.get('placeholder'));\n\n builder\n .configureMd((md) => md.use(checkboxPlugin, {idPrefix, divClass: b()}))\n .addNode(CheckboxNode.Checkbox, () => ({\n spec: schemaSpecs[CheckboxNode.Checkbox],\n toMd: serializerTokens[CheckboxNode.Checkbox],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Checkbox],\n },\n view: opts.checkboxView,\n }))\n .addNode(CheckboxNode.Input, () => ({\n spec: schemaSpecs[CheckboxNode.Input],\n toMd: serializerTokens[CheckboxNode.Input],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Input],\n },\n view: opts.inputView,\n }))\n .addNode(CheckboxNode.Label, () => ({\n spec: schemaSpecs[CheckboxNode.Label],\n toMd: serializerTokens[CheckboxNode.Label],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Label],\n tokenName: 'checkbox_label',\n },\n view: opts.labelView,\n }));\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/index.ts"],"names":[],"mappings":";;;;AAAA,yGAA+E;AAI/E,sCAAkD;AAClD,wCAAsC;AACtC,wCAAoE;AACpE,gDAA8C;AAE9C,oCAMiB;AALb,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AACZ,0GAAA,iBAAiB,OAAA;AACjB,0GAAA,iBAAiB,OAAA;AASd,MAAM,aAAa,GAAwC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,IAAA,uBAAc,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAE7E,OAAO;SACF,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAc,EAAE,EAAC,QAAQ,EAAR,gBAAQ,EAAE,QAAQ,EAAE,IAAA,SAAC,EAAC,IAAI,EAAE,UAAU,CAAC,EAAC,CAAC,CAAC;SACtF,OAAO,CAAC,oBAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACnC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,QAAQ,CAAC;QACxC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,QAAQ,CAAC;QAC7C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,QAAQ,CAAC;SACjD;QACD,IAAI,EAAE,IAAI,CAAC,YAAY;KAC1B,CAAC,CAAC;SACF,OAAO,CAAC,oBAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAChC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,KAAK,CAAC;QACrC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,KAAK,CAAC;QAC1C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,KAAK,CAAC;SAC9C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS;KACvB,CAAC,CAAC;SACF,OAAO,CAAC,oBAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAChC,IAAI,EAAE,WAAW,CAAC,oBAAY,CAAC,KAAK,CAAC;QACrC,IAAI,EAAE,6BAAgB,CAAC,oBAAY,CAAC,KAAK,CAAC;QAC1C,MAAM,EAAE;YACJ,SAAS,EAAE,qBAAY,CAAC,oBAAY,CAAC,KAAK,CAAC;YAC3C,SAAS,EAAE,gBAAgB;SAC9B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS;KACvB,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AA9BW,QAAA,aAAa,iBA8BxB","sourcesContent":["import checkboxPlugin from '@diplodoc/transform/lib/plugins/checkbox/index.js';\n\nimport type {ExtensionAuto, ExtensionNodeSpec} from '#core';\n\nimport {CheckboxNode, b, idPrefix} from './const';\nimport {parserTokens} from './parser';\nimport {type GetSchemaSpecsOptions, getSchemaSpecs} from './schema';\nimport {serializerTokens} from './serializer';\n\nexport {\n CheckboxAttr,\n CheckboxNode,\n checkboxType,\n checkboxLabelType,\n checkboxInputType,\n} from './const';\n\nexport type CheckboxSpecsOptions = GetSchemaSpecsOptions & {\n inputView?: ExtensionNodeSpec['view'];\n labelView?: ExtensionNodeSpec['view'];\n checkboxView?: ExtensionNodeSpec['view'];\n};\n\nexport const CheckboxSpecs: ExtensionAuto<CheckboxSpecsOptions> = (builder, opts) => {\n const schemaSpecs = getSchemaSpecs(opts, builder.context.get('placeholder'));\n\n builder\n .configureMd((md) => md.use(checkboxPlugin, {idPrefix, divClass: b(null, 'checkbox')}))\n .addNode(CheckboxNode.Checkbox, () => ({\n spec: schemaSpecs[CheckboxNode.Checkbox],\n toMd: serializerTokens[CheckboxNode.Checkbox],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Checkbox],\n },\n view: opts.checkboxView,\n }))\n .addNode(CheckboxNode.Input, () => ({\n spec: schemaSpecs[CheckboxNode.Input],\n toMd: serializerTokens[CheckboxNode.Input],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Input],\n },\n view: opts.inputView,\n }))\n .addNode(CheckboxNode.Label, () => ({\n spec: schemaSpecs[CheckboxNode.Label],\n toMd: serializerTokens[CheckboxNode.Label],\n fromMd: {\n tokenSpec: parserTokens[CheckboxNode.Label],\n tokenName: 'checkbox_label',\n },\n view: opts.labelView,\n }));\n};\n"]}
@@ -2,10 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parserTokens = void 0;
4
4
  const const_1 = require("../const.js");
5
+ const const_2 = require("./const.js");
6
+ const getCheckboxAttrs = (token, tokens, index) => {
7
+ const tight = checkboxIsTight(tokens, index);
8
+ const attrs = token.attrs ? Object.fromEntries(token.attrs) : {};
9
+ return { ...attrs, [const_1.CheckboxAttr.Tight]: tight };
10
+ };
5
11
  const getAttrs = (tok) => (tok.attrs ? Object.fromEntries(tok.attrs) : {});
6
12
  exports.parserTokens = {
7
- [const_1.CheckboxNode.Checkbox]: { name: const_1.CheckboxNode.Checkbox, type: 'block', getAttrs },
13
+ [const_1.CheckboxNode.Checkbox]: {
14
+ name: const_1.CheckboxNode.Checkbox,
15
+ type: 'block',
16
+ getAttrs: getCheckboxAttrs,
17
+ },
8
18
  [const_1.CheckboxNode.Input]: { name: const_1.CheckboxNode.Input, type: 'node', getAttrs },
9
19
  [const_1.CheckboxNode.Label]: { name: const_1.CheckboxNode.Label, type: 'block', getAttrs },
10
20
  };
21
+ function checkboxIsTight(tokens, index) {
22
+ let closeTokenEndLine;
23
+ let nextOpenTokenStartLine;
24
+ for (let i = index + 1; i < tokens.length; i++) {
25
+ if (tokens[i].type === const_2.CHECKBOX_CLOSE_TOKEN) {
26
+ closeTokenEndLine = tokens[i].map?.[1];
27
+ if (tokens[i + 1]?.type === const_2.CHECKBOX_OPEN_TOKEN) {
28
+ nextOpenTokenStartLine = tokens[i + 1].map?.[0];
29
+ }
30
+ break;
31
+ }
32
+ }
33
+ if (!Number.isFinite(closeTokenEndLine) || !Number.isFinite(nextOpenTokenStartLine))
34
+ return null;
35
+ return closeTokenEndLine === nextOpenTokenStartLine;
36
+ }
11
37
  //# sourceMappingURL=parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/parser.ts"],"names":[],"mappings":";;;AACA,uCAAsC;AAEtC,MAAM,QAAQ,GAA4B,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEvF,QAAA,YAAY,GAAsC;IAC3D,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE,EAAC,IAAI,EAAE,oBAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAC;IAE/E,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,EAAC,IAAI,EAAE,oBAAY,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAC;IAExE,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,EAAC,IAAI,EAAE,oBAAY,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAC;CAC5E,CAAC","sourcesContent":["import type {ParserToken} from '../../../../core';\nimport {CheckboxNode} from '../const';\n\nconst getAttrs: ParserToken['getAttrs'] = (tok) => (tok.attrs ? Object.fromEntries(tok.attrs) : {});\n\nexport const parserTokens: Record<CheckboxNode, ParserToken> = {\n [CheckboxNode.Checkbox]: {name: CheckboxNode.Checkbox, type: 'block', getAttrs},\n\n [CheckboxNode.Input]: {name: CheckboxNode.Input, type: 'node', getAttrs},\n\n [CheckboxNode.Label]: {name: CheckboxNode.Label, type: 'block', getAttrs},\n};\n"]}
1
+ {"version":3,"file":"parser.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/parser.ts"],"names":[],"mappings":";;;AAIA,uCAAoD;AAEpD,sCAAkE;AAElE,MAAM,gBAAgB,GAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjE,OAAO,EAAC,GAAG,KAAK,EAAE,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,KAAK,EAAC,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,QAAQ,GAA4B,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEvF,QAAA,YAAY,GAAsC;IAC3D,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE;QACrB,IAAI,EAAE,oBAAY,CAAC,QAAQ;QAC3B,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,gBAAgB;KAC7B;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,EAAC,IAAI,EAAE,oBAAY,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAC;IAExE,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,EAAC,IAAI,EAAE,oBAAY,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAC;CAC5E,CAAC;AAEF,SAAS,eAAe,CAAC,MAAe,EAAE,KAAa;IACnD,IAAI,iBAAqC,CAAC;IAC1C,IAAI,sBAA0C,CAAC;IAE/C,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAoB,EAAE,CAAC;YAC1C,iBAAiB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAEvC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,KAAK,2BAAmB,EAAE,CAAC;gBAC9C,sBAAsB,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,MAAM;QACV,CAAC;IACL,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC/E,OAAO,IAAI,CAAC;IAEhB,OAAO,iBAAiB,KAAK,sBAAsB,CAAC;AACxD,CAAC","sourcesContent":["import type Token from 'markdown-it/lib/token';\n\nimport type {ParserToken} from '#core';\n\nimport {CheckboxAttr, CheckboxNode} from '../const';\n\nimport {CHECKBOX_CLOSE_TOKEN, CHECKBOX_OPEN_TOKEN} from './const';\n\nconst getCheckboxAttrs: ParserToken['getAttrs'] = (token, tokens, index) => {\n const tight = checkboxIsTight(tokens, index);\n const attrs = token.attrs ? Object.fromEntries(token.attrs) : {};\n\n return {...attrs, [CheckboxAttr.Tight]: tight};\n};\n\nconst getAttrs: ParserToken['getAttrs'] = (tok) => (tok.attrs ? Object.fromEntries(tok.attrs) : {});\n\nexport const parserTokens: Record<CheckboxNode, ParserToken> = {\n [CheckboxNode.Checkbox]: {\n name: CheckboxNode.Checkbox,\n type: 'block',\n getAttrs: getCheckboxAttrs,\n },\n\n [CheckboxNode.Input]: {name: CheckboxNode.Input, type: 'node', getAttrs},\n\n [CheckboxNode.Label]: {name: CheckboxNode.Label, type: 'block', getAttrs},\n};\n\nfunction checkboxIsTight(tokens: Token[], index: number): boolean | null {\n let closeTokenEndLine: number | undefined;\n let nextOpenTokenStartLine: number | undefined;\n\n for (let i = index + 1; i < tokens.length; i++) {\n if (tokens[i].type === CHECKBOX_CLOSE_TOKEN) {\n closeTokenEndLine = tokens[i].map?.[1];\n\n if (tokens[i + 1]?.type === CHECKBOX_OPEN_TOKEN) {\n nextOpenTokenStartLine = tokens[i + 1].map?.[0];\n }\n\n break;\n }\n }\n\n if (!Number.isFinite(closeTokenEndLine) || !Number.isFinite(nextOpenTokenStartLine))\n return null;\n\n return closeTokenEndLine === nextOpenTokenStartLine;\n}\n"]}
@@ -1,5 +1,11 @@
1
1
  import { type NodeSpec } from 'prosemirror-model';
2
2
  import type { PlaceholderOptions } from "../../../../utils/placeholder.js";
3
3
  import { CheckboxNode } from "./const.js";
4
- import type { CheckboxSpecsOptions } from "./index.js";
5
- export declare const getSchemaSpecs: (opts?: Pick<CheckboxSpecsOptions, "checkboxLabelPlaceholder">, placeholder?: PlaceholderOptions) => Record<CheckboxNode, NodeSpec>;
4
+ export type GetSchemaSpecsOptions = {
5
+ multiline?: boolean;
6
+ /**
7
+ * @deprecated use placeholder option in BehaviorPreset instead.
8
+ */
9
+ checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
10
+ };
11
+ export declare const getSchemaSpecs: (opts?: GetSchemaSpecsOptions, placeholder?: PlaceholderOptions) => Record<CheckboxNode, NodeSpec>;
@@ -11,8 +11,9 @@ const getSchemaSpecs = (opts, placeholder) => ({
11
11
  selectable: true,
12
12
  allowSelection: false,
13
13
  attrs: {
14
- [const_1.CheckboxAttr.Class]: { default: (0, const_1.b)() },
14
+ [const_1.CheckboxAttr.Class]: { default: (0, const_1.b)(null, 'checkbox') },
15
15
  [const_1.CheckboxAttr.Line]: { default: null },
16
+ ...(opts?.multiline ? { [const_1.CheckboxAttr.Tight]: { default: null } } : undefined),
16
17
  },
17
18
  parseDOM: [
18
19
  {
@@ -95,6 +96,7 @@ const getSchemaSpecs = (opts, placeholder) => ({
95
96
  selectable: false,
96
97
  allowSelection: false,
97
98
  disableGapCursor: true,
99
+ canContainBreaks: Boolean(opts?.multiline),
98
100
  complex: 'leaf',
99
101
  },
100
102
  });
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/schema.ts"],"names":[],"mappings":"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","sourcesContent":["import {Fragment, type NodeSpec, type Schema} from 'prosemirror-model';\n\nimport type {PlaceholderOptions} from '../../../../utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode, b, checkboxInputType, checkboxLabelType} from './const';\n\nimport type {CheckboxSpecsOptions} from './index';\n\nconst DEFAULT_LABEL_PLACEHOLDER = 'Checkbox';\n\nexport const getSchemaSpecs = (\n opts?: Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'>,\n placeholder?: PlaceholderOptions,\n): Record<CheckboxNode, NodeSpec> => ({\n [CheckboxNode.Checkbox]: {\n group: 'block checkbox',\n content: `${CheckboxNode.Input} ${CheckboxNode.Label}`,\n selectable: true,\n allowSelection: false,\n attrs: {\n [CheckboxAttr.Class]: {default: b()},\n [CheckboxAttr.Line]: {default: null},\n },\n parseDOM: [\n {\n tag: 'div.checkbox',\n priority: 100,\n getContent(node, schema) {\n if (node instanceof HTMLElement) {\n const input = node.querySelector<HTMLInputElement>('input[type=checkbox]');\n\n if (input && input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(\n schema,\n input.checked,\n label?.textContent,\n );\n }\n }\n return Fragment.empty;\n },\n },\n {\n tag: 'input[type=checkbox]',\n priority: 50,\n getContent(input, schema) {\n if (input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(schema, input.checked, label?.textContent);\n }\n return Fragment.empty;\n },\n },\n ],\n toDOM(node) {\n return ['div', node.attrs, 0];\n },\n complex: 'root',\n },\n\n [CheckboxNode.Input]: {\n group: 'block checkbox',\n parseDOM: [],\n attrs: {\n [CheckboxAttr.Type]: {default: 'checkbox'},\n [CheckboxAttr.Id]: {default: null},\n [CheckboxAttr.Checked]: {default: null},\n },\n toDOM(node) {\n return ['div', node.attrs];\n },\n selectable: false,\n allowSelection: false,\n complex: 'leaf',\n },\n\n [CheckboxNode.Label]: {\n content: 'inline*',\n group: 'block checkbox',\n parseDOM: [\n {\n tag: `span[class=\"${b('label')}\"]`,\n getAttrs: (node) => ({\n [CheckboxAttr.For]: (node as Element).getAttribute(CheckboxAttr.For) || '',\n }),\n },\n {\n // input handled by checkbox node parse rule\n // ignore label\n tag: 'input[type=checkbox] ~ label',\n ignore: true,\n consuming: true,\n },\n ],\n attrs: {\n [CheckboxAttr.For]: {default: null},\n },\n escapeText: false,\n placeholder: {\n content:\n placeholder?.[CheckboxNode.Label] ??\n opts?.checkboxLabelPlaceholder ??\n DEFAULT_LABEL_PLACEHOLDER,\n alwaysVisible: true,\n },\n toDOM(node) {\n return ['span', {...node.attrs, class: b('label')}, 0];\n },\n selectable: false,\n allowSelection: false,\n disableGapCursor: true,\n complex: 'leaf',\n },\n});\n\n// fallback for invalid HTML (input without id + label without for)\nfunction findNextSiblingLabel(element: HTMLInputElement): HTMLLabelElement | null {\n const nextSibling = element.nextElementSibling;\n return nextSibling instanceof HTMLLabelElement ? nextSibling : null;\n}\n\nfunction findLabelForInput(element: HTMLInputElement): HTMLLabelElement | null {\n return element.labels?.[0] || findNextSiblingLabel(element);\n}\n\nfunction createCheckboxFragment(\n schema: Schema<any, any>,\n checked: boolean | null,\n labelText: string | null | undefined,\n): Fragment {\n return Fragment.from([\n checkboxInputType(schema).create({[CheckboxAttr.Checked]: checked ? 'true' : null}),\n checkboxLabelType(schema).create(null, labelText ? schema.text(labelText) : null),\n ]);\n}\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/schema.ts"],"names":[],"mappings":"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","sourcesContent":["import {Fragment, type NodeSpec, type Schema} from 'prosemirror-model';\n\nimport type {PlaceholderOptions} from 'src/utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode, b, checkboxInputType, checkboxLabelType} from './const';\n\nconst DEFAULT_LABEL_PLACEHOLDER = 'Checkbox';\n\nexport type GetSchemaSpecsOptions = {\n multiline?: boolean;\n /**\n * @deprecated use placeholder option in BehaviorPreset instead.\n */\n checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];\n};\n\nexport const getSchemaSpecs = (\n opts?: GetSchemaSpecsOptions,\n placeholder?: PlaceholderOptions,\n): Record<CheckboxNode, NodeSpec> => ({\n [CheckboxNode.Checkbox]: {\n group: 'block checkbox',\n content: `${CheckboxNode.Input} ${CheckboxNode.Label}`,\n selectable: true,\n allowSelection: false,\n attrs: {\n [CheckboxAttr.Class]: {default: b(null, 'checkbox')},\n [CheckboxAttr.Line]: {default: null},\n ...(opts?.multiline ? {[CheckboxAttr.Tight]: {default: null}} : undefined),\n },\n parseDOM: [\n {\n tag: 'div.checkbox',\n priority: 100,\n getContent(node, schema) {\n if (node instanceof HTMLElement) {\n const input = node.querySelector<HTMLInputElement>('input[type=checkbox]');\n\n if (input && input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(\n schema,\n input.checked,\n label?.textContent,\n );\n }\n }\n return Fragment.empty;\n },\n },\n {\n tag: 'input[type=checkbox]',\n priority: 50,\n getContent(input, schema) {\n if (input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(schema, input.checked, label?.textContent);\n }\n return Fragment.empty;\n },\n },\n ],\n toDOM(node) {\n return ['div', node.attrs, 0];\n },\n complex: 'root',\n },\n\n [CheckboxNode.Input]: {\n group: 'block checkbox',\n parseDOM: [],\n attrs: {\n [CheckboxAttr.Type]: {default: 'checkbox'},\n [CheckboxAttr.Id]: {default: null},\n [CheckboxAttr.Checked]: {default: null},\n },\n toDOM(node) {\n return ['div', node.attrs];\n },\n selectable: false,\n allowSelection: false,\n complex: 'leaf',\n },\n\n [CheckboxNode.Label]: {\n content: 'inline*',\n group: 'block checkbox',\n parseDOM: [\n {\n tag: `span[class=\"${b('label')}\"]`,\n getAttrs: (node) => ({\n [CheckboxAttr.For]: (node as Element).getAttribute(CheckboxAttr.For) || '',\n }),\n },\n {\n // input handled by checkbox node parse rule\n // ignore label\n tag: 'input[type=checkbox] ~ label',\n ignore: true,\n consuming: true,\n },\n ],\n attrs: {\n [CheckboxAttr.For]: {default: null},\n },\n escapeText: false,\n placeholder: {\n content:\n placeholder?.[CheckboxNode.Label] ??\n opts?.checkboxLabelPlaceholder ??\n DEFAULT_LABEL_PLACEHOLDER,\n alwaysVisible: true,\n },\n toDOM(node) {\n return ['span', {...node.attrs, class: b('label')}, 0];\n },\n selectable: false,\n allowSelection: false,\n disableGapCursor: true,\n canContainBreaks: Boolean(opts?.multiline),\n complex: 'leaf',\n },\n});\n\n// fallback for invalid HTML (input without id + label without for)\nfunction findNextSiblingLabel(element: HTMLInputElement): HTMLLabelElement | null {\n const nextSibling = element.nextElementSibling;\n return nextSibling instanceof HTMLLabelElement ? nextSibling : null;\n}\n\nfunction findLabelForInput(element: HTMLInputElement): HTMLLabelElement | null {\n return element.labels?.[0] || findNextSiblingLabel(element);\n}\n\nfunction createCheckboxFragment(\n schema: Schema<any, any>,\n checked: boolean | null,\n labelText: string | null | undefined,\n): Fragment {\n return Fragment.from([\n checkboxInputType(schema).create({[CheckboxAttr.Checked]: checked ? 'true' : null}),\n checkboxLabelType(schema).create(null, labelText ? schema.text(labelText) : null),\n ]);\n}\n"]}
@@ -4,9 +4,21 @@ exports.serializerTokens = void 0;
4
4
  const placeholder_1 = require("../../../../utils/placeholder.js");
5
5
  const const_1 = require("./const.js");
6
6
  exports.serializerTokens = {
7
- [const_1.CheckboxNode.Checkbox]: (state, node) => {
7
+ [const_1.CheckboxNode.Checkbox]: (state, node, parent, index) => {
8
8
  state.renderInline(node);
9
- state.closeBlock(node);
9
+ // TODO [MAJOR]: remove this check after removing `multiline` option
10
+ if (!node.type.spec.attrs?.[const_1.CheckboxAttr.Tight]) {
11
+ state.closeBlock(node);
12
+ return;
13
+ }
14
+ const tight = node.attrs[const_1.CheckboxAttr.Tight];
15
+ const nextIsCheckbox = parent.maybeChild(index + 1)?.type.name === const_1.CheckboxNode.Checkbox;
16
+ if (tight === false || !nextIsCheckbox) {
17
+ state.closeBlock(node);
18
+ }
19
+ else {
20
+ state.ensureNewLine();
21
+ }
10
22
  },
11
23
  [const_1.CheckboxNode.Input]: (state, node) => {
12
24
  const checked = node.attrs[const_1.CheckboxAttr.Checked] === 'true';
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/serializer.ts"],"names":[],"mappings":";;;AACA,kEAAoE;AAEpE,sCAAmD;AAEtC,QAAA,gBAAgB,GAA8C;IACvE,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAY,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC;QAC5D,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YAC5E,KAAK,CAAC,KAAK,CAAC,IAAA,mCAAqB,EAAC,IAAI,CAAC,CAAC,CAAC;YACzC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ,CAAC","sourcesContent":["import type {SerializerNodeToken} from '../../../../core';\nimport {getPlaceholderContent} from '../../../../utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode} from './const';\n\nexport const serializerTokens: Record<CheckboxNode, SerializerNodeToken> = {\n [CheckboxNode.Checkbox]: (state, node) => {\n state.renderInline(node);\n state.closeBlock(node);\n },\n\n [CheckboxNode.Input]: (state, node) => {\n const checked = node.attrs[CheckboxAttr.Checked] === 'true';\n state.write(`[${checked ? 'X' : ' '}] `);\n },\n\n [CheckboxNode.Label]: (state, node, _, idx) => {\n if ((!node.content.size || node.textContent.trim().length === 0) && idx !== 0) {\n state.write(getPlaceholderContent(node));\n return;\n }\n\n if (!idx) {\n state.write('[ ] ');\n }\n\n state.renderInline(node);\n },\n};\n"]}
1
+ {"version":3,"file":"serializer.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/serializer.ts"],"names":[],"mappings":";;;AACA,kEAAoE;AAEpE,sCAAmD;AAEtC,QAAA,gBAAgB,GAA8C;IACvE,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QACpD,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAEzB,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,oBAAY,CAAC,QAAQ,CAAC;QAEzF,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YACrC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAY,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC;QAC5D,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YAC5E,KAAK,CAAC,KAAK,CAAC,IAAA,mCAAqB,EAAC,IAAI,CAAC,CAAC,CAAC;YACzC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ,CAAC","sourcesContent":["import type {SerializerNodeToken} from '../../../../core';\nimport {getPlaceholderContent} from '../../../../utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode} from './const';\n\nexport const serializerTokens: Record<CheckboxNode, SerializerNodeToken> = {\n [CheckboxNode.Checkbox]: (state, node, parent, index) => {\n state.renderInline(node);\n\n // TODO [MAJOR]: remove this check after removing `multiline` option\n if (!node.type.spec.attrs?.[CheckboxAttr.Tight]) {\n state.closeBlock(node);\n return;\n }\n\n const tight = node.attrs[CheckboxAttr.Tight];\n const nextIsCheckbox = parent.maybeChild(index + 1)?.type.name === CheckboxNode.Checkbox;\n\n if (tight === false || !nextIsCheckbox) {\n state.closeBlock(node);\n } else {\n state.ensureNewLine();\n }\n },\n\n [CheckboxNode.Input]: (state, node) => {\n const checked = node.attrs[CheckboxAttr.Checked] === 'true';\n state.write(`[${checked ? 'X' : ' '}] `);\n },\n\n [CheckboxNode.Label]: (state, node, _, idx) => {\n if ((!node.content.size || node.textContent.trim().length === 0) && idx !== 0) {\n state.write(getPlaceholderContent(node));\n return;\n }\n\n if (!idx) {\n state.write('[ ] ');\n }\n\n state.renderInline(node);\n },\n};\n"]}
@@ -1,12 +1,8 @@
1
- .g-md-checkbox {
1
+ .yfm-editor .g-md-checkbox {
2
2
  display: flex;
3
- align-items: center;
4
- /* Increasing selector specificity to override yfm styles with zero padding */
5
3
  }
6
- .g-md-checkbox__label {
7
- display: inline-block;
8
- }
9
- .g-md-checkbox__input {
10
- /* stylelint-disable declaration-no-important */
11
- margin-right: 5px !important;
4
+ .yfm-editor .g-md-checkbox__input[type=checkbox] {
5
+ top: 3px;
6
+ align-self: flex-start;
7
+ margin-right: 5px;
12
8
  }
@@ -3,7 +3,14 @@ import { type CheckboxSpecsOptions } from "./CheckboxSpecs/index.js";
3
3
  import "./index.css";
4
4
  declare const checkboxAction = "addCheckbox";
5
5
  export { CheckboxAttr, CheckboxNode, checkboxType, checkboxLabelType, checkboxInputType, } from "./CheckboxSpecs/index.js";
6
- export type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {};
6
+ export type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {
7
+ /**
8
+ * Allow multiline label in checkboxes.
9
+ * Available with @diplodoc/transform v4.68.0 or higher.
10
+ * @default false
11
+ */
12
+ multiline?: boolean;
13
+ };
7
14
  export declare const Checkbox: ExtensionAuto<CheckboxOptions>;
8
15
  declare global {
9
16
  namespace WysiwygEditor {
@@ -22,7 +22,7 @@ const Checkbox = (builder, opts) => {
22
22
  inputView: () => nodeviews_1.CheckboxInputView.create,
23
23
  });
24
24
  builder
25
- .addPlugin(plugin_1.keymapPlugin, builder.Priority.High)
25
+ .addPlugin(() => (0, plugin_1.keymapPlugin)(opts), builder.Priority.High)
26
26
  .addPlugin(fix_paste_1.fixPastePlugin)
27
27
  .addAction(checkboxAction, () => (0, actions_1.addCheckbox)())
28
28
  .addInputRules(({ schema }) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/index.ts"],"names":[],"mappings":";;;AACA,6DAAwD;AAExD,4DAAyE;AACzE,0CAAsC;AACtC,8CAA8C;AAC9C,wCAAsC;AACtC,sDAAmD;AACnD,sCAAwD;AAExD,uBAAsB;AAEtB,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,0DAMyB;AALrB,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,kHAAA,iBAAiB,OAAA;AACjB,kHAAA,iBAAiB,OAAA;AAKd,MAAM,QAAQ,GAAmC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtE,OAAO,CAAC,GAAG,CAAC,6BAAa,EAAE;QACvB,GAAG,IAAI;QACP,SAAS,EAAE,GAAG,EAAE,CAAC,6BAAiB,CAAC,MAAM;KAC5C,CAAC,CAAC;IAEH,OAAO;SACF,SAAS,CAAC,qBAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC9C,SAAS,CAAC,0BAAc,CAAC;SACzB,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC;SAC9C,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,IAAA,0BAAa,EACT,eAAe,EACf,IAAA,oBAAY,EAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAC1E,CAAC,CACJ;SACJ;KACJ,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AAnBW,QAAA,QAAQ,YAmBnB","sourcesContent":["import type {Action, ExtensionAuto} from '../../../core';\nimport {nodeInputRule} from '../../../utils/inputrules';\n\nimport {CheckboxSpecs, type CheckboxSpecsOptions} from './CheckboxSpecs';\nimport {addCheckbox} from './actions';\nimport {CheckboxInputView} from './nodeviews';\nimport {keymapPlugin} from './plugin';\nimport {fixPastePlugin} from './plugins/fix-paste';\nimport {checkboxInputType, checkboxType} from './utils';\n\nimport './index.scss';\n\nconst checkboxAction = 'addCheckbox';\n\nexport {\n CheckboxAttr,\n CheckboxNode,\n checkboxType,\n checkboxLabelType,\n checkboxInputType,\n} from './CheckboxSpecs';\n\nexport type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {};\n\nexport const Checkbox: ExtensionAuto<CheckboxOptions> = (builder, opts) => {\n builder.use(CheckboxSpecs, {\n ...opts,\n inputView: () => CheckboxInputView.create,\n });\n\n builder\n .addPlugin(keymapPlugin, builder.Priority.High)\n .addPlugin(fixPastePlugin)\n .addAction(checkboxAction, () => addCheckbox())\n .addInputRules(({schema}) => ({\n rules: [\n nodeInputRule(\n /^\\[(\\s?)\\]\\s$/,\n checkboxType(schema).createAndFill({}, checkboxInputType(schema).create()),\n 2,\n ),\n ],\n }));\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [checkboxAction]: Action;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/index.ts"],"names":[],"mappings":";;;AACA,6DAAwD;AAExD,4DAAyE;AACzE,0CAAsC;AACtC,8CAA8C;AAC9C,wCAAsC;AACtC,sDAAmD;AACnD,sCAAwD;AAExD,uBAAsB;AAEtB,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,0DAMyB;AALrB,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,kHAAA,iBAAiB,OAAA;AACjB,kHAAA,iBAAiB,OAAA;AAad,MAAM,QAAQ,GAAmC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtE,OAAO,CAAC,GAAG,CAAC,6BAAa,EAAE;QACvB,GAAG,IAAI;QACP,SAAS,EAAE,GAAG,EAAE,CAAC,6BAAiB,CAAC,MAAM;KAC5C,CAAC,CAAC;IAEH,OAAO;SACF,SAAS,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAY,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC1D,SAAS,CAAC,0BAAc,CAAC;SACzB,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC;SAC9C,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,IAAA,0BAAa,EACT,eAAe,EACf,IAAA,oBAAY,EAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAC1E,CAAC,CACJ;SACJ;KACJ,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AAnBW,QAAA,QAAQ,YAmBnB","sourcesContent":["import type {Action, ExtensionAuto} from '../../../core';\nimport {nodeInputRule} from '../../../utils/inputrules';\n\nimport {CheckboxSpecs, type CheckboxSpecsOptions} from './CheckboxSpecs';\nimport {addCheckbox} from './actions';\nimport {CheckboxInputView} from './nodeviews';\nimport {keymapPlugin} from './plugin';\nimport {fixPastePlugin} from './plugins/fix-paste';\nimport {checkboxInputType, checkboxType} from './utils';\n\nimport './index.scss';\n\nconst checkboxAction = 'addCheckbox';\n\nexport {\n CheckboxAttr,\n CheckboxNode,\n checkboxType,\n checkboxLabelType,\n checkboxInputType,\n} from './CheckboxSpecs';\n\nexport type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {\n /**\n * Allow multiline label in checkboxes.\n * Available with @diplodoc/transform v4.68.0 or higher.\n * @default false\n */\n // TODO [MAJOR]: enable by default and remove option\n multiline?: boolean;\n};\n\nexport const Checkbox: ExtensionAuto<CheckboxOptions> = (builder, opts) => {\n builder.use(CheckboxSpecs, {\n ...opts,\n inputView: () => CheckboxInputView.create,\n });\n\n builder\n .addPlugin(() => keymapPlugin(opts), builder.Priority.High)\n .addPlugin(fixPastePlugin)\n .addAction(checkboxAction, () => addCheckbox())\n .addInputRules(({schema}) => ({\n rules: [\n nodeInputRule(\n /^\\[(\\s?)\\]\\s$/,\n checkboxType(schema).createAndFill({}, checkboxInputType(schema).create()),\n 2,\n ),\n ],\n }));\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [checkboxAction]: Action;\n }\n }\n}\n"]}
@@ -1,3 +1,7 @@
1
1
  import { type Command } from 'prosemirror-state';
2
2
  export declare const splitCheckbox: (replaceWithParagraph?: boolean) => Command;
3
- export declare const keymapPlugin: () => import("prosemirror-state").Plugin<any>;
3
+ type KeymapPluginOptions = {
4
+ multiline?: boolean;
5
+ };
6
+ export declare const keymapPlugin: (props: KeymapPluginOptions) => import("prosemirror-state").Plugin<any>;
7
+ export {};
@@ -6,8 +6,9 @@ const prosemirror_model_1 = require("prosemirror-model");
6
6
  const prosemirror_state_1 = require("prosemirror-state");
7
7
  // @ts-ignore // TODO: fix cjs build
8
8
  const prosemirror_utils_1 = require("prosemirror-utils");
9
- const selection_1 = require("../../../utils/selection.js");
10
9
  const BaseSchema_1 = require("../../base/BaseSchema/index.js");
10
+ const Breaks_1 = require("../../markdown/Breaks/index.js");
11
+ const selection_1 = require("../../../utils/selection.js");
11
12
  const utils_1 = require("./utils.js");
12
13
  const splitCheckbox = (replaceWithParagraph) => (state, dispatch) => {
13
14
  const { $from, $to } = state.selection;
@@ -34,6 +35,10 @@ const splitCheckbox = (replaceWithParagraph) => (state, dispatch) => {
34
35
  tr.insert($from.after(), [node]);
35
36
  tr.replace(label.start + $from.parentOffset, label.pos + label.node.nodeSize);
36
37
  tr.setSelection(new prosemirror_state_1.TextSelection(tr.doc.resolve(tr.selection.$from.after() + (replaceWithParagraph ? 2 : 4))));
38
+ // remove break before cursor
39
+ if ((0, Breaks_1.isBreakNode)($from.nodeBefore)) {
40
+ tr.replaceWith($from.pos - 1, $from.pos, prosemirror_model_1.Fragment.empty);
41
+ }
37
42
  dispatch?.(tr);
38
43
  return true;
39
44
  }
@@ -58,10 +63,10 @@ const removeCheckbox = (state, dispatch) => {
58
63
  }
59
64
  return false;
60
65
  };
61
- const keymapPlugin = () => (0, prosemirror_keymap_1.keymap)({
66
+ const keymapPlugin = (props) => (0, prosemirror_keymap_1.keymap)({
62
67
  Enter: (0, exports.splitCheckbox)(),
63
68
  Backspace: removeCheckbox,
64
- 'Shift-Enter': (0, exports.splitCheckbox)(true),
69
+ ...(props.multiline ? undefined : { 'Shift-Enter': (0, exports.splitCheckbox)(true) }),
65
70
  });
66
71
  exports.keymapPlugin = keymapPlugin;
67
72
  //# sourceMappingURL=plugin.js.map