@edifice.io/tiptap-extensions 1.5.16-develop-rc.2 → 1.7.4-develop-pedago.20241211160712

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 (154) hide show
  1. package/README.md +66 -0
  2. package/dist/abbr/abbr.cjs +1 -32
  3. package/dist/abbr/abbr.cjs.map +1 -1
  4. package/dist/abbr/abbr.d.ts +12 -12
  5. package/dist/abbr/abbr.js +13 -17
  6. package/dist/abbr/abbr.js.map +1 -1
  7. package/dist/alert/alert.cjs +1 -32
  8. package/dist/alert/alert.cjs.map +1 -1
  9. package/dist/alert/alert.js +22 -20
  10. package/dist/alert/alert.js.map +1 -1
  11. package/dist/attachment/attachment-transformer.cjs +2 -0
  12. package/dist/attachment/attachment-transformer.cjs.map +1 -0
  13. package/dist/attachment/attachment-transformer.d.ts +12 -0
  14. package/dist/attachment/attachment-transformer.js +76 -0
  15. package/dist/attachment/attachment-transformer.js.map +1 -0
  16. package/dist/attachment/attachment.cjs +1 -73
  17. package/dist/attachment/attachment.cjs.map +1 -1
  18. package/dist/attachment/attachment.d.ts +6 -6
  19. package/dist/attachment/attachment.js +29 -40
  20. package/dist/attachment/attachment.js.map +1 -1
  21. package/dist/attachment/index.d.ts +1 -0
  22. package/dist/audio/audio.cjs +2 -52
  23. package/dist/audio/audio.cjs.map +1 -1
  24. package/dist/audio/audio.d.ts +13 -17
  25. package/dist/audio/audio.js +25 -28
  26. package/dist/audio/audio.js.map +1 -1
  27. package/dist/font-size/font-size.cjs +1 -48
  28. package/dist/font-size/font-size.cjs.map +1 -1
  29. package/dist/font-size/font-size.d.ts +13 -13
  30. package/dist/font-size/font-size.js +17 -29
  31. package/dist/font-size/font-size.js.map +1 -1
  32. package/dist/heading/heading.cjs +1 -61
  33. package/dist/heading/heading.cjs.map +1 -1
  34. package/dist/heading/heading.d.ts +12 -10
  35. package/dist/heading/heading.js +25 -39
  36. package/dist/heading/heading.js.map +1 -1
  37. package/dist/highlight/highlight.cjs +1 -25
  38. package/dist/highlight/highlight.cjs.map +1 -1
  39. package/dist/highlight/highlight.d.ts +1 -4
  40. package/dist/highlight/highlight.js +13 -11
  41. package/dist/highlight/highlight.js.map +1 -1
  42. package/dist/hyperlink/hyperlink.cjs +1 -47
  43. package/dist/hyperlink/hyperlink.cjs.map +1 -1
  44. package/dist/hyperlink/hyperlink.d.ts +24 -27
  45. package/dist/hyperlink/hyperlink.js +19 -21
  46. package/dist/hyperlink/hyperlink.js.map +1 -1
  47. package/dist/iframe/iframe.cjs +1 -69
  48. package/dist/iframe/iframe.cjs.map +1 -1
  49. package/dist/iframe/iframe.d.ts +14 -12
  50. package/dist/iframe/iframe.js +32 -48
  51. package/dist/iframe/iframe.js.map +1 -1
  52. package/dist/image/image.cjs +2 -0
  53. package/dist/image/image.cjs.map +1 -0
  54. package/dist/image/image.d.ts +26 -0
  55. package/dist/image/image.js +178 -0
  56. package/dist/image/image.js.map +1 -0
  57. package/dist/image/index.d.ts +3 -3
  58. package/dist/index.cjs +1 -43
  59. package/dist/index.js +24 -22
  60. package/dist/index.js.map +1 -1
  61. package/dist/line-height/line-height.cjs +1 -33
  62. package/dist/line-height/line-height.cjs.map +1 -1
  63. package/dist/line-height/line-height.js +15 -18
  64. package/dist/line-height/line-height.js.map +1 -1
  65. package/dist/linker/linker.cjs +1 -95
  66. package/dist/linker/linker.cjs.map +1 -1
  67. package/dist/linker/linker.d.ts +17 -17
  68. package/dist/linker/linker.js +49 -57
  69. package/dist/linker/linker.js.map +1 -1
  70. package/dist/mathjax/mathjax.cjs +1 -47
  71. package/dist/mathjax/mathjax.cjs.map +1 -1
  72. package/dist/mathjax/mathjax.js +20 -30
  73. package/dist/mathjax/mathjax.js.map +1 -1
  74. package/dist/paragraph/paragraph.cjs +1 -13
  75. package/dist/paragraph/paragraph.cjs.map +1 -1
  76. package/dist/paragraph/paragraph.d.ts +1 -4
  77. package/dist/paragraph/paragraph.js +8 -6
  78. package/dist/paragraph/paragraph.js.map +1 -1
  79. package/dist/speech-recognition/speech-recognition.cjs +1 -76
  80. package/dist/speech-recognition/speech-recognition.cjs.map +1 -1
  81. package/dist/speech-recognition/speech-recognition.d.ts +12 -12
  82. package/dist/speech-recognition/speech-recognition.js +36 -57
  83. package/dist/speech-recognition/speech-recognition.js.map +1 -1
  84. package/dist/speech-synthesis/speech-synthesis.cjs +1 -32
  85. package/dist/speech-synthesis/speech-synthesis.cjs.map +1 -1
  86. package/dist/speech-synthesis/speech-synthesis.d.ts +9 -9
  87. package/dist/speech-synthesis/speech-synthesis.js +10 -19
  88. package/dist/speech-synthesis/speech-synthesis.js.map +1 -1
  89. package/dist/table-cell/table-cell.cjs +1 -27
  90. package/dist/table-cell/table-cell.cjs.map +1 -1
  91. package/dist/table-cell/table-cell.d.ts +1 -4
  92. package/dist/table-cell/table-cell.js +12 -17
  93. package/dist/table-cell/table-cell.js.map +1 -1
  94. package/dist/transform/html-to-json/html-to-json.cjs +1 -4
  95. package/dist/transform/html-to-json/html-to-json.d.ts +1 -4
  96. package/dist/transform/html-to-json/html-to-json.js +4 -2
  97. package/dist/transform/json-to-html/json-to-html.cjs +1 -4
  98. package/dist/transform/json-to-html/json-to-html.js +4 -2
  99. package/dist/video/video.cjs +2 -111
  100. package/dist/video/video.cjs.map +1 -1
  101. package/dist/video/video.d.ts +19 -28
  102. package/dist/video/video.js +90 -114
  103. package/dist/video/video.js.map +1 -1
  104. package/package.json +27 -16
  105. package/.turbo/turbo-build.log +0 -58
  106. package/.turbo/turbo-format.log +0 -142
  107. package/.turbo/turbo-lint.log +0 -5
  108. package/dist/image/custom-image.cjs +0 -163
  109. package/dist/image/custom-image.cjs.map +0 -1
  110. package/dist/image/custom-image.d.ts +0 -27
  111. package/dist/image/custom-image.js +0 -181
  112. package/dist/image/custom-image.js.map +0 -1
  113. package/src/abbr/abbr.ts +0 -57
  114. package/src/abbr/index.ts +0 -5
  115. package/src/alert/alert.ts +0 -46
  116. package/src/alert/index.ts +0 -5
  117. package/src/attachment/attachment.ts +0 -113
  118. package/src/attachment/index.ts +0 -5
  119. package/src/audio/audio.ts +0 -81
  120. package/src/audio/index.ts +0 -5
  121. package/src/font-size/font-size.ts +0 -74
  122. package/src/font-size/index.ts +0 -5
  123. package/src/heading/heading.ts +0 -90
  124. package/src/heading/index.ts +0 -5
  125. package/src/highlight/highlight.ts +0 -27
  126. package/src/highlight/index.ts +0 -5
  127. package/src/hyperlink/hyperlink.ts +0 -92
  128. package/src/hyperlink/index.ts +0 -5
  129. package/src/iframe/iframe.ts +0 -112
  130. package/src/iframe/index.ts +0 -5
  131. package/src/image/custom-image.ts +0 -226
  132. package/src/image/index.ts +0 -5
  133. package/src/index.ts +0 -19
  134. package/src/line-height/index.ts +0 -5
  135. package/src/line-height/line-height.ts +0 -37
  136. package/src/linker/index.ts +0 -5
  137. package/src/linker/linker.ts +0 -153
  138. package/src/mathjax/index.ts +0 -5
  139. package/src/mathjax/mathjax.ts +0 -55
  140. package/src/paragraph/index.ts +0 -5
  141. package/src/paragraph/paragraph.ts +0 -25
  142. package/src/speech-recognition/index.ts +0 -5
  143. package/src/speech-recognition/speech-recognition.ts +0 -123
  144. package/src/speech-synthesis/index.ts +0 -5
  145. package/src/speech-synthesis/speech-synthesis.ts +0 -52
  146. package/src/table-cell/index.ts +0 -5
  147. package/src/table-cell/table-cell.ts +0 -28
  148. package/src/transform/html-to-json/html-to-json.ts +0 -5
  149. package/src/transform/index.ts +0 -4
  150. package/src/transform/json-to-html/json-to-html.ts +0 -5
  151. package/src/video/index.ts +0 -5
  152. package/src/video/video.ts +0 -173
  153. package/tsconfig.json +0 -20
  154. package/vite.config.ts +0 -46
