jodit 3.23.3 → 3.24.2

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 (175) hide show
  1. package/README.md +4 -4
  2. package/build/jodit.css +8 -3
  3. package/build/jodit.es2018.css +7 -2
  4. package/build/jodit.es2018.en.css +7 -2
  5. package/build/jodit.es2018.en.js +8384 -7869
  6. package/build/jodit.es2018.en.min.css +1 -1
  7. package/build/jodit.es2018.en.min.js +1 -1
  8. package/build/jodit.es2018.js +8384 -7869
  9. package/build/jodit.es2018.min.css +1 -1
  10. package/build/jodit.es2018.min.js +1 -1
  11. package/build/jodit.js +2954 -2414
  12. package/build/jodit.min.css +2 -2
  13. package/build/jodit.min.js +1 -1
  14. package/build/plugins/debug/debug.es2018.en.js +8 -8
  15. package/build/plugins/debug/debug.es2018.en.min.js +1 -1
  16. package/build/plugins/debug/debug.es2018.js +8 -8
  17. package/build/plugins/debug/debug.es2018.min.js +1 -1
  18. package/build/plugins/debug/debug.js +8 -8
  19. package/build/plugins/debug/debug.min.js +1 -1
  20. package/build/plugins/speech-recognize/speech-recognize.css +1 -1
  21. package/build/plugins/speech-recognize/speech-recognize.es2018.css +1 -1
  22. package/build/plugins/speech-recognize/speech-recognize.es2018.en.css +1 -1
  23. package/build/plugins/speech-recognize/speech-recognize.es2018.en.js +38 -38
  24. package/build/plugins/speech-recognize/speech-recognize.es2018.en.min.js +1 -1
  25. package/build/plugins/speech-recognize/speech-recognize.es2018.js +38 -38
  26. package/build/plugins/speech-recognize/speech-recognize.es2018.min.js +1 -1
  27. package/build/plugins/speech-recognize/speech-recognize.js +30 -30
  28. package/build/plugins/speech-recognize/speech-recognize.min.js +1 -1
  29. package/build/vdom.css +12 -1
  30. package/build/vdom.js +1445 -41
  31. package/package.json +23 -23
  32. package/src/core/constants.ts +10 -8
  33. package/src/core/dom/dom.test.js +25 -0
  34. package/src/core/dom/dom.ts +90 -41
  35. package/src/core/helpers/checker/has-browser-color-picker.ts +2 -2
  36. package/src/core/helpers/checker/index.ts +1 -0
  37. package/src/core/helpers/checker/is-boolean.ts +1 -1
  38. package/src/core/helpers/checker/is-marker.ts +20 -0
  39. package/src/core/helpers/normalize/normalize-css-value.ts +19 -0
  40. package/src/core/helpers/normalize/normalize-node.ts +2 -2
  41. package/src/core/helpers/size/position.test.js +198 -187
  42. package/src/core/helpers/utils/css.ts +7 -14
  43. package/src/core/plugin/plugin.ts +1 -1
  44. package/src/core/selection/interface.ts +24 -0
  45. package/src/core/selection/select.ts +69 -29
  46. package/src/core/selection/selection.test.js +5 -17
  47. package/src/core/selection/style/api/extract.ts +6 -7
  48. package/src/core/selection/style/api/finite-state-machine.ts +40 -35
  49. package/src/core/selection/style/api/get-suit-child.ts +3 -4
  50. package/src/core/selection/style/api/get-suit-parent.ts +3 -4
  51. package/src/core/selection/style/api/{element-has-same-style.ts → has-same-style.ts} +25 -6
  52. package/src/core/selection/style/api/index.ts +6 -6
  53. package/src/core/selection/style/api/is-inside-invisible-element.ts +1 -1
  54. package/src/core/selection/style/api/is-normal-node.ts +3 -3
  55. package/src/core/selection/style/api/is-same-attributes.ts +56 -0
  56. package/src/core/selection/style/api/is-suit-element.ts +22 -12
  57. package/src/core/selection/style/api/list/toggle-ordered-list.ts +100 -0
  58. package/src/core/selection/style/api/list/wrap-list.ts +71 -0
  59. package/src/core/selection/style/api/toggle-attributes.ts +251 -0
  60. package/src/core/selection/style/api/unwrap-children.ts +10 -8
  61. package/src/core/selection/style/api/wrap-unwrapped-text.ts +7 -8
  62. package/src/core/selection/style/api/{wrap-and-commit-style.ts → wrap.ts} +8 -11
  63. package/src/core/selection/style/apply-style.ts +32 -181
  64. package/src/core/selection/style/commit-style.ts +79 -4
  65. package/src/core/selection/style/style.test.js +457 -128
  66. package/src/core/selection/style/transactions.ts +256 -0
  67. package/src/core/ui/button/tooltip/tooltip.test.js +95 -76
  68. package/src/core/ui/popup/popup.test.js +158 -153
  69. package/src/{plugins/backspace/interface.d.ts → core/vdom/on-demand.ts} +7 -5
  70. package/src/core/vdom/render/index.ts +2 -4
  71. package/src/core/vdom/render/patcher.ts +14 -0
  72. package/src/core/vdom/v-dom-jodit.less +17 -0
  73. package/src/core/vdom/v-dom-jodit.ts +102 -3
  74. package/src/core/view/view.ts +2 -2
  75. package/src/index.ts +2 -0
  76. package/src/jodit.ts +5 -1
  77. package/src/langs/i18n.test.js +221 -216
  78. package/src/modules/dialog/dialog.less +9 -1
  79. package/src/modules/dialog/dialog.ts +25 -16
  80. package/src/modules/file-browser/data-provider.ts +44 -12
  81. package/src/modules/file-browser/file-browser.test.js +1019 -958
  82. package/src/modules/file-browser/file-browser.ts +0 -1
  83. package/src/modules/messages/messages.ts +3 -8
  84. package/src/plugins/backspace/backspace.test.js +2 -9
  85. package/src/plugins/backspace/backspace.ts +5 -0
  86. package/src/plugins/backspace/cases/check-join-neighbors.ts +7 -1
  87. package/src/plugins/backspace/cases/check-join-two-lists.ts +2 -1
  88. package/src/plugins/backspace/helpers.ts +9 -1
  89. package/src/plugins/backspace/interface.ts +31 -0
  90. package/src/plugins/clean-html/helpers/visitor/filters/fill-empty-paragraph.ts +2 -1
  91. package/src/plugins/color/color.test.js +122 -119
  92. package/src/plugins/enter/enter.test.js +18 -5
  93. package/src/plugins/enter/enter.ts +9 -5
  94. package/src/plugins/enter/interface.ts +41 -0
  95. package/src/plugins/font/config.ts +8 -8
  96. package/src/plugins/font/font.test.js +18 -23
  97. package/src/plugins/hotkeys/hotkeys.test.js +35 -47
  98. package/src/plugins/iframe/iframe.test.js +206 -195
  99. package/src/plugins/image/image.ts +1 -1
  100. package/src/plugins/image-properties/config.ts +22 -0
  101. package/src/plugins/image-properties/image-properties.test.js +174 -93
  102. package/src/plugins/image-properties/templates/position-tab.ts +22 -1
  103. package/src/plugins/indent/indent.test.js +2 -8
  104. package/src/plugins/link/link.test.js +19 -0
  105. package/src/plugins/link/link.ts +25 -15
  106. package/src/plugins/placeholder/placeholder.ts +8 -7
  107. package/src/plugins/size/size.test.js +239 -225
  108. package/src/plugins/tab/cases/on-tab-inside-li.ts +131 -22
  109. package/src/plugins/tab/tab.test.js +95 -11
  110. package/src/plugins/tab/tab.ts +22 -2
  111. package/src/plugins/wrap-nodes/config.ts +11 -0
  112. package/src/plugins/wrap-nodes/wrap-nodes.ts +0 -1
  113. package/src/types/events.d.ts +4 -0
  114. package/src/types/file-browser.d.ts +17 -10
  115. package/src/types/select.d.ts +6 -1
  116. package/src/types/style.d.ts +72 -5
  117. package/src/types/uploader.d.ts +14 -0
  118. package/src/types/view.d.ts +2 -2
  119. package/types/core/async/async.d.ts +1 -1
  120. package/types/core/constants.d.ts +3 -3
  121. package/types/core/dom/dom.d.ts +6 -3
  122. package/types/core/helpers/checker/index.d.ts +1 -0
  123. package/types/core/helpers/checker/is-boolean.d.ts +1 -1
  124. package/types/core/helpers/checker/is-marker.d.ts +10 -0
  125. package/types/core/helpers/html/safe-html.d.ts +1 -1
  126. package/types/core/helpers/normalize/normalize-css-value.d.ts +2 -0
  127. package/types/core/helpers/normalize/normalize-node.d.ts +1 -1
  128. package/types/core/helpers/utils/append-script.d.ts +1 -1
  129. package/types/core/selection/interface.d.ts +19 -0
  130. package/types/core/selection/select.d.ts +22 -5
  131. package/types/core/selection/style/api/finite-state-machine.d.ts +10 -9
  132. package/types/core/selection/style/api/get-suit-child.d.ts +2 -3
  133. package/types/core/selection/style/api/get-suit-parent.d.ts +2 -3
  134. package/types/core/selection/style/api/{element-has-same-style.d.ts → has-same-style.d.ts} +2 -2
  135. package/types/core/selection/style/api/index.d.ts +6 -6
  136. package/types/core/selection/style/api/is-same-attributes.d.ts +12 -0
  137. package/types/core/selection/style/api/is-suit-element.d.ts +4 -4
  138. package/types/core/selection/style/api/{toggle → list}/toggle-ordered-list.d.ts +2 -3
  139. package/types/core/selection/style/api/{wrap-ordered-list.d.ts → list/wrap-list.d.ts} +2 -3
  140. package/types/core/selection/style/api/toggle-attributes.d.ts +11 -0
  141. package/types/core/selection/style/api/unwrap-children.d.ts +2 -2
  142. package/types/core/selection/style/api/wrap-unwrapped-text.d.ts +2 -3
  143. package/types/core/selection/style/api/{wrap-and-commit-style.d.ts → wrap.d.ts} +2 -3
  144. package/types/core/selection/style/apply-style.d.ts +3 -3
  145. package/types/core/selection/style/commit-style.d.ts +6 -2
  146. package/types/core/selection/style/transactions.d.ts +29 -0
  147. package/types/core/ui/popup/popup.d.ts +1 -1
  148. package/types/core/view/view.d.ts +1 -1
  149. package/types/index.d.ts +2 -0
  150. package/types/modules/file-browser/builders/elements-map.d.ts +1 -1
  151. package/types/modules/file-browser/data-provider.d.ts +5 -0
  152. package/types/modules/messages/messages.d.ts +2 -1
  153. package/types/plugins/backspace/helpers.d.ts +5 -1
  154. package/types/plugins/backspace/interface.d.ts +21 -0
  155. package/types/plugins/enter/enter.d.ts +2 -0
  156. package/types/plugins/enter/interface.d.ts +32 -0
  157. package/types/plugins/image-properties/config.d.ts +19 -0
  158. package/types/plugins/link/link.d.ts +1 -1
  159. package/types/plugins/paste/interface.d.ts +2 -2
  160. package/types/plugins/tab/cases/on-tab-inside-li.d.ts +1 -1
  161. package/types/plugins/wrap-nodes/config.d.ts +10 -0
  162. package/types/types/events.d.ts +4 -0
  163. package/types/types/file-browser.d.ts +17 -10
  164. package/types/types/select.d.ts +6 -1
  165. package/types/types/storage.d.ts +1 -1
  166. package/types/types/style.d.ts +72 -5
  167. package/types/types/uploader.d.ts +14 -0
  168. package/types/types/view.d.ts +2 -2
  169. package/vdom.html +20 -0
  170. package/src/core/selection/style/api/toggle/toggle-css.ts +0 -136
  171. package/src/core/selection/style/api/toggle/toggle-ordered-list.ts +0 -54
  172. package/src/core/selection/style/api/toggle-commit-styles.ts +0 -35
  173. package/src/core/selection/style/api/wrap-ordered-list.ts +0 -42
  174. package/types/core/selection/style/api/toggle/toggle-css.d.ts +0 -12
  175. package/types/core/selection/style/api/toggle-commit-styles.d.ts +0 -13
