@puredesktop/platform-editor 1.0.0-beta.1 → 2.1.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 (45) hide show
  1. package/package.json +1 -1
  2. package/src/CollapsePanel.tsx +35 -35
  3. package/src/DocumentDiffView.tsx +130 -130
  4. package/src/DocumentEditor.test.ts +118 -118
  5. package/src/DocumentEditor.tsx +2651 -2631
  6. package/src/alignedLineDiff.test.ts +52 -52
  7. package/src/alignedLineDiff.ts +67 -67
  8. package/src/collectionAssetSrc.ts +2 -2
  9. package/src/commentUtils.test.ts +350 -350
  10. package/src/commentUtils.ts +546 -546
  11. package/src/constants/toolKeys.ts +14 -14
  12. package/src/contentFormat.test.ts +27 -27
  13. package/src/contentFormat.ts +18 -18
  14. package/src/editorExtensions.ts +155 -155
  15. package/src/extensions/appliedChangeMark.ts +115 -115
  16. package/src/extensions/autoReviewPrompts.test.ts +529 -529
  17. package/src/extensions/autoReviewPrompts.ts +1442 -1442
  18. package/src/extensions/collectionImage.ts +26 -26
  19. package/src/extensions/collectionImagePaste.ts +215 -215
  20. package/src/extensions/commentMark.ts +223 -223
  21. package/src/extensions/documentAssetIdentity.ts +54 -54
  22. package/src/extensions/figure.ts +92 -92
  23. package/src/extensions/footnote.ts +186 -186
  24. package/src/extensions/indexMarker.ts +88 -88
  25. package/src/extensions/mathEditing.ts +239 -239
  26. package/src/extensions/mermaidBlock.tsx +297 -297
  27. package/src/extensions/slashCommands.test.ts +170 -170
  28. package/src/extensions/slashCommands.ts +746 -746
  29. package/src/extensions/smartTypography.test.ts +74 -74
  30. package/src/extensions/smartTypography.ts +120 -120
  31. package/src/index.ts +138 -137
  32. package/src/insertCollectionImage.test.ts +60 -60
  33. package/src/insertCollectionImage.ts +63 -63
  34. package/src/insertInlineAssetKind.test.ts +67 -67
  35. package/src/insertInlineAssetKind.ts +49 -49
  36. package/src/mermaidPreview.test.ts +54 -54
  37. package/src/mermaidPreview.ts +115 -115
  38. package/src/styled.ts +697 -676
  39. package/src/toolbar/ToolBtn.tsx +77 -63
  40. package/src/toolbar/Toolbar.test.tsx +325 -325
  41. package/src/toolbar/Toolbar.tsx +662 -624
  42. package/src/toolbar/groups/HeadingGroup.tsx +175 -153
  43. package/src/toolbar/overlayTypes.ts +28 -28
  44. package/src/useEditorExtensions.ts +22 -22
  45. package/src/utils/markdownUtils.ts +331 -331