@@ -1,226 +0,0 @@
1
- import { mergeAttributes, nodeInputRule } from '@tiptap/core';
2
- import Image from '@tiptap/extension-image';
3
-
4
- export const IMAGE_INPUT_REGEX =
5
- /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/;
6
-
7
- export interface CustomImageOptions {
8
- HTMLAttributes: Record<string, string>;
9
- sizes: string[];
10
- }
11
-
12
- interface AttributesProps {
13
- width: number | string;
14
- height: number | string;
15
- size: string;
16
- }
17
-
18
- declare module '@tiptap/core' {
19
- interface Commands<ReturnType> {
20
- customImage: {
21
- setAttributes: (options: AttributesProps) => ReturnType;
22
- setNewImage: (options: {
23
- src: string;
24
- alt?: string;
25
- title?: string;
26
- }) => ReturnType;
27
- };
28
- }
29
- }
30
-
31
- export const CustomImage = Image.extend<CustomImageOptions>({
32
- name: 'custom-image',
33
- draggable: true,
34
- selectable: true,
35
-
36
- addOptions() {
37
- return {
38
- ...this.parent?.(),
39
- inline: true,
40
- content: 'inline*',
41
- sizes: ['small', 'medium', 'large'],
42
- HTMLAttributes: {
43
- class: 'custom-image',
44
- },
45
- };
46
- },
47
-
48
- addAttributes() {
49
- return {
50
- ...this.parent?.(),
51
- size: {
52
- default: 'medium',
53
- rendered: false,
54
- },
55
- alt: {
56
- renderHTML: (attributes) => {
57
- return {
58
- alt: attributes.alt,
59
- };
60
- },
61
- parseHTML: (element) => element.getAttribute('alt'),
62
- },
63
- title: {
64
- renderHTML: (attributes) => {
65
- return {
66
- title: attributes.title,
67
- };
68
- },
69
- parseHTML: (element) => element.getAttribute('title'),
70
- },
71
- width: {
72
- default: '350',
73
- renderHTML: (attributes) => {
74
- if (
75
- attributes.width !== null &&
76
- attributes.width !== undefined &&
77
- !Number.isNaN(attributes.width)
78
- ) {
79
- return {
80
- width: parseInt(attributes.width),
81
- };
82
- }
83
- return {};
84
- },
85
- parseHTML: (element) => element.getAttribute('width'),
86
- },
87
- height: {
88
- renderHTML: (attributes) => {
89
- if (
90
- attributes.height !== null &&
91
- attributes.height !== undefined &&
92
- !Number.isNaN(attributes.height)
93
- ) {
94
- return {
95
- height: parseInt(attributes.height),
96
- };
97
- }
98
- return {};
99
- },
100
- parseHTML: (element) => element.getAttribute('height'),
101
- },
102
- style: {
103
- renderHTML: (attributes) => {
104
- return attributes.style
105
- ? {
106
- style: attributes.style,
107
- }
108
- : {};
109
- },
110
- parseHTML: (element) => {
111
- const style = element.getAttribute('style');
112
- return style && typeof style === 'string' && style.length > 0
113
- ? {}
114
- : null;
115
- },
116
- },
117
- };
118
- },
119
-
120
- parseHTML() {
121
- return [
122
- {
123
- tag: 'img[src]:not([src^="data:"])',
124
- getAttrs: (el: HTMLImageElement) => {
125
- const attr = { src: el.getAttribute('src') };
126
- // Check old content format and get the width from the parent element
127
- if (el.parentElement?.className.includes('image-container')) {
128
- if (el.parentElement.style?.width) {
129
- attr['width'] = el.parentElement.style.width;
130
- }
131
- }
132
- if (el.style?.width) {
133
- attr['width'] = el.style.width;
134
- }
135
-
136
- // Check old content smiley
137
- const oldSmileyList = [
138
- 'happy',
139
- 'proud',
140
- 'dreamy',
141
- 'love',
142
- 'tired',
143
- 'angry',
144
- 'worried',
145
- 'sick',
146
- 'joker',
147
- 'sad',
148
- ];
149
- if (
150
- oldSmileyList.filter((smiley) => attr.src.includes(smiley + '.png'))
151
- .length > 0
152
- ) {
153
- attr['style'] = {
154
- width: '1.5em',
155
- height: '1.5em',
156
- fontSize: el.parentElement?.style?.fontSize,
157
- };
158
- attr['width'] = 'null';
159
- attr['height'] = 'null';
160
- }
161
- return attr;
162
- },
163
- },
164
- ];
165
- },
166
-
167
- renderHTML({ HTMLAttributes }) {
168
- return [
169
- 'img',
170
- mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
171
- ];
172
- },
173
-
174
- addInputRules() {
175
- return [
176
- nodeInputRule({
177
- find: IMAGE_INPUT_REGEX,
178
- type: this.type,
179
- getAttributes: (match) => {
180
- const [, , alt, src, title] = match;
181
-
182
- return {
183
- src,
184
- alt,
185
- title,
186
- };
187
- },
188
- }),
189
- ];
190
- },
191
-
192
- addCommands() {
193
- return {
194
- setNewImage:
195
- (attrs) =>
196
- ({ tr, dispatch }) => {
197
- const { selection } = tr;
198
- const node = this.type.create(attrs);
199
-
200
- if (dispatch) {
201
- tr.replaceRangeWith(selection.from, selection.to, node);
202
- }
203
-
204
- return true;
205
- },
206
- setAttributes:
207
- (attributes) =>
208
- ({ tr, dispatch }) => {
209
- const { selection } = tr;
210
-
211
- const nodeAttrs = tr.doc.nodeAt(tr.selection.from);
212
- const options = {
213
- ...nodeAttrs.attrs,
214
- ...attributes,
215
- };
216
- const node = this.type.create(options);
217
-
218
- if (dispatch) {
219
- tr.replaceRangeWith(selection.from, selection.to, node);
220
- }
221
-
222
- return true;
223
- },
224
- };
225
- },
226
- });
@@ -1,5 +0,0 @@
1
- import { CustomImage } from './custom-image';
2
-
3
- export * from './custom-image';
4
-
5
- export default CustomImage;
package/src/index.ts DELETED
@@ -1,19 +0,0 @@
1
- export * from './abbr';
2
- export * from './alert';
3
- export * from './attachment';
4
- export * from './audio';
5
- export * from './font-size';
6
- export * from './heading';
7
- export * from './highlight';
8
- export * from './hyperlink';
9
- export * from './iframe';
10
- export * from './image';
11
- export * from './line-height';
12
- export * from './linker';
13
- export * from './mathjax';
14
- export * from './paragraph';
15
- export * from './speech-recognition';
16
- export * from './speech-synthesis';
17
- export * from './table-cell';
18
- export * from './transform';
19
- export * from './video';
@@ -1,5 +0,0 @@
1
- import { LineHeight } from './line-height';
2
-
3
- export * from './line-height';
4
-
5
- export default LineHeight;
@@ -1,37 +0,0 @@
1
- import '@tiptap/extension-text-style';
2
-
3
- import { Extension } from '@tiptap/core';
4
-
5
- export const LineHeight = Extension.create({
6
- name: 'lineHeight',
7
-
8
- addOptions() {
9
- return {
10
- types: ['textStyle'],
11
- };
12
- },
13
-
14
- addGlobalAttributes() {
15
- return [
16
- {
17
- types: this.options.types,
18
- attributes: {
19
- lineHeight: {
20
- default: null,
21
- parseHTML: (element) =>
22
- element.style.lineHeight?.replace(/['"]+/g, ''),
23
- renderHTML: (attributes) => {
24
- if (!attributes.lineHeight) {
25
- return {};
26
- }
27
-
28
- return {
29
- style: `line-height: ${attributes.lineHeight}`,
30
- };
31
- },
32
- },
33
- },
34
- },
35
- ];
36
- },
37
- });
@@ -1,5 +0,0 @@
1
- import { Linker } from './linker';
2
-
3
- export * from './linker';
4
-
5
- export default Linker;
@@ -1,153 +0,0 @@
1
- import { Node, mergeAttributes } from '@tiptap/core';
2
- import { NodeSelection } from '@tiptap/pm/state';
3
-
4
- /* Our own model of a link in a rich document. */
5
- export type LinkerAttributes = {
6
- href: string | null;
7
- target: '_blank' | null;
8
- title: string | null;
9
- 'data-id': string | null;
10
- 'data-app-prefix': string | null;
11
- };
12
-
13
- declare module '@tiptap/core' {
14
- interface Commands<ReturnType> {
15
- linker: {
16
- /**
17
- * Set a linker node
18
- */
19
- setLinker: (attributes: LinkerAttributes) => ReturnType;
20
- /**
21
- * Unset a linker node
22
- */
23
- unsetLinker: () => ReturnType;
24
- };
25
- }
26
- }
27
-
28
- /**
29
- * Internal links extension.
30
- * Reproduces the legacy angularJs "linker" directive.
31
- *
32
- * Links to internal resources MAY have a `title` and MUST HAVE `data-id` and `data-app-prefix` attributes :
33
- * `<a href="/blog#/view/35fa4198-blog_id/5e654c71-article_id" data-app-prefix="blog" data-id="35fa4198-blog_id" target="_blank" title="Voir ce billet de blog" class="ng-scope">/blog#/view/35fa4198-57fe-45eb-94f4-a5e4defff305/5e654c71-1e61-4f84-86dc-6fcfaf33f513</a>`
34
- */
35
- export const Linker = Node.create({
36
- name: 'linker',
37
- content: 'text*',
38
- marks: '',
39
- group: 'inline',
40
-
41
- inline: true,
42
- selectable: true,
43
- atom: true,
44
- draggable: true,
45
- isolating: true,
46
- allowGapCursor: false,
47
-
48
- priority: 1100,
49
- keepOnSplit: false,
50
-
51
- addOptions() {
52
- return {
53
- openOnClick: true,
54
- HTMLAttributes: {
55
- target: null,
56
- title: null,
57
- class: null,
58
- 'data-id': null,
59
- 'data-app-prefix': null,
60
- },
61
- validate: undefined,
62
- };
63
- },
64
-
65
- addAttributes() {
66
- return {
67
- href: {
68
- default: null,
69
- },
70
- class: {
71
- default: this.options.HTMLAttributes.class,
72
- },
73
- target: {
74
- default: this.options.HTMLAttributes.target,
75
- // Sanitize target value
76
- parseHTML: (element) =>
77
- element.getAttribute('target') !== '_blank' ? null : '_blank',
78
- },
79
- title: {
80
- default: this.options.HTMLAttributes.title,
81
- },
82
- 'data-id': {
83
- default: this.options.HTMLAttributes['data-id'],
84
- },
85
- 'data-app-prefix': {
86
- default: this.options.HTMLAttributes['data-app-prefix'],
87
- },
88
- };
89
- },
90
-
91
- parseHTML() {
92
- return [
93
- {
94
- tag: 'a[href]:not([href *= "javascript:" i])[data-id][data-app-prefix]',
95
- },
96
- ];
97
- },
98
-
99
- renderHTML({ HTMLAttributes }) {
100
- if (HTMLAttributes.href?.startsWith('javascript:')) {
101
- return [
102
- 'a',
103
- mergeAttributes(this.options.HTMLAttributes, {
104
- ...HTMLAttributes,
105
- href: '',
106
- }),
107
- 0,
108
- ];
109
- }
110
- return [
111
- 'a',
112
- mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
113
- 0,
114
- ];
115
- },
116
-
117
- addCommands() {
118
- return {
119
- setLinker:
120
- (attrs) =>
121
- ({ commands }) => {
122
- // Insert a Linker node with inner text node
123
- commands.insertContent({
124
- type: this.name,
125
- attrs,
126
- content: [
127
- {
128
- type: 'text',
129
- text: attrs.title,
130
- },
131
- ],
132
- });
133
- return true;
134
- },
135
-
136
- unsetLinker:
137
- () =>
138
- ({ state, tr }) => {
139
- // Which Linker node is actually selected ?
140
- const { node, from, to } = state.selection as NodeSelection;
141
- // Delete any selected Linker node
142
- if (node?.type.name === 'linker') {
143
- /* The following does not work as one would expected.
144
- commands.deleteNode(this.name);
145
- commands.deleteCurrentNode();
146
- * Replaced by : */
147
- tr.delete(from, to).scrollIntoView();
148
- }
149
- return true;
150
- },
151
- };
152
- },
153
- });
@@ -1,5 +0,0 @@
1
- import { MathJax } from './mathjax';
2
-
3
- export * from './mathjax';
4
-
5
- export default MathJax;
@@ -1,55 +0,0 @@
1
- import { Node } from '@tiptap/core';
2
-
3
- export const MathJax = Node.create({
4
- name: 'mathjaxnode',
5
- group: 'inline',
6
- inline: true,
7
- atom: false,
8
- selectable: true,
9
-
10
- parseHTML() {
11
- return [
12
- {
13
- tag: 'mathjax',
14
- },
15
- ];
16
- },
17
-
18
- addAttributes() {
19
- return {
20
- equation: {
21
- default: null,
22
- parseHTML: (element: any) => {
23
- const children = [...element.childNodes];
24
- const textNodes = children.filter((child) => child.nodeType === 3);
25
- return textNodes.length > 0
26
- ? textNodes[textNodes.length - 1].nodeValue
27
- : null;
28
- },
29
- },
30
- };
31
- },
32
-
33
- renderHTML({ HTMLAttributes }) {
34
- let equation = (HTMLAttributes.equation || '')
35
- // Get what is between \begin{equation}{... ...}\end{equation}
36
- // Or between \begin{equation}... ...\end{equation} without enclosing brackets
37
- .replaceAll(
38
- /(?:\\)?begin{equation}\s*\n?\s*{(.+?)}\n?\s*?(?:\\)?end{equation}/gm,
39
- '$$$1$$',
40
- )
41
- .replaceAll(
42
- /(?:\\)?begin{equation}\s*\n?\s*(.+?)\n?\s*?(?:\\)?end{equation}/gm,
43
- '$$$1$$',
44
- );
45
- if (equation.length > 0) {
46
- if (equation.charAt(0) !== '$') {
47
- equation = `$${equation}`;
48
- }
49
- if (equation.charAt(equation.length - 1) !== '$') {
50
- equation = `${equation}$`;
51
- }
52
- }
53
- return ['span', {}, equation];
54
- },
55
- });
@@ -1,5 +0,0 @@
1
- import { Paragraph } from './paragraph';
2
-
3
- export * from './paragraph';
4
-
5
- export default Paragraph;
@@ -1,25 +0,0 @@
1
- import { Paragraph as TiptapParagraph } from '@tiptap/extension-paragraph';
2
-
3
- /**
4
- * Extends `Paragraph` extension from TipTap.
5
- *
6
- * This extension is used to parse documents in old-format (version 0),
7
- * where text alignments were applied on a <div> wrapping a <span>.
8
- * The new format is a <p> with style attributes.
9
- *
10
- * For example :
11
- * `<div style="text-align: right;"><span style="font-size: 20pt;">A right-aligned text</span></div>`
12
- * is now parsed and rendered as
13
- * `<p style="text-align: right;"><span style="font-size: 20pt;">A right-aligned text</span></p>`
14
- */
15
- export const Paragraph = TiptapParagraph.extend({
16
- parseHTML() {
17
- const parentRules = this.parent?.() ?? [];
18
- return [
19
- ...parentRules,
20
- {
21
- tag: 'div[style]:has(> span)',
22
- },
23
- ];
24
- },
25
- });
@@ -1,5 +0,0 @@
1
- import { SpeechRecognition } from './speech-recognition';
2
-
3
- export * from './speech-recognition';
4
-
5
- export default SpeechRecognition;
@@ -1,123 +0,0 @@
1
- import { Node } from '@tiptap/core';
2
-
3
- export interface SpeechRecognitionOptions {
4
- lang: string;
5
- }
6
-
7
- declare module '@tiptap/core' {
8
- interface Commands<ReturnType> {
9
- SpeechRecognition: {
10
- startSpeechRecognition: () => ReturnType;
11
- stopSpeechRecognition: () => ReturnType;
12
- isSpeechRecognitionStarted: () => boolean;
13
- };
14
- }
15
- }
16
-
17
- class SR_Node<O = any, S = any> extends Node<O, S> {
18
- protected constructor() {
19
- super();
20
- }
21
-
22
- recognition: SpeechRecognition | undefined;
23
- readonly isStarted: boolean = false;
24
-
25
- static create<O = any, S = any>(config?: any) {
26
- return Node.create(config) as SR_Node<O, S>;
27
- }
28
- }
29
-
30
- export const SpeechRecognition = SR_Node.create<SpeechRecognitionOptions>({
31
- name: 'SpeechRecognition',
32
-
33
- addOptions() {
34
- return {
35
- lang: 'fr-FR',
36
- };
37
- },
38
-
39
- onCreate() {
40
- if (
41
- !('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)
42
- ) {
43
- console.warn(
44
- '"speechrecognition extension from @edifice.io/tiptap-extensions" requires a browser supporting the SpeechRecognition API".',
45
- );
46
- }
47
- },
48
-
49
- addCommands() {
50
- return {
51
- startSpeechRecognition:
52
- () =>
53
- ({ commands }) => {
54
- const SpeechRecognition =
55
- window.SpeechRecognition || window.webkitSpeechRecognition;
56
- this.recognition = new SpeechRecognition();
57
-
58
- this.recognition.lang = this.options.lang;
59
- this.recognition.interimResults = true;
60
- this.recognition.maxAlternatives = 1;
61
- this.recognition.continuous = true;
62
-
63
- this.recognition.start();
64
-
65
- // Memoize initial caret positions
66
- let { from, to } = this.editor.state.selection;
67
-
68
- this.recognition.onresult = (event: SpeechRecognitionEvent) => {
69
- let currentResult = '';
70
-
71
- // Add to the currentResult variable the content of the last recognized sentence
72
- for (let i = event.resultIndex; i < event.results.length; i++) {
73
- currentResult += event.results[i][0].transcript;
74
- }
75
-
76
- // Is this the final recognition ?
77
- const isFinal = event.results[event.results.length - 1].isFinal;
78
-
79
- // Replace selection by the last recognized sentence (+ style and select, if not final)
80
- this.editor.commands.deleteRange({ from, to });
81
- this.editor.commands.insertContentAt(
82
- from,
83
- isFinal ? currentResult : `<code>${currentResult}</code>`,
84
- { updateSelection: !isFinal },
85
- );
86
- to = this.editor.state.selection.to;
87
-
88
- if (isFinal) {
89
- // Next content will go after last insertion
90
- from = to;
91
- }
92
- };
93
-
94
- this.recognition.onerror = (event: SpeechRecognitionErrorEvent) => {
95
- // TODO create a "feedback" tiptap extension, to display user friendly error messages ?
96
- console.log(
97
- `[speechrecognition from @edifice.io/tiptap-extensions][error][${event.error}]: ${event.message}`,
98
- );
99
- };
100
-
101
- this.recognition.onstart = () => {
102
- this.isStarted = true;
103
- };
104
-
105
- this.recognition.onend = () => {
106
- this.isStarted = false;
107
- };
108
-
109
- return commands;
110
- },
111
-
112
- stopSpeechRecognition:
113
- () =>
114
- ({ commands }) => {
115
- this.recognition.stop();
116
- this.editor.commands.focus();
117
- return commands;
118
- },
119
-
120
- isSpeechRecognitionStarted: () => () => this.isStarted,
121
- };
122
- },
123
- });
@@ -1,5 +0,0 @@
1
- import { SpeechSynthesis } from './speech-synthesis';
2
-
3
- export * from './speech-synthesis';
4
-
5
- export default SpeechSynthesis;