@@ -4,6 +4,8 @@
4
4
  * Copyright (c) 2013-2022 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
+ const { Dom } = Jodit.modules;
8
+
7
9
  describe('Apply style', () => {
8
10
  describe('Test Style module', function () {
9
11
  let editor;
@@ -18,6 +20,26 @@ describe('Apply style', () => {
18
20
 
19
21
  describe('Base apply', () => {
20
22
  [
23
+ [
24
+ '<p><strong>|test</strong> pop <strong>test|</strong></p>',
25
+ {
26
+ element: 'strong'
27
+ },
28
+ '<p>|test pop test|</p>'
29
+ ],
30
+ [
31
+ '<p><strong>|test</strong> pop <strong>test|</strong></p>',
32
+ {
33
+ element: 'strong',
34
+ attributes: { style: { fontWeight: 700 } }
35
+ },
36
+ '<p>|test pop test|</p>'
37
+ ],
38
+ [
39
+ '<p>|test|</p>',
40
+ { element: 'strong' },
41
+ '<p>|<strong>test</strong>|</p>'
42
+ ],
21
43
  [
22
44
  '<p>|test|</p>',
23
45
  {
@@ -32,6 +54,68 @@ describe('Apply style', () => {
32
54
  },
33
55
  '<p>|test|</p>'
34
56
  ],
57
+ [
58
+ '<p>|test|</p>',
59
+ {
60
+ element: 'a',
61
+ attributes: {
62
+ href: 'https://xdsoft.net'
63
+ }
64
+ },
65
+ '<p>|<a href="https://xdsoft.net">test</a>|</p>'
66
+ ],
67
+ [
68
+ '<p>|test|</p>',
69
+ {
70
+ element: 'h1',
71
+ attributes: {
72
+ class: 'header'
73
+ }
74
+ },
75
+ '<h1 class="header">|test|</h1>'
76
+ ],
77
+ [
78
+ '<p><a href="https://xdsoft.net">|test|</a></p>',
79
+ {
80
+ element: 'a',
81
+ attributes: {
82
+ href: 'https://xdsoft.net'
83
+ }
84
+ },
85
+ '<p>|test|</p>'
86
+ ],
87
+ [
88
+ '<p><a href="https://xdsoft.net">|test|</a></p>',
89
+ {
90
+ element: 'a',
91
+ attributes: {
92
+ title: 'book',
93
+ href: 'https://sitename.net'
94
+ }
95
+ },
96
+ '<p><a href="https://sitename.net" title="book">|test|</a></p>'
97
+ ],
98
+ [
99
+ '<p><span>|test|</span></p>',
100
+ {
101
+ element: 'a',
102
+ attributes: {
103
+ title: 'book',
104
+ href: 'https://sitename.net'
105
+ }
106
+ },
107
+ '<p><span>|<a href="https://sitename.net" title="book">test</a>|</span></p>'
108
+ ],
109
+ [
110
+ '<p><a href="https://xdsoft.net">|test|</a></p>',
111
+ {
112
+ element: 'a',
113
+ attributes: {
114
+ href: 'https://sitename.net'
115
+ }
116
+ },
117
+ '<p><a href="https://sitename.net">|test|</a></p>'
118
+ ],
35
119
  [
36
120
  '<p><strong style="font-family: Impact, Charcoal, sans-serif;"><em>|test|</em></strong></p>',
37
121
  {
@@ -40,22 +124,48 @@ describe('Apply style', () => {
40
124
  '<p><span style="font-family:Impact,Charcoal,sans-serif"><em>|test|</em></span></p>'
41
125
  ],
42
126
  [
43
- '<p>|Hello world|</p>',
127
+ '<p><strong>|test|</strong></p>',
44
128
  {
45
- element: 'ul',
46
- style: {
47
- listStyleType: 'circle'
48
- }
129
+ className: 'class1'
49
130
  },
50
- '<ul style="list-style-type:circle"><li>|Hello world|</li></ul>'
131
+ '<p><strong class="class1">|test|</strong></p>'
51
132
  ],
52
133
  [
53
134
  '<p><strong>|test|</strong></p>',
54
135
  {
55
- className: 'class1'
136
+ attributes: {
137
+ class: 'class1'
138
+ }
56
139
  },
57
140
  '<p><strong class="class1">|test|</strong></p>'
58
141
  ],
142
+ [
143
+ '<p><strong class="class2">|test|</strong></p>',
144
+ {
145
+ attributes: {
146
+ class: 'class1'
147
+ }
148
+ },
149
+ '<p><strong class="class2 class1">|test|</strong></p>'
150
+ ],
151
+ [
152
+ '<p><strong class="class1">|test|</strong></p>',
153
+ {
154
+ attributes: {
155
+ class: 'class1'
156
+ }
157
+ },
158
+ '<p><strong>|test|</strong></p>'
159
+ ],
160
+ [
161
+ '<p><strong class="class1 class2">|test|</strong></p>',
162
+ {
163
+ attributes: {
164
+ class: 'class1'
165
+ }
166
+ },
167
+ '<p><strong class="class2">|test|</strong></p>'
168
+ ],
59
169
  [
60
170
  '<p><strong>|test|</strong></p>',
61
171
  {
@@ -97,7 +207,7 @@ describe('Apply style', () => {
97
207
  '<p>|test|</p>'
98
208
  ],
99
209
  [
100
- // (st) => getClosestWrapper -> extractSelectedPart -> toggleCommitStyles -> unwrap -> toggleCSS
210
+ // (st) => getClosestWrapper -> extractSelectedPart -> toggleICommitStyles -> unwrap -> toggleCSS
101
211
  // (so) => ----
102
212
  '<p><strong>te|st</strong> so|me</p>',
103
213
  {
@@ -133,24 +243,218 @@ describe('Apply style', () => {
133
243
  { style: { fontFamily: 'Helvetica,sans-serif' } },
134
244
  '<p>|<span style="font-family:Helvetica,sans-serif">test</span></p><style>.a {color: red}</style><p><span style="font-family:Helvetica,sans-serif">stop</span>|</p>'
135
245
  ],
246
+ [
247
+ '<p>test|<u>test</u>|test</p>',
248
+ { style: { color: '#FFF000' } },
249
+ '<p>test|<u style="color:#FFF000">test</u>|test</p>'
250
+ ],
251
+ [
252
+ '<p><u>|test|</u></p>',
253
+ { style: { color: '#FFF000' } },
254
+ '<p><u style="color:#FFF000">|test|</u></p>'
255
+ ],
256
+ [
257
+ '<p>|<u>test</u>|</p>',
258
+ { style: { color: '#FFF000' } },
259
+ '<p>|<u style="color:#FFF000">test</u>|</p>'
260
+ ],
261
+ [
262
+ '<p><u>|tes|t</u></p>',
263
+ { style: { color: '#FFF000' } },
264
+ '<p><u>|<span style="color:#FFF000">tes</span>|t</u></p>'
265
+ ],
266
+ [
267
+ '<p><strong>|test|</strong></p>',
268
+ { style: { color: '#FFF000' } },
269
+ '<p><strong style="color:#FFF000">|test|</strong></p>'
270
+ ],
271
+ [
272
+ '<p>test|</p>',
273
+ { element: 'strong' },
274
+ '<p>test<strong>|</strong></p>'
275
+ ],
276
+ [
277
+ '<p><strong>|test|</strong></p>',
278
+ { element: 'strong' },
279
+ '<p>|test|</p>'
280
+ ],
281
+ [
282
+ '<p><strong>te|s|t</strong></p>',
283
+ { element: 'strong' },
284
+ '<p><strong>te</strong>|s|<strong>t</strong></p>'
285
+ ],
286
+ [
287
+ '<p>te|s|t</p>',
288
+ {
289
+ style: {
290
+ color: '#fff'
291
+ }
292
+ },
293
+ '<p>te|<span style="color:#FFFFFF">s</span>|t</p>'
294
+ ],
295
+ [
296
+ '<p>te|st</p>',
297
+ {
298
+ style: {
299
+ color: '#fff'
300
+ }
301
+ },
302
+ '<p>te<span style="color:#FFFFFF">|</span>st</p>'
303
+ ],
304
+ [
305
+ '<p>|test|</p>',
306
+ {
307
+ style: {
308
+ color: 'red',
309
+ backgroundColor: 'yellow'
310
+ }
311
+ },
312
+ '<p>|<span style="background-color:yellow;color:red">test</span>|</p>'
313
+ ],
314
+ [
315
+ '<p>|test <span style="color:#FFFFFF">test</span> test|</p>',
316
+ {
317
+ style: {
318
+ color: '#00FF00'
319
+ }
320
+ },
321
+ '<p>|<span style="color:#00FF00">test test test</span>|</p>'
322
+ ],
323
+ [
324
+ '<p>|test <strong>test</strong> test|</p>',
325
+ {
326
+ element: 'strong'
327
+ },
328
+ '<p>|<strong>test test test</strong>|</p>'
329
+ ],
330
+ [
331
+ '<p>|<strong>test test</strong> test|</p>',
332
+ {
333
+ element: 'strong'
334
+ },
335
+ '<p>|test test test|</p>'
336
+ ],
337
+ [
338
+ '<p>|pop <strong>test test</strong> test|</p>',
339
+ {
340
+ element: 'strong'
341
+ },
342
+ '<p>|<strong>pop test test test</strong>|</p>'
343
+ ],
344
+ [
345
+ '<h3><span style="color:#00FF00">|pop test test test|</span></h3>',
346
+ {
347
+ element: 'p'
348
+ },
349
+ '<p><span style="color:#00FF00">|pop test test test|</span></p>'
350
+ ],
351
+ [
352
+ 'test|<br>test<br>test<br>test',
353
+ { element: 'h1' },
354
+ '<h1>test|</h1><br>test<br>test<br>test',
355
+ { enter: 'BR' }
356
+ ],
357
+ // Lists
358
+ [
359
+ '<ol><li>ordered</li><li>|list</li><li>pop</li></ol>',
360
+ { element: 'ul' },
361
+ '<ol><li>ordered</li></ol><ul><li>|list</li></ul><ol><li>pop</li></ol>'
362
+ ],
363
+ [
364
+ '<ol><li>|ordered</li><li>list</li></ol><p>test|</p>',
365
+ { element: 'ol' },
366
+ '<p>|ordered</p><p>list</p><p>test|</p>'
367
+ ],
368
+ [
369
+ '<p>|test</p><ol><li>ordered</li><li>list|</li></ol>',
370
+ { element: 'ol' },
371
+ '<ol><li>|test</li><li>ordered</li><li>list|</li></ol>'
372
+ ],
373
+ [
374
+ '<ol><li>ordered</li></ol><p>|test</p><ol><li>list</li><li>pop</li></ol>',
375
+ { element: 'ol' },
376
+ '<ol><li>ordered</li><li>|test</li><li>list</li><li>pop</li></ol>'
377
+ ],
378
+ [
379
+ '<ul><li>ordered</li></ul><p>|test</p><ol><li>list</li><li>pop</li></ol>',
380
+ { element: 'ol' },
381
+ '<ul><li>ordered</li></ul><ol><li>|test</li><li>list</li><li>pop</li></ol>'
382
+ ],
383
+ [
384
+ '<ul><li>ordered</li></ul><p>|test</p><ol><li>list</li><li>pop</li></ol>',
385
+ { element: 'ul' },
386
+ '<ul><li>ordered</li><li>|test</li></ul><ol><li>list</li><li>pop</li></ol>'
387
+ ],
388
+ [
389
+ '<ol class="p"><li>ordered</li></ol><p>|test</p><ol><li>list</li><li>pop</li></ol>',
390
+ { element: 'ol' },
391
+ '<ol class="p"><li>ordered</li><li>|test</li></ol><ol><li>list</li><li>pop</li></ol>'
392
+ ],
393
+ [
394
+ '<ol><li>ordered</li><li>list</li></ol><p>|test</p><p>pop|</p>',
395
+ { element: 'ol' },
396
+ '<ol><li>ordered</li><li>list</li><li>|test</li><li>pop|</li></ol>'
397
+ ],
398
+ [
399
+ '<p>|test</p><p>pop|</p><ol><li>ordered</li><li>list</li></ol>',
400
+ { element: 'ol' },
401
+ '<ol><li>|test</li><li>pop|</li><li>ordered</li><li>list</li></ol>'
402
+ ],
403
+ [
404
+ '<p>|test</p><ol><li>ordered</li><li>list</li></ol>',
405
+ { element: 'ol' },
406
+ '<ol><li>|test</li><li>ordered</li><li>list</li></ol>'
407
+ ],
408
+ [
409
+ '<p>|Hello world|</p>',
410
+ {
411
+ element: 'ul',
412
+ style: {
413
+ listStyleType: 'circle'
414
+ }
415
+ },
416
+ '<ul style="list-style-type:circle"><li>|Hello world|</li></ul>'
417
+ ],
136
418
  [
137
419
  '<p>|test</p><p>ordered</p><p>list|</p>',
138
420
  { element: 'ol' },
139
421
  '<ol><li>|test</li><li>ordered</li><li>list|</li></ol>'
140
422
  ],
141
-
423
+ [
424
+ '<p>|test</p><p>ordered</p><p>list|</p>',
425
+ { element: 'ol', attributes: { class: 'test' } },
426
+ '<ol class="test"><li>|test</li><li>ordered</li><li>list|</li></ol>'
427
+ ],
428
+ [
429
+ '<p>|test</p><p>ordered</p><p>list</p><p>a few</p><p>leafs|</p>',
430
+ { element: 'ol', attributes: { class: 'test' } },
431
+ '<ol class="test"><li>|test</li><li>ordered</li><li>list</li><li>a few</li><li>leafs|</li></ol>'
432
+ ],
433
+ [
434
+ '<p>|text</p><p>pop</p><p>oup</p><p>test|</p>',
435
+ {
436
+ element: 'ul',
437
+ attributes: {
438
+ class: 'todo-list2'
439
+ }
440
+ },
441
+ '<ul class="todo-list2"><li>|text</li><li>pop</li><li>oup</li><li>test|</li></ul>'
442
+ ],
443
+ [
444
+ '<p>|test</p><p>ordered</p><p>list</p><p>a few</p><p>leafs|</p>',
445
+ { element: 'ul', attributes: { class: 'test' } },
446
+ '<ul class="test"><li>|test</li><li>ordered</li><li>list</li><li>a few</li><li>leafs|</li></ul>'
447
+ ],
142
448
  [
143
449
  '<p>|test</p><p>ordered</p><p>list|</p>',
144
450
  { element: 'ol', style: { listStyleType: null } },
145
451
  '<ol><li>|test</li><li>ordered</li><li>list|</li></ol>'
146
452
  ],
147
-
148
453
  [
149
454
  '<p>|test1</p>\n\n<p>ordered</p>\n\n<p>list1|</p>',
150
455
  { element: 'ol' },
151
456
  '<ol><li>|test1</li><li>ordered</li><li>list1|</li></ol>'
152
457
  ],
153
-
154
458
  [
155
459
  '<h1>|test</h1><p>ordered</p><p>list|</p>',
156
460
  { element: 'ol' },
@@ -166,6 +470,31 @@ describe('Apply style', () => {
166
470
  { element: 'ol' },
167
471
  '<p>|test</p><ol><li>ordered</li><li>list</li></ol>'
168
472
  ],
473
+ [
474
+ '<ol><li>|1</li><li>2</li><li>3</li></ol><ul><li>4</li><li>5</li><li>6|</li></ul>',
475
+ { element: 'ol' },
476
+ '<p>|1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6|</p>'
477
+ ],
478
+ [
479
+ '<ol><li>|1</li><li>2</li><li>3</li></ol><ul><li>4</li><li>5</li><li>6|</li></ul>',
480
+ { element: 'ul' },
481
+ '<ul><li>|1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6|</li></ul>'
482
+ ],
483
+ [
484
+ '<ol><li>|1</li><li>2</li><li>3</li></ol><ul><li>4</li><li>5</li></ul><p>6|</p>',
485
+ { element: 'ul' },
486
+ '<ul><li>|1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6|</li></ul>'
487
+ ],
488
+ [
489
+ '<ol><li>|1</li><li>2</li><li>3</li></ol><ul><li>3.5</li></ul><ul><li>4</li><li>5</li></ul><p>6|</p>',
490
+ { element: 'ul' },
491
+ '<ul><li>|1</li><li>2</li><li>3</li><li>3.5</li><li>4</li><li>5</li><li>6|</li></ul>'
492
+ ],
493
+ [
494
+ '<ol><li>|1</li><li>2</li><li>3</li></ol><ol><li>3.5</li></ol><ul><li>4</li><li>5</li></ul><p>6|</p>',
495
+ { element: 'ul' },
496
+ '<ul><li>|1</li><li>2</li><li>3</li><li>3.5</li><li>4</li><li>5</li><li>6|</li></ul>'
497
+ ],
169
498
  [
170
499
  '<ol><li>test</li><li>ord|ered</li><li>list</li></ol>',
171
500
  { element: 'ol' },
@@ -176,19 +505,41 @@ describe('Apply style', () => {
176
505
  { element: 'ol' },
177
506
  '<p>|test</p><p>ordered</p><p>list|</p>'
178
507
  ],
179
-
180
508
  [
181
509
  '<ul><li>|test</li><li>unordered</li><li>list|</li></ul>',
182
510
  { element: 'ul' },
183
511
  '<p>|test</p><p>unordered</p><p>list|</p>'
184
512
  ],
185
-
186
513
  [
187
514
  '<ul><li>|test</li><li>unordered</li><li>list|</li></ul>',
188
515
  { element: 'ol' },
189
516
  '<ol><li>|test</li><li>unordered</li><li>list|</li></ol>'
190
517
  ],
191
-
518
+ [
519
+ '<ul><li>test</li><li>unordered|</li><li>list</li></ul>',
520
+ { element: 'ul' },
521
+ '<ul><li>test</li></ul><p>unordered|</p><ul><li>list</li></ul>'
522
+ ],
523
+ [
524
+ '<ul><li>test</li></ul><p>unordered|</p><ul><li>list</li></ul>',
525
+ { element: 'ul' },
526
+ '<ul><li>test</li><li>unordered|</li><li>list</li></ul>'
527
+ ],
528
+ [
529
+ '<ul class="test"><li>test</li></ul><p>unordered|</p><ul class="test"><li>list</li></ul>',
530
+ { element: 'ul', attributes: { class: 'test' } },
531
+ '<ul class="test"><li>test</li><li>unordered|</li><li>list</li></ul>'
532
+ ],
533
+ [
534
+ '<ul><li>test</li><li>unor|der|ed</li><li>list</li></ul>',
535
+ { element: 'ul' },
536
+ '<ul><li>test</li></ul><p>unor|der|ed</p><ul><li>list</li></ul>'
537
+ ],
538
+ [
539
+ '<ul><li>test</li><li>unor|der|ed</li><li>list</li></ul>',
540
+ { element: 'ul', attributes: { class: 'test' } },
541
+ '<ul><li>test</li></ul><ul class="test"><li>unor|der|ed</li></ul><ul><li>list</li></ul>'
542
+ ],
192
543
  [
193
544
  '<ul><li>|test</li><li>unordered</li><li>list|</li></ul>',
194
545
  {
@@ -197,7 +548,6 @@ describe('Apply style', () => {
197
548
  },
198
549
  '<ol style="list-style-type:lower-roman"><li>|test</li><li>unordered</li><li>list|</li></ol>'
199
550
  ],
200
-
201
551
  [
202
552
  '<ol><li>|test</li><li>unordered</li><li>list|</li></ol>',
203
553
  {
@@ -206,7 +556,6 @@ describe('Apply style', () => {
206
556
  },
207
557
  '<ol style="list-style-type:lower-roman"><li>|test</li><li>unordered</li><li>list|</li></ol>'
208
558
  ],
209
-
210
559
  [
211
560
  '<ol style="list-style-type:lower-roman"><li>|test</li><li>ordered</li><li>list|</li></ol>',
212
561
  {
@@ -215,7 +564,6 @@ describe('Apply style', () => {
215
564
  },
216
565
  '<p>|test</p><p>ordered</p><p>list|</p>'
217
566
  ],
218
-
219
567
  [
220
568
  '<ol style="list-style-type:lower-alpha"><li>|test</li><li>unordered</li><li>list|</li></ol>',
221
569
  {
@@ -224,31 +572,26 @@ describe('Apply style', () => {
224
572
  },
225
573
  '<ol style="list-style-type:lower-roman"><li>|test</li><li>unordered</li><li>list|</li></ol>'
226
574
  ],
227
-
228
575
  [
229
576
  '<p>|test</p><p>ordered</p><p>list|</p>',
230
577
  { element: 'ol' },
231
578
  '<ol><li>|test</li><li>ordered</li><li>list|</li></ol>'
232
579
  ],
233
-
234
580
  [
235
581
  '<p>|test</p><p>ordered</p><p>list</p>',
236
582
  { element: 'ol' },
237
583
  '<ol><li>|test</li></ol><p>ordered</p><p>list</p>'
238
584
  ],
239
-
240
585
  [
241
586
  '<h1>|test</h1><p>ordered</p><p>list|</p>',
242
587
  { element: 'ol' },
243
588
  '<ol><li>|test</li><li>ordered</li><li>list|</li></ol>'
244
589
  ],
245
-
246
590
  [
247
591
  '<p>te|st</p><p>ordered</p><p>li|st</p>',
248
592
  { element: 'ol' },
249
593
  '<ol><li>te|st</li><li>ordered</li><li>li|st</li></ol>'
250
594
  ],
251
-
252
595
  [
253
596
  '<p>|test</p><p>unordered</p><p>list|</p>',
254
597
  { element: 'ul' },
@@ -257,130 +600,107 @@ describe('Apply style', () => {
257
600
  [
258
601
  '<ul><li>|1</li><li>2</li><li>3|</li></ul>',
259
602
  { element: 'h1' },
260
- '<ul><li><h1>|1</h1></li><li><h1>2</h1></li><li><h1>3|</h1></li></ul>'
261
- ],
262
-
263
- [
264
- 'test|<br>test<br>test<br>test',
265
- { element: 'h1' },
266
- '<h1>test|</h1><br>test<br>test<br>test',
267
- { enter: 'BR' }
603
+ '<ul><li>|<h1>1</h1></li><li><h1>2</h1></li><li><h1>3</h1>|</li></ul>'
268
604
  ],
269
-
270
605
  [
271
606
  '<ul><li><h1>|1</h1></li><li><h1>2</h1></li><li><h1>3|</h1></li></ul>',
272
607
  { element: 'h1' },
273
608
  '<ul><li>|1</li><li>2</li><li>3|</li></ul>'
274
609
  ],
275
610
  [
276
- '<p>test|<u>test</u>|test</p>',
277
- { style: { color: '#FFF000' } },
278
- '<p>test|<u style="color:#FFF000">test</u>|test</p>'
279
- ],
280
- [
281
- '<p><u>|test|</u></p>',
282
- { style: { color: '#FFF000' } },
283
- '<p><u style="color:#FFF000">|test|</u></p>'
284
- ],
285
- [
286
- '<p>|<u>test</u>|</p>',
287
- { style: { color: '#FFF000' } },
288
- '<p>|<u style="color:#FFF000">test</u>|</p>'
289
- ],
290
- [
291
- '<p><u>|tes|t</u></p>',
292
- { style: { color: '#FFF000' } },
293
- '<p><u>|<span style="color:#FFF000">tes</span>|t</u></p>'
294
- ],
295
- [
296
- '<p><strong>|test|</strong></p>',
297
- { style: { color: '#FFF000' } },
298
- '<p><strong style="color:#FFF000">|test|</strong></p>'
299
- ],
300
- [
301
- '<p>|test|</p>',
302
- { element: 'strong' },
303
- '<p>|<strong>test</strong>|</p>'
304
- ],
305
- [
306
- '<p>test|</p>',
307
- { element: 'strong' },
308
- '<p>test<strong>|</strong></p>'
309
- ],
310
- [
311
- '<p><strong>|test|</strong></p>',
312
- { element: 'strong' },
313
- '<p>|test|</p>'
314
- ],
315
- [
316
- '<p><strong>te|s|t</strong></p>',
317
- { element: 'strong' },
318
- '<p><strong>te</strong>|s|<strong>t</strong></p>'
319
- ],
320
- [
321
- '<p>te|s|t</p>',
322
- {
323
- style: {
324
- color: '#fff'
325
- }
326
- },
327
- '<p>te|<span style="color:#FFFFFF">s</span>|t</p>'
328
- ],
329
- [
330
- '<p>te|st</p>',
331
- {
332
- style: {
333
- color: '#fff'
334
- }
335
- },
336
- '<p>te<span style="color:#FFFFFF">|</span>st</p>'
337
- ],
338
- [
339
- '<p>|test|</p>',
611
+ '<ul class="todo-list"><li>test|</li></ul>',
340
612
  {
341
- style: {
342
- color: 'red',
343
- backgroundColor: 'yellow'
613
+ element: 'ul',
614
+ hooks: {
615
+ beforeToggleList(mode, style, list) {
616
+ Dom.replace(
617
+ list,
618
+ style.element,
619
+ editor.createInside
620
+ );
621
+ return 'replace';
622
+ }
344
623
  }
345
624
  },
346
- '<p>|<span style="background-color:yellow;color:red">test</span>|</p>'
625
+ '<ul><li>test|</li></ul>'
347
626
  ],
348
627
  [
349
- '<p>|test <span style="color:#FFFFFF">test</span> test|</p>',
628
+ '<ul class="todo-list"><li>test|</li></ul>',
350
629
  {
351
- style: {
352
- color: '#00FF00'
630
+ element: 'ul',
631
+ hooks: {
632
+ afterToggleList(mode, li) {
633
+ if (mode === 'unwrap') {
634
+ li.setAttribute('replaced', true);
635
+ }
636
+ }
353
637
  }
354
638
  },
355
- '<p>|<span style="color:#00FF00">test test test</span>|</p>'
356
- ],
357
- [
358
- '<p>|test <strong>test</strong> test|</p>',
639
+ '<p replaced="true">test|</p>',
359
640
  {
360
- element: 'strong'
361
- },
362
- '<p>|<strong>test test test</strong>|</p>'
641
+ disablePlugins: ['todo-list']
642
+ }
363
643
  ],
364
644
  [
365
- '<p>|<strong>test test</strong> test|</p>',
645
+ '<ul class="todo-list"><li>test|</li></ul>',
366
646
  {
367
- element: 'strong'
647
+ element: 'ol'
368
648
  },
369
- '<p>|test test test|</p>'
649
+ '<ol><li>test|</li></ol>'
370
650
  ],
371
651
  [
372
- '<p>|pop <strong>test test</strong> test|</p>',
652
+ '<p>|test|</p>',
373
653
  {
374
- element: 'strong'
654
+ element: 'ul',
655
+ hooks: {
656
+ beforeWrapList(_, wrapper) {
657
+ const li = Dom.replace(
658
+ wrapper,
659
+ 'li',
660
+ editor.createInside
661
+ );
662
+
663
+ const label = editor.createInside.element(
664
+ 'label',
665
+ { class: 'jodit_todo_label' }
666
+ );
667
+
668
+ const input = editor.createInside.element(
669
+ 'input',
670
+ {
671
+ type: 'checkbox'
672
+ }
673
+ );
674
+ label.appendChild(input);
675
+ Dom.prepend(li, label);
676
+
677
+ return li;
678
+ }
679
+ },
680
+ attributes: {
681
+ class: 'todo-list'
682
+ }
375
683
  },
376
- '<p>|<strong>pop test test test</strong>|</p>'
684
+ '<ul class="todo-list"><li><label class="jodit_todo_label"><input type="checkbox"></label>|test|</li></ul>'
377
685
  ],
378
686
  [
379
- '<h3><span style="color:#00FF00">|pop test test test|</span></h3>',
687
+ '<p>|pop|</p>',
380
688
  {
381
- element: 'p'
689
+ element: 'ul',
690
+ hooks: {
691
+ afterWrapList(_, wrapper, style) {
692
+ wrapper.querySelectorAll('li').forEach(li => {
693
+ li.className =
694
+ 'test ' +
695
+ style.options.attributes.class;
696
+ });
697
+ }
698
+ },
699
+ attributes: {
700
+ class: 'todo-list'
701
+ }
382
702
  },
383
- '<p><span style="color:#00FF00">|pop test test test|</span></p>'
703
+ '<ul class="todo-list"><li class="test todo-list">|pop|</li></ul>'
384
704
  ]
385
705
  ].forEach(([input, opt, output, jSettings]) => {
386
706
  describe(`For selection ${input} apply style ${JSON.stringify(
@@ -568,7 +888,12 @@ describe('Apply style', () => {
568
888
  '<p>test<span style="font-size:12px">stop</span></p>'
569
889
  );
570
890
 
571
- style.apply(editor);
891
+ const style2 = new Style({
892
+ style: {
893
+ fontSize: 12
894
+ }
895
+ });
896
+ style2.apply(editor);
572
897
 
573
898
  editor.s.insertHTML('elem');
574
899
 
@@ -580,7 +905,7 @@ describe('Apply style', () => {
580
905
  });
581
906
 
582
907
  describe('Without editing', function () {
583
- it('Should unwap empty SPAN', function () {
908
+ it('Should unwrap empty SPAN', function () {
584
909
  editor.value = '<p>test|</p>';
585
910
  setCursorToChar(editor);
586
911
 
@@ -590,9 +915,15 @@ describe('Apply style', () => {
590
915
  }
591
916
  });
592
917
 
593
- style.apply(editor);
594
918
  style.apply(editor);
595
919
 
920
+ const style2 = new Style({
921
+ style: {
922
+ fontSize: 12
923
+ }
924
+ });
925
+ style2.apply(editor);
926
+
596
927
  editor.s.insertHTML('elem');
597
928
 
598
929
  expect(sortAttributes(editor.value)).equals(
@@ -931,9 +1262,8 @@ describe('Apply style', () => {
931
1262
 
932
1263
  describe('Double times', function () {
933
1264
  it('Should create new SPAN inside first', function () {
934
- editor.s.setCursorAfter(
935
- editor.editor.firstChild.firstChild
936
- );
1265
+ editor.value = '<p>test|</p>';
1266
+ setCursorToChar(editor);
937
1267
 
938
1268
  const style = new Style({
939
1269
  style: {
@@ -960,11 +1290,10 @@ describe('Apply style', () => {
960
1290
  );
961
1291
  });
962
1292
 
963
- describe('With same style', function () {
1293
+ describe('With same style 1', function () {
964
1294
  it('Should break first SPAN', function () {
965
- editor.s.setCursorAfter(
966
- editor.editor.firstChild.firstChild
967
- );
1295
+ editor.value = '<p>test|</p>';
1296
+ setCursorToChar(editor);
968
1297
 
969
1298
  const style = new Style({
970
1299
  style: {