@@ -1,170 +1,170 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import {
3
- createDefaultSlashCommands,
4
- type SlashCommandItem,
5
- } from './slashCommands.js'
6
-
7
- function createEditor() {
8
- const chain = {
9
- focus: vi.fn(() => chain),
10
- deleteRange: vi.fn(() => chain),
11
- setTextSelection: vi.fn(() => chain),
12
- setParagraph: vi.fn(() => chain),
13
- setNode: vi.fn(() => chain),
14
- toggleBold: vi.fn(() => chain),
15
- toggleItalic: vi.fn(() => chain),
16
- toggleUnderline: vi.fn(() => chain),
17
- toggleCode: vi.fn(() => chain),
18
- toggleBulletList: vi.fn(() => chain),
19
- toggleOrderedList: vi.fn(() => chain),
20
- toggleTaskList: vi.fn(() => chain),
21
- sinkListItem: vi.fn(() => chain),
22
- liftListItem: vi.fn(() => chain),
23
- toggleBlockquote: vi.fn(() => chain),
24
- toggleCodeBlock: vi.fn(() => chain),
25
- insertTable: vi.fn(() => chain),
26
- insertFootnote: vi.fn(() => chain),
27
- toggleIndexMarker: vi.fn(() => chain),
28
- insertMermaidBlock: vi.fn(() => chain),
29
- run: vi.fn(() => true),
30
- }
31
- const editor = {
32
- chain: vi.fn(() => chain),
33
- }
34
- return { editor, chain }
35
- }
36
-
37
- function runCommand(item: SlashCommandItem) {
38
- const { editor, chain } = createEditor()
39
- item.run({
40
- editor: editor as never,
41
- range: { from: 2, to: 8 },
42
- query: item.title,
43
- source: 'typed',
44
- })
45
- return { editor, chain }
46
- }
47
-
48
- function runSelectionCommand(item: SlashCommandItem) {
49
- const { editor, chain } = createEditor()
50
- item.run({
51
- editor: editor as never,
52
- range: { from: 2, to: 8 },
53
- query: item.title,
54
- source: 'selection',
55
- })
56
- return { editor, chain }
57
- }
58
-
59
- describe('createDefaultSlashCommands', () => {
60
- it('provides the default PureWriter content command inventory', () => {
61
- expect(createDefaultSlashCommands().map(item => item.id)).toEqual([
62
- 'paragraph',
63
- 'heading-1',
64
- 'heading-2',
65
- 'heading-3',
66
- 'bold',
67
- 'italic',
68
- 'underline',
69
- 'inline-code',
70
- 'link',
71
- 'bullet-list',
72
- 'numbered-list',
73
- 'task-list',
74
- 'indent-list',
75
- 'outdent-list',
76
- 'quote',
77
- 'code-block',
78
- 'table',
79
- 'footnote',
80
- 'index-marker',
81
- 'inline-equation',
82
- 'display-equation',
83
- 'mermaid',
84
- ])
85
- })
86
-
87
- it('turns slash text into a paragraph', () => {
88
- const paragraph = createDefaultSlashCommands().find(
89
- item => item.id === 'paragraph',
90
- )
91
- expect(paragraph).toBeDefined()
92
-
93
- const { chain } = runCommand(paragraph!)
94
-
95
- expect(chain.deleteRange).toHaveBeenCalledWith({ from: 2, to: 8 })
96
- expect(chain.setParagraph).toHaveBeenCalledOnce()
97
- expect(chain.run).toHaveBeenCalledOnce()
98
- })
99
-
100
- it('turns slash text into headings', () => {
101
- const commands = createDefaultSlashCommands()
102
-
103
- const h1 = runCommand(commands.find(item => item.id === 'heading-1')!)
104
- const h2 = runCommand(commands.find(item => item.id === 'heading-2')!)
105
- const h3 = runCommand(commands.find(item => item.id === 'heading-3')!)
106
-
107
- expect(h1.chain.setNode).toHaveBeenCalledWith('heading', { level: 1 })
108
- expect(h2.chain.setNode).toHaveBeenCalledWith('heading', { level: 2 })
109
- expect(h3.chain.setNode).toHaveBeenCalledWith('heading', { level: 3 })
110
- })
111
-
112
- it('turns slash text into mark, list, and block commands', () => {
113
- const commands = createDefaultSlashCommands()
114
-
115
- const bold = runCommand(commands.find(item => item.id === 'bold')!)
116
- const italic = runCommand(commands.find(item => item.id === 'italic')!)
117
- const underline = runCommand(
118
- commands.find(item => item.id === 'underline')!,
119
- )
120
- const inlineCode = runCommand(
121
- commands.find(item => item.id === 'inline-code')!,
122
- )
123
- const bullet = runCommand(commands.find(item => item.id === 'bullet-list')!)
124
- const numbered = runCommand(
125
- commands.find(item => item.id === 'numbered-list')!,
126
- )
127
- const task = runCommand(commands.find(item => item.id === 'task-list')!)
128
- const indent = runCommand(commands.find(item => item.id === 'indent-list')!)
129
- const outdent = runCommand(
130
- commands.find(item => item.id === 'outdent-list')!,
131
- )
132
- const quote = runCommand(commands.find(item => item.id === 'quote')!)
133
- const code = runCommand(commands.find(item => item.id === 'code-block')!)
134
- const table = runCommand(commands.find(item => item.id === 'table')!)
135
- const footnote = runCommand(commands.find(item => item.id === 'footnote')!)
136
- const index = runCommand(
137
- commands.find(item => item.id === 'index-marker')!,
138
- )
139
- const mermaid = runCommand(commands.find(item => item.id === 'mermaid')!)
140
-
141
- expect(bold.chain.toggleBold).toHaveBeenCalledOnce()
142
- expect(italic.chain.toggleItalic).toHaveBeenCalledOnce()
143
- expect(underline.chain.toggleUnderline).toHaveBeenCalledOnce()
144
- expect(inlineCode.chain.toggleCode).toHaveBeenCalledOnce()
145
- expect(bullet.chain.toggleBulletList).toHaveBeenCalledOnce()
146
- expect(numbered.chain.toggleOrderedList).toHaveBeenCalledOnce()
147
- expect(task.chain.toggleTaskList).toHaveBeenCalledOnce()
148
- expect(indent.chain.sinkListItem).toHaveBeenCalledWith('listItem')
149
- expect(outdent.chain.liftListItem).toHaveBeenCalledWith('listItem')
150
- expect(quote.chain.toggleBlockquote).toHaveBeenCalledOnce()
151
- expect(code.chain.toggleCodeBlock).toHaveBeenCalledOnce()
152
- expect(table.chain.insertTable).toHaveBeenCalledWith({
153
- rows: 3,
154
- cols: 3,
155
- withHeaderRow: true,
156
- })
157
- expect(footnote.chain.insertFootnote).toHaveBeenCalledOnce()
158
- expect(index.chain.toggleIndexMarker).toHaveBeenCalledOnce()
159
- expect(mermaid.chain.insertMermaidBlock).toHaveBeenCalledOnce()
160
- })
161
-
162
- it('does not delete selected text when a slash command is run on a selection', () => {
163
- const commands = createDefaultSlashCommands()
164
- const bold = runSelectionCommand(commands.find(item => item.id === 'bold')!)
165
-
166
- expect(bold.chain.deleteRange).not.toHaveBeenCalled()
167
- expect(bold.chain.setTextSelection).toHaveBeenCalledWith({ from: 2, to: 8 })
168
- expect(bold.chain.toggleBold).toHaveBeenCalledOnce()
169
- })
170
- })
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import {
3
+ createDefaultSlashCommands,
4
+ type SlashCommandItem,
5
+ } from './slashCommands.js'
6
+
7
+ function createEditor() {
8
+ const chain = {
9
+ focus: vi.fn(() => chain),
10
+ deleteRange: vi.fn(() => chain),
11
+ setTextSelection: vi.fn(() => chain),
12
+ setParagraph: vi.fn(() => chain),
13
+ setNode: vi.fn(() => chain),
14
+ toggleBold: vi.fn(() => chain),
15
+ toggleItalic: vi.fn(() => chain),
16
+ toggleUnderline: vi.fn(() => chain),
17
+ toggleCode: vi.fn(() => chain),
18
+ toggleBulletList: vi.fn(() => chain),
19
+ toggleOrderedList: vi.fn(() => chain),
20
+ toggleTaskList: vi.fn(() => chain),
21
+ sinkListItem: vi.fn(() => chain),
22
+ liftListItem: vi.fn(() => chain),
23
+ toggleBlockquote: vi.fn(() => chain),
24
+ toggleCodeBlock: vi.fn(() => chain),
25
+ insertTable: vi.fn(() => chain),
26
+ insertFootnote: vi.fn(() => chain),
27
+ toggleIndexMarker: vi.fn(() => chain),
28
+ insertMermaidBlock: vi.fn(() => chain),
29
+ run: vi.fn(() => true),
30
+ }
31
+ const editor = {
32
+ chain: vi.fn(() => chain),
33
+ }
34
+ return { editor, chain }
35
+ }
36
+
37
+ function runCommand(item: SlashCommandItem) {
38
+ const { editor, chain } = createEditor()
39
+ item.run({
40
+ editor: editor as never,
41
+ range: { from: 2, to: 8 },
42
+ query: item.title,
43
+ source: 'typed',
44
+ })
45
+ return { editor, chain }
46
+ }
47
+
48
+ function runSelectionCommand(item: SlashCommandItem) {
49
+ const { editor, chain } = createEditor()
50
+ item.run({
51
+ editor: editor as never,
52
+ range: { from: 2, to: 8 },
53
+ query: item.title,
54
+ source: 'selection',
55
+ })
56
+ return { editor, chain }
57
+ }
58
+
59
+ describe('createDefaultSlashCommands', () => {
60
+ it('provides the default PureWriter content command inventory', () => {
61
+ expect(createDefaultSlashCommands().map(item => item.id)).toEqual([
62
+ 'paragraph',
63
+ 'heading-1',
64
+ 'heading-2',
65
+ 'heading-3',
66
+ 'bold',
67
+ 'italic',
68
+ 'underline',
69
+ 'inline-code',
70
+ 'link',
71
+ 'bullet-list',
72
+ 'numbered-list',
73
+ 'task-list',
74
+ 'indent-list',
75
+ 'outdent-list',
76
+ 'quote',
77
+ 'code-block',
78
+ 'table',
79
+ 'footnote',
80
+ 'index-marker',
81
+ 'inline-equation',
82
+ 'display-equation',
83
+ 'mermaid',
84
+ ])
85
+ })
86
+
87
+ it('turns slash text into a paragraph', () => {
88
+ const paragraph = createDefaultSlashCommands().find(
89
+ item => item.id === 'paragraph',
90
+ )
91
+ expect(paragraph).toBeDefined()
92
+
93
+ const { chain } = runCommand(paragraph!)
94
+
95
+ expect(chain.deleteRange).toHaveBeenCalledWith({ from: 2, to: 8 })
96
+ expect(chain.setParagraph).toHaveBeenCalledOnce()
97
+ expect(chain.run).toHaveBeenCalledOnce()
98
+ })
99
+
100
+ it('turns slash text into headings', () => {
101
+ const commands = createDefaultSlashCommands()
102
+
103
+ const h1 = runCommand(commands.find(item => item.id === 'heading-1')!)
104
+ const h2 = runCommand(commands.find(item => item.id === 'heading-2')!)
105
+ const h3 = runCommand(commands.find(item => item.id === 'heading-3')!)
106
+
107
+ expect(h1.chain.setNode).toHaveBeenCalledWith('heading', { level: 1 })
108
+ expect(h2.chain.setNode).toHaveBeenCalledWith('heading', { level: 2 })
109
+ expect(h3.chain.setNode).toHaveBeenCalledWith('heading', { level: 3 })
110
+ })
111
+
112
+ it('turns slash text into mark, list, and block commands', () => {
113
+ const commands = createDefaultSlashCommands()
114
+
115
+ const bold = runCommand(commands.find(item => item.id === 'bold')!)
116
+ const italic = runCommand(commands.find(item => item.id === 'italic')!)
117
+ const underline = runCommand(
118
+ commands.find(item => item.id === 'underline')!,
119
+ )
120
+ const inlineCode = runCommand(
121
+ commands.find(item => item.id === 'inline-code')!,
122
+ )
123
+ const bullet = runCommand(commands.find(item => item.id === 'bullet-list')!)
124
+ const numbered = runCommand(
125
+ commands.find(item => item.id === 'numbered-list')!,
126
+ )
127
+ const task = runCommand(commands.find(item => item.id === 'task-list')!)
128
+ const indent = runCommand(commands.find(item => item.id === 'indent-list')!)
129
+ const outdent = runCommand(
130
+ commands.find(item => item.id === 'outdent-list')!,
131
+ )
132
+ const quote = runCommand(commands.find(item => item.id === 'quote')!)
133
+ const code = runCommand(commands.find(item => item.id === 'code-block')!)
134
+ const table = runCommand(commands.find(item => item.id === 'table')!)
135
+ const footnote = runCommand(commands.find(item => item.id === 'footnote')!)
136
+ const index = runCommand(
137
+ commands.find(item => item.id === 'index-marker')!,
138
+ )
139
+ const mermaid = runCommand(commands.find(item => item.id === 'mermaid')!)
140
+
141
+ expect(bold.chain.toggleBold).toHaveBeenCalledOnce()
142
+ expect(italic.chain.toggleItalic).toHaveBeenCalledOnce()
143
+ expect(underline.chain.toggleUnderline).toHaveBeenCalledOnce()
144
+ expect(inlineCode.chain.toggleCode).toHaveBeenCalledOnce()
145
+ expect(bullet.chain.toggleBulletList).toHaveBeenCalledOnce()
146
+ expect(numbered.chain.toggleOrderedList).toHaveBeenCalledOnce()
147
+ expect(task.chain.toggleTaskList).toHaveBeenCalledOnce()
148
+ expect(indent.chain.sinkListItem).toHaveBeenCalledWith('listItem')
149
+ expect(outdent.chain.liftListItem).toHaveBeenCalledWith('listItem')
150
+ expect(quote.chain.toggleBlockquote).toHaveBeenCalledOnce()
151
+ expect(code.chain.toggleCodeBlock).toHaveBeenCalledOnce()
152
+ expect(table.chain.insertTable).toHaveBeenCalledWith({
153
+ rows: 3,
154
+ cols: 3,
155
+ withHeaderRow: true,
156
+ })
157
+ expect(footnote.chain.insertFootnote).toHaveBeenCalledOnce()
158
+ expect(index.chain.toggleIndexMarker).toHaveBeenCalledOnce()
159
+ expect(mermaid.chain.insertMermaidBlock).toHaveBeenCalledOnce()
160
+ })
161
+
162
+ it('does not delete selected text when a slash command is run on a selection', () => {
163
+ const commands = createDefaultSlashCommands()
164
+ const bold = runSelectionCommand(commands.find(item => item.id === 'bold')!)
165
+
166
+ expect(bold.chain.deleteRange).not.toHaveBeenCalled()
167
+ expect(bold.chain.setTextSelection).toHaveBeenCalledWith({ from: 2, to: 8 })
168
+ expect(bold.chain.toggleBold).toHaveBeenCalledOnce()
169
+ })
170
+ })