jodit 3.9.3 → 3.10.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 (214) hide show
  1. package/.idea/workspace.xml +306 -295
  2. package/CHANGELOG.MD +349 -119
  3. package/build/jodit.css +675 -538
  4. package/build/jodit.es2018.css +536 -436
  5. package/build/jodit.es2018.en.css +536 -436
  6. package/build/jodit.es2018.en.js +1529 -738
  7. package/build/jodit.es2018.en.min.css +1 -1
  8. package/build/jodit.es2018.en.min.js +1 -1
  9. package/build/jodit.es2018.js +1533 -742
  10. package/build/jodit.es2018.min.css +1 -1
  11. package/build/jodit.es2018.min.js +1 -1
  12. package/build/jodit.js +2598 -1680
  13. package/build/jodit.min.css +2 -2
  14. package/build/jodit.min.js +1 -1
  15. package/index.d.ts +10 -0
  16. package/package.json +10 -10
  17. package/src/config.ts +19 -20
  18. package/src/core/component/component.ts +16 -15
  19. package/src/core/component/statuses.ts +6 -6
  20. package/src/core/dom.ts +16 -4
  21. package/src/core/events/event-emitter.ts +4 -2
  22. package/src/core/global.ts +13 -2
  23. package/src/core/helpers/append-script.ts +14 -0
  24. package/src/core/helpers/selector.ts +8 -3
  25. package/src/core/helpers/size/index.ts +1 -0
  26. package/src/core/helpers/size/object-size.ts +22 -0
  27. package/src/core/selection/select.ts +1 -0
  28. package/src/core/selection/style/api/{get-closest-wrapper.ts → extract.ts} +26 -43
  29. package/src/core/selection/style/api/finite-state-machine.ts +66 -0
  30. package/src/core/selection/style/api/index.ts +12 -5
  31. package/src/core/selection/style/api/{check-special-elements.ts → is-inside-invisible-element.ts} +1 -1
  32. package/src/core/selection/style/api/is-suit-element.ts +12 -1
  33. package/src/core/selection/style/api/toggle/toggle-css.ts +134 -0
  34. package/src/core/selection/style/api/toggle/toggle-ordered-list.ts +49 -0
  35. package/src/core/selection/style/api/toggle-commit-styles.ts +27 -0
  36. package/src/core/selection/style/api/wrap-and-commit-style.ts +68 -0
  37. package/src/core/selection/style/api/wrap-ordered-list.ts +37 -0
  38. package/src/core/selection/style/api/wrap-unwrapped-text.ts +1 -4
  39. package/src/core/selection/style/apply-style.ts +161 -97
  40. package/src/core/selection/style/commit-style.ts +13 -0
  41. package/src/core/storage/engines/local-storage-provider.ts +9 -3
  42. package/src/core/storage/engines/memory-storage-provider.ts +6 -3
  43. package/src/core/storage/storage.ts +7 -4
  44. package/src/core/ui/button/button/button.less +10 -8
  45. package/src/core/ui/button/button/button.ts +9 -9
  46. package/src/core/ui/button/group/group.ts +2 -2
  47. package/src/core/ui/element.ts +4 -3
  48. package/src/core/ui/form/block/block.ts +1 -1
  49. package/src/core/ui/form/form.ts +8 -0
  50. package/src/core/ui/form/inputs/area/area.less +5 -0
  51. package/src/core/ui/form/inputs/area/area.ts +22 -1
  52. package/src/core/ui/form/inputs/checkbox/checkbox.less +50 -0
  53. package/src/core/ui/form/inputs/checkbox/checkbox.ts +48 -4
  54. package/src/core/ui/form/inputs/input/input.less +1 -1
  55. package/src/core/ui/form/inputs/input/input.ts +14 -4
  56. package/src/core/ui/helpers/buttons.ts +14 -6
  57. package/src/core/ui/icon.ts +3 -1
  58. package/src/core/ui/index.ts +1 -3
  59. package/src/core/ui/list/group.less +8 -2
  60. package/src/core/ui/list/group.ts +2 -2
  61. package/src/{modules/file-browser/consts.ts → core/ui/list/index.ts} +4 -4
  62. package/src/core/ui/list/list.less +10 -1
  63. package/src/core/ui/list/list.ts +20 -3
  64. package/src/core/ui/{separator.ts → list/separator.ts} +2 -2
  65. package/src/core/ui/list/spacer.ts +15 -0
  66. package/src/core/ui/popup/popup.less +5 -3
  67. package/src/core/ui/popup/popup.ts +53 -1
  68. package/src/core/view/view-with-toolbar.ts +6 -1
  69. package/src/jodit.ts +17 -14
  70. package/src/modules/dialog/dialog.less +1 -16
  71. package/src/modules/dialog/dialog.ts +10 -3
  72. package/src/modules/file-browser/builders/context-menu.ts +29 -22
  73. package/src/modules/file-browser/config.ts +10 -2
  74. package/src/modules/file-browser/file-browser.ts +50 -29
  75. package/src/modules/file-browser/listeners/native-listeners.ts +37 -19
  76. package/src/modules/file-browser/listeners/state-listeners.ts +48 -22
  77. package/src/modules/file-browser/styles/file-browser.less +4 -291
  78. package/src/modules/file-browser/styles/preview.less +11 -8
  79. package/src/modules/file-browser/ui/files/files.less +174 -0
  80. package/src/modules/file-browser/ui/files/files.ts +14 -0
  81. package/src/modules/file-browser/ui/index.ts +8 -0
  82. package/src/modules/file-browser/ui/tree/tree.less +118 -0
  83. package/src/modules/file-browser/ui/tree/tree.ts +14 -0
  84. package/src/modules/status-bar/status-bar.less +27 -1
  85. package/src/modules/status-bar/status-bar.ts +15 -1
  86. package/src/modules/toolbar/collection/collection.ts +17 -8
  87. package/src/modules/toolbar/collection/editor-collection.ts +27 -2
  88. package/src/modules/widget/file-selector/file-selector.ts +1 -1
  89. package/src/modules/widget/tabs/tabs.less +2 -1
  90. package/src/modules/widget/tabs/tabs.ts +5 -3
  91. package/src/plugins/add-new-line/add-new-line.ts +1 -0
  92. package/src/plugins/bold.ts +2 -2
  93. package/src/plugins/clipboard/drag-and-drop.ts +4 -1
  94. package/src/plugins/clipboard/paste/paste.ts +1 -1
  95. package/src/plugins/font.ts +11 -1
  96. package/src/plugins/image/image-properties/image-properties.ts +7 -0
  97. package/src/plugins/index.ts +1 -0
  98. package/src/plugins/inline-popup/config/config.ts +1 -0
  99. package/src/plugins/inline-popup/config/items/toolbar.ts +33 -0
  100. package/src/plugins/inline-popup/inline-popup.ts +17 -0
  101. package/src/plugins/keyboard/delete.ts +30 -8
  102. package/src/plugins/link/template.ts +2 -2
  103. package/src/plugins/mobile.ts +10 -14
  104. package/src/plugins/ordered-list.ts +40 -1
  105. package/src/plugins/powered-by-jodit.ts +39 -0
  106. package/src/plugins/print/preview.ts +103 -48
  107. package/src/plugins/resizer/resizer.less +10 -7
  108. package/src/plugins/resizer/resizer.ts +12 -14
  109. package/src/plugins/size/resize-handler.ts +4 -1
  110. package/src/plugins/size/size.less +2 -19
  111. package/src/plugins/size/size.ts +6 -1
  112. package/src/plugins/source/const.ts +7 -0
  113. package/src/plugins/source/editor/engines/ace.ts +5 -0
  114. package/src/plugins/source/source.ts +33 -7
  115. package/src/plugins/sticky/sticky.ts +2 -0
  116. package/src/styles/icons/index.ts +2 -0
  117. package/src/styles/icons/resize-handler.svg +4 -0
  118. package/src/styles/jodit.less +6 -0
  119. package/src/styles/mixins.less +20 -0
  120. package/src/styles/themes/dark.less +11 -1
  121. package/src/types/ajax.d.ts +0 -1
  122. package/src/types/file-browser.d.ts +13 -1
  123. package/src/types/jodit.d.ts +4 -1
  124. package/src/types/popup.d.ts +1 -0
  125. package/src/types/select.d.ts +2 -0
  126. package/src/types/storage.ts +3 -3
  127. package/src/types/style.d.ts +8 -0
  128. package/src/types/toolbar.d.ts +9 -2
  129. package/src/types/types.d.ts +1 -1
  130. package/src/types/ui.d.ts +23 -4
  131. package/src/types/view.d.ts +1 -0
  132. package/types/core/component/component.d.ts +10 -5
  133. package/types/core/component/statuses.d.ts +6 -6
  134. package/types/core/dom.d.ts +3 -2
  135. package/types/core/helpers/append-script.d.ts +1 -0
  136. package/types/core/helpers/selector.d.ts +2 -3
  137. package/types/core/helpers/size/index.d.ts +1 -0
  138. package/types/core/helpers/size/object-size.d.ts +7 -0
  139. package/types/core/selection/style/api/{get-closest-wrapper.d.ts → extract.d.ts} +6 -5
  140. package/types/core/selection/style/api/finite-state-machine.d.ts +21 -0
  141. package/types/core/selection/style/api/index.d.ts +12 -5
  142. package/types/core/selection/style/api/{check-special-elements.d.ts → is-inside-invisible-element.d.ts} +1 -1
  143. package/types/core/selection/style/api/is-suit-element.d.ts +9 -0
  144. package/types/core/selection/style/api/toggle/toggle-css.d.ts +11 -0
  145. package/types/core/selection/style/api/toggle/toggle-ordered-list.d.ts +11 -0
  146. package/types/core/selection/style/api/{toggle-styles.d.ts → toggle-commit-styles.d.ts} +1 -3
  147. package/types/core/selection/style/api/{post-process-list-element.d.ts → wrap-and-commit-style.d.ts} +3 -3
  148. package/types/core/selection/style/api/wrap-ordered-list.d.ts +12 -0
  149. package/types/core/selection/style/apply-style.d.ts +1 -4
  150. package/types/core/selection/style/commit-style.d.ts +7 -0
  151. package/types/core/storage/engines/local-storage-provider.d.ts +3 -3
  152. package/types/core/storage/engines/memory-storage-provider.d.ts +3 -3
  153. package/types/core/storage/storage.d.ts +3 -3
  154. package/types/core/ui/button/button/button.d.ts +3 -3
  155. package/types/core/ui/form/form.d.ts +1 -0
  156. package/types/core/ui/form/inputs/area/area.d.ts +7 -1
  157. package/types/core/ui/form/inputs/checkbox/checkbox.d.ts +10 -3
  158. package/types/core/ui/helpers/buttons.d.ts +2 -2
  159. package/types/core/ui/icon.d.ts +1 -1
  160. package/types/core/ui/index.d.ts +1 -3
  161. package/types/core/ui/list/group.d.ts +2 -1
  162. package/types/core/ui/list/index.d.ts +9 -0
  163. package/types/core/ui/{separator.d.ts → list/separator.d.ts} +1 -1
  164. package/types/core/ui/list/spacer.d.ts +9 -0
  165. package/types/core/ui/popup/popup.d.ts +2 -1
  166. package/types/core/view/view-with-toolbar.d.ts +4 -2
  167. package/types/jodit.d.ts +6 -6
  168. package/types/modules/file-browser/file-browser.d.ts +3 -2
  169. package/types/modules/file-browser/listeners/native-listeners.d.ts +5 -1
  170. package/types/modules/file-browser/ui/files/files.d.ts +10 -0
  171. package/types/modules/file-browser/ui/index.d.ts +7 -0
  172. package/types/modules/file-browser/ui/tree/tree.d.ts +10 -0
  173. package/types/modules/status-bar/status-bar.d.ts +6 -1
  174. package/types/modules/toolbar/button/button.d.ts +1 -1
  175. package/types/modules/toolbar/collection/collection.d.ts +5 -2
  176. package/types/modules/toolbar/collection/editor-collection.d.ts +9 -1
  177. package/types/modules/widget/tabs/tabs.d.ts +2 -1
  178. package/types/plugins/index.d.ts +1 -0
  179. package/types/plugins/inline-popup/inline-popup.d.ts +4 -0
  180. package/types/plugins/keyboard/delete.d.ts +2 -0
  181. package/types/plugins/ordered-list.d.ts +8 -1
  182. package/types/plugins/powered-by-jodit.d.ts +12 -0
  183. package/types/plugins/source/const.d.ts +6 -0
  184. package/types/plugins/source/editor/engines/ace.d.ts +1 -0
  185. package/types/plugins/source/source.d.ts +1 -0
  186. package/types/styles/icons/index.d.ts +2 -1
  187. package/types/types/storage.d.ts +3 -3
  188. package/types/types/{ajax.d.ts → types/ajax.d.ts} +0 -1
  189. package/types/types/{async.d.ts → types/async.d.ts} +0 -0
  190. package/types/types/{context.d.ts → types/context.d.ts} +0 -0
  191. package/types/types/{core.ts → types/core.ts} +0 -0
  192. package/types/types/{create.d.ts → types/create.d.ts} +0 -0
  193. package/types/types/{dialog.d.ts → types/dialog.d.ts} +0 -0
  194. package/types/types/{events.d.ts → types/events.d.ts} +0 -0
  195. package/types/types/{file-browser.d.ts → types/file-browser.d.ts} +13 -1
  196. package/types/types/{form.d.ts → types/form.d.ts} +0 -0
  197. package/types/types/{index.d.ts → types/index.d.ts} +0 -0
  198. package/types/types/{jodit.d.ts → types/jodit.d.ts} +4 -1
  199. package/types/types/{observe.d.ts → types/observe.d.ts} +0 -0
  200. package/types/types/{plugin.d.ts → types/plugin.d.ts} +0 -0
  201. package/types/types/{popup.d.ts → types/popup.d.ts} +1 -0
  202. package/types/types/{select.d.ts → types/select.d.ts} +2 -0
  203. package/types/types/{source.d.ts → types/source.d.ts} +0 -0
  204. package/types/types/{storage.ts → types/storage.ts} +3 -3
  205. package/types/types/{style.d.ts → types/style.d.ts} +8 -0
  206. package/types/types/{toolbar.d.ts → types/toolbar.d.ts} +9 -2
  207. package/types/types/{traits.d.ts → types/traits.d.ts} +0 -0
  208. package/types/types/{types.d.ts → types/types.d.ts} +1 -1
  209. package/types/types/{ui.d.ts → types/ui.d.ts} +23 -4
  210. package/types/types/{uploader.d.ts → types/uploader.d.ts} +0 -0
  211. package/types/types/{view.d.ts → types/view.d.ts} +1 -0
  212. package/src/core/selection/style/api/post-process-list-element.ts +0 -33
  213. package/src/core/selection/style/api/toggle-styles.ts +0 -74
  214. package/types/modules/file-browser/consts.d.ts +0 -8
package/index.d.ts CHANGED
@@ -24,6 +24,16 @@ declare global {
24
24
  offset: number;
25
25
  }
26
26
 
27
+ interface IdleDeadline {
28
+ readonly didTimeout: boolean;
29
+ timeRemaining(): DOMHighResTimeStamp;
30
+ }
31
+
32
+ // https://github.com/xdan/jodit/issues/743
33
+ interface IdleRequestCallback {
34
+ (deadline: IdleDeadline): void;
35
+ }
36
+
27
37
  interface Document {
28
38
  caretPositionFromPoint?(x: number, y: number): CaretPosition;
29
39
  caretRangeFromPoint(x: number, y: number): Range;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "3.9.3",
3
+ "version": "3.10.2",
4
4
  "description": "Jodit is awesome and usefully wysiwyg editor with filebrowser",
5
5
  "main": "build/jodit.min.js",
6
6
  "types": "./types/index.d.ts",
@@ -11,18 +11,18 @@
11
11
  "start": "node server.js --port=2000",
12
12
  "clean": "rm -rf build/*",
13
13
  "build": "npm run clean && npm run types && npm run build-es5 && npm run build-es2018 && npm run build-es2018-en && npm run build-no-uglify-es5 && npm run build-no-uglify-es2018 && npm run build-no-uglify-es2018-en",
14
- "build-es5": "node ./build-system/build.js --progress --mode production --es es5 --uglify true",
15
- "build-es2018": "node ./build-system/build.js --progress --mode production --es es2018 --uglify true",
16
- "build-es2018-en": "node ./build-system/build.js --progress --mode production --es es2018 --excludeLangs true --uglify true",
17
- "build-no-uglify-es5": "node ./build-system/build.js --progress --mode production --es es5 --uglify false",
18
- "build-no-uglify-es2018": "node ./build-system/build.js --progress --mode production --es es2018 --uglify false",
19
- "build-no-uglify-es2018-en": "node ./build-system/build.js --progress --mode production --es es2018 --excludeLangs true --uglify false",
20
- "test": "npm run clean && node ./build-system/build.js --progress --mode production --es es2018 --uglify false --isTest true && npm run test-only-run",
14
+ "build-es5": "webpack --progress --mode production --env es=es5 --env uglify=true",
15
+ "build-es2018": "webpack --progress --mode production --env es=es2018 --env uglify=true",
16
+ "build-es2018-en": "webpack --progress --mode production --env es=es2018 --env excludeLangs=true --env uglify=true",
17
+ "build-no-uglify-es5": "webpack --progress --mode production --env es=es5 --env uglify=false",
18
+ "build-no-uglify-es2018": "webpack --progress --mode production --env es=es2018 --env uglify=false",
19
+ "build-no-uglify-es2018-en": "webpack --progress --mode production --env es=es2018 --env excludeLangs=true --env uglify=false",
20
+ "test": "npm run clean && webpack --progress --mode production --env es=es2018 --env uglify=false --env isTest=true && npm run test-only-run",
21
21
  "test-debug": "karma start --browsers Chrome karma.conf.js --single-run false",
22
22
  "test-chrome": "karma start --browsers Chrome karma.conf.js",
23
23
  "test-only-run": "karma start --browsers FirefoxHeadless karma.conf.js",
24
24
  "jodit": "cd ../jodit-react/ && npm update && npm run newversion && cd ../jodit-pro && npm run newversion && cd ../jodit-joomla && npm run newversion && cd ../jodit-master && npm run newversion",
25
- "types": "rm -rf types/* && cp -r ./src/types ./types/types && tsc --project . --declaration --declarationDir types --outDir types --emitDeclarationOnly --removeComments false",
25
+ "types": "rm -rf types/* && mkdir -p ./types/types && cp -r ./src/types ./types/types && tsc --project . --declaration --declarationDir types --outDir types --emitDeclarationOnly --removeComments false",
26
26
  "pretty": "npx prettier --write ./src/*.{ts,less} ./src/**/*.{ts,less} ./src/**/**/*.{ts,less} ./src/**/**/**/*.{ts,less} ./src/**/**/**/**/*.{ts,less}",
27
27
  "fix": "npx eslint ./src/ ./test/ --fix && npm run pretty",
28
28
  "lint": "npx eslint ./src/ ./test/ && stylelint ./src/**/**.less"
@@ -98,7 +98,7 @@
98
98
  "ts-loader": "^9.2.6",
99
99
  "ts-private-uglifier": "^1.0.2",
100
100
  "tslib": "^2.3.1",
101
- "typescript": "^4.4.4",
101
+ "typescript": "^4.5.2",
102
102
  "url-loader": "^4.1.1",
103
103
  "webpack": "^5.59.1",
104
104
  "webpack-cli": "^4.9.1",
package/src/config.ts CHANGED
@@ -627,13 +627,9 @@ export class Config implements IViewOptions {
627
627
  group: 'font-style',
628
628
  buttons: []
629
629
  },
630
- {
631
- group: 'script',
632
- buttons: []
633
- },
634
630
  {
635
631
  group: 'list',
636
- buttons: ['ul', 'ol']
632
+ buttons: []
637
633
  },
638
634
  {
639
635
  group: 'indent',
@@ -647,6 +643,11 @@ export class Config implements IViewOptions {
647
643
  group: 'color',
648
644
  buttons: []
649
645
  },
646
+ '---',
647
+ {
648
+ group: 'script',
649
+ buttons: []
650
+ },
650
651
  {
651
652
  group: 'media',
652
653
  buttons: []
@@ -668,6 +669,7 @@ export class Config implements IViewOptions {
668
669
  group: 'form',
669
670
  buttons: []
670
671
  },
672
+ '---',
671
673
  {
672
674
  group: 'history',
673
675
  buttons: []
@@ -694,8 +696,6 @@ export class Config implements IViewOptions {
694
696
  * The list of buttons that appear in the editor's toolbar on medium places (≥ options.sizeMD).
695
697
  */
696
698
  buttonsMD: ButtonsOption = [
697
- 'source',
698
- '|',
699
699
  'bold',
700
700
  'italic',
701
701
  '|',
@@ -707,19 +707,20 @@ export class Config implements IViewOptions {
707
707
  'fontsize',
708
708
  'brush',
709
709
  'paragraph',
710
- '|',
710
+ 'align',
711
+ '---',
711
712
  'image',
712
713
  'table',
713
- 'link',
714
714
  '|',
715
- 'align',
715
+ 'link',
716
716
  '\n',
717
- 'undo',
718
- 'redo',
719
- '|',
720
717
  'hr',
721
718
  'copyformat',
722
719
  'fullsize',
720
+ '---',
721
+ 'undo',
722
+ 'redo',
723
+ '|',
723
724
  'dots'
724
725
  ];
725
726
 
@@ -727,8 +728,6 @@ export class Config implements IViewOptions {
727
728
  * The list of buttons that appear in the editor's toolbar on small places (≥ options.sizeSM).
728
729
  */
729
730
  buttonsSM: ButtonsOption = [
730
- 'source',
731
- '|',
732
731
  'bold',
733
732
  'italic',
734
733
  '|',
@@ -739,7 +738,7 @@ export class Config implements IViewOptions {
739
738
  'fontsize',
740
739
  'brush',
741
740
  'paragraph',
742
- '|',
741
+ '---',
743
742
  'image',
744
743
  'table',
745
744
  '\n',
@@ -752,6 +751,7 @@ export class Config implements IViewOptions {
752
751
  '|',
753
752
  'copyformat',
754
753
  'fullsize',
754
+ '---',
755
755
  'dots'
756
756
  ];
757
757
 
@@ -760,17 +760,16 @@ export class Config implements IViewOptions {
760
760
  */
761
761
  buttonsXS: ButtonsOption = [
762
762
  'bold',
763
- 'image',
764
- '|',
765
763
  'brush',
766
764
  'paragraph',
767
765
  'eraser',
766
+ '---',
767
+ 'image',
768
768
  '\n',
769
769
  'align',
770
- '|',
771
770
  'undo',
772
771
  'redo',
773
- '|',
772
+ '---',
774
773
  'dots'
775
774
  ];
776
775
 
@@ -8,7 +8,6 @@ import type {
8
8
  ComponentStatus,
9
9
  IComponent,
10
10
  IDictionary,
11
- IViewBased,
12
11
  Nullable
13
12
  } from '../../types';
14
13
 
@@ -27,7 +26,17 @@ const StatusListHandlers: Map<
27
26
  export abstract class Component implements IComponent {
28
27
  static STATUSES = STATUSES;
29
28
 
30
- readonly componentName: string;
29
+ private __componentName!: string;
30
+
31
+ get componentName(): string {
32
+ if (!this.__componentName) {
33
+ this.__componentName =
34
+ 'jodit-' + kebabCase(this.className() || getClassName(this));
35
+ }
36
+
37
+ return this.__componentName;
38
+ }
39
+
31
40
  readonly uid: string;
32
41
 
33
42
  /**
@@ -139,16 +148,11 @@ export abstract class Component implements IComponent {
139
148
  /**
140
149
  * Bind destructor to come View
141
150
  */
142
- bindDestruct(jodit: IViewBased): this {
143
- const destructMe = () => {
144
- !this.isInDestruct && this.destruct();
145
- };
146
-
147
- jodit.e && jodit.e.on(STATUSES.beforeDestruct, destructMe);
148
-
149
- this.hookStatus(STATUSES.beforeDestruct, () => {
150
- jodit.e && jodit.e.off(STATUSES.beforeDestruct, destructMe);
151
- });
151
+ bindDestruct(component: IComponent): this {
152
+ component.hookStatus(
153
+ STATUSES.beforeDestruct,
154
+ () => !this.isInDestruct && this.destruct()
155
+ );
152
156
 
153
157
  return this;
154
158
  }
@@ -156,9 +160,6 @@ export abstract class Component implements IComponent {
156
160
  abstract className(): string;
157
161
 
158
162
  protected constructor() {
159
- this.componentName =
160
- 'jodit-' + kebabCase(this.className() || getClassName(this));
161
-
162
163
  this.uid = 'jodit-uid-' + uniqueUid();
163
164
  }
164
165
 
@@ -4,9 +4,9 @@
4
4
  * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
- export enum STATUSES {
8
- beforeInit = 'beforeInit',
9
- ready = 'ready',
10
- beforeDestruct = 'beforeDestruct',
11
- destructed = 'destructed'
12
- }
7
+ export const STATUSES = {
8
+ beforeInit: 'beforeInit',
9
+ ready: 'ready',
10
+ beforeDestruct: 'beforeDestruct',
11
+ destructed: 'destructed'
12
+ } as const;
package/src/core/dom.ts CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  get,
25
25
  isArray,
26
26
  isFunction,
27
+ isHTML,
27
28
  isString,
28
29
  isVoid,
29
30
  toArray,
@@ -191,11 +192,15 @@ export class Dom {
191
192
  */
192
193
  static replace(
193
194
  elm: HTMLElement,
194
- newTagName: HTMLTagNames | HTMLElement,
195
+ newTagName: HTMLTagNames | HTMLElement | string,
195
196
  create: ICreate,
196
197
  withAttributes = false,
197
198
  notMoveContent = false
198
199
  ): HTMLElement {
200
+ if (isHTML(newTagName)) {
201
+ newTagName = create.fromHTML(newTagName);
202
+ }
203
+
199
204
  const tag = isString(newTagName)
200
205
  ? create.element(newTagName)
201
206
  : newTagName;
@@ -225,12 +230,19 @@ export class Dom {
225
230
  *
226
231
  * @param node - The element of wood to be checked
227
232
  */
228
- static isEmptyTextNode(node: Node): boolean {
233
+ static isEmptyTextNode(node: Nullable<Node>): boolean {
229
234
  return (
230
235
  Dom.isText(node) &&
231
236
  (!node.nodeValue ||
232
- node.nodeValue.replace(consts.INVISIBLE_SPACE_REG_EXP(), '')
233
- .length === 0)
237
+ node.nodeValue
238
+ .replace(consts.INVISIBLE_SPACE_REG_EXP(), '')
239
+ .trim().length === 0)
240
+ );
241
+ }
242
+
243
+ static isEmptyContent(node: Node): boolean {
244
+ return Dom.each(node as HTMLElement, (elm: Node | null): boolean =>
245
+ Dom.isEmptyTextNode(elm)
234
246
  );
235
247
  }
236
248
 
@@ -264,7 +264,9 @@ export class EventEmitter implements IEventEmitter {
264
264
  return this;
265
265
  }
266
266
 
267
- const isDOMElement = isFunction((subject as any).addEventListener),
267
+ const isDOMElement = isFunction(
268
+ (subject as HTMLElement).addEventListener
269
+ ),
268
270
  self: EventEmitter = this;
269
271
 
270
272
  let syntheticCallback: CallbackFunction = function (
@@ -360,7 +362,7 @@ export class EventEmitter implements IEventEmitter {
360
362
 
361
363
  const newCallback = (...args: any) => {
362
364
  this.off(subject, events, newCallback);
363
- callback(...args);
365
+ return callback(...args);
364
366
  };
365
367
 
366
368
  this.on(subject, events, newCallback, onTop);
@@ -30,12 +30,23 @@ export const instances: IDictionary<IJodit> = {};
30
30
 
31
31
  let counter = 1;
32
32
 
33
+ const uuids = new Set();
33
34
  /**
34
35
  * Generate global unique uid
35
36
  */
36
37
  export function uniqueUid(): string {
37
- counter += 10 * (Math.random() + 1);
38
- return Math.round(counter).toString(16);
38
+ function gen(): string {
39
+ counter += 10 * (Math.random() + 1);
40
+ return Math.round(counter).toString(16);
41
+ }
42
+
43
+ let uid = gen();
44
+ while (uuids.has(uid)) {
45
+ uid = gen();
46
+ }
47
+ uuids.add(uid);
48
+
49
+ return uid;
39
50
  }
40
51
 
41
52
  export const pluginSystem = new PluginSystem();
@@ -113,3 +113,17 @@ export const loadNext = (
113
113
  loadNext(jodit, urls, i + 1)
114
114
  );
115
115
  };
116
+
117
+ export const loadNextStyle = (
118
+ jodit: IViewBased,
119
+ urls: string[],
120
+ i: number = 0
121
+ ): Promise<void> => {
122
+ if (!isString(urls[i])) {
123
+ return Promise.resolve();
124
+ }
125
+
126
+ return appendStyleAsync(jodit, urls[i]).then(() =>
127
+ loadNextStyle(jodit, urls, i + 1)
128
+ );
129
+ };
@@ -4,7 +4,12 @@
4
4
  * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
- import type { HTMLTagNames, IDictionary, Nullable } from '../../types/';
7
+ import type {
8
+ HTMLTagNames,
9
+ IDictionary,
10
+ IUIElement,
11
+ Nullable
12
+ } from '../../types/';
8
13
  import { IS_IE } from '../constants';
9
14
  import { isString } from './checker';
10
15
  import { attr } from './utils';
@@ -116,13 +121,13 @@ export const getXPathByElement = (
116
121
  * Find all `ref` or `data-ref` elements inside HTMLElement
117
122
  */
118
123
  export const refs = <T extends HTMLElement>(
119
- root: HTMLElement | UIElement
124
+ root: HTMLElement | IUIElement
120
125
  ): IDictionary<T> => {
121
126
  if (root instanceof UIElement) {
122
127
  root = root.container;
123
128
  }
124
129
 
125
- return $$('[ref],[data-ref]', root).reduce((def, child) => {
130
+ return $$('[ref],[data-ref]', <HTMLElement>root).reduce((def, child) => {
126
131
  const key = attr(child, '-ref');
127
132
 
128
133
  if (key && isString(key)) {
@@ -9,3 +9,4 @@ export * from './get-scroll-parent';
9
9
  export * from './inner-width';
10
10
  export * from './offset';
11
11
  export * from './position';
12
+ export * from './object-size';
@@ -0,0 +1,22 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * Released under MIT see LICENSE.txt in the project root for license information.
4
+ * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+
7
+ import { isArray, isPlainObject, isString } from '../checker';
8
+ import type { CanUndef } from '../../../types';
9
+
10
+ export function size(
11
+ subject: CanUndef<object | string | Array<unknown>>
12
+ ): number {
13
+ if (isString(subject) || isArray(subject)) {
14
+ return subject.length;
15
+ }
16
+
17
+ if (isPlainObject(subject)) {
18
+ return Object.keys(subject).length;
19
+ }
20
+
21
+ return 0;
22
+ }
@@ -110,6 +110,7 @@ export class Select implements ISelect {
110
110
  * Return current selection object
111
111
  * @param select - Immediately add in selection
112
112
  */
113
+ @autobind
113
114
  createRange(select: boolean = false): Range {
114
115
  const range = this.doc.createRange();
115
116
 
@@ -4,69 +4,52 @@
4
4
  * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
- import type { CommitStyle } from '../commit-style';
8
- import { Dom } from '../../../dom';
9
- import { isSuitElement } from './is-suit-element';
10
- import { call, trim } from '../../../helpers';
11
- import type { Nullable } from '../../../../types';
7
+ import type { IJodit } from '../../../../types';
12
8
  import { Select } from '../../select';
9
+ import { call, trim } from '../../../helpers';
10
+ import { Dom } from '../../../dom';
13
11
 
14
12
  /**
15
13
  * If the selection area is inside an element that matches the commit (suitable relative),
16
14
  * but does not completely fill it.
17
15
  * Then the method cuts the parent and leaves itself in a copy of the parent (suitable relative) in the middle.
18
- * And returns it copy.
19
16
  *
20
17
  * @example
18
+ * Apply strong to
21
19
  * ```html
22
20
  * <strong><span>some<font>SELECTED</font>text</span></strong>
23
- * to
21
+ * ```
22
+ * Should extract selection from parent `strong`
23
+ * ```html
24
24
  * `<strong><span>some</span></strong><strong><span><font>SELECTED</font></span></strong><strong><span>test</span></strong>
25
25
  * ```
26
26
  */
27
- export function getClosestWrapper(
28
- style: CommitStyle,
27
+ export function extractSelectedPart(
28
+ wrapper: HTMLElement,
29
29
  font: HTMLElement,
30
- root: HTMLElement,
31
- getRange: () => Range
32
- ): Nullable<HTMLElement> {
33
- const wrapper = Dom.closest(
34
- font,
35
- node => isSuitElement(style, node, true),
36
- root
37
- );
38
-
39
- if (wrapper) {
40
- if (style.elementIsBlock) {
41
- return wrapper;
42
- }
43
-
44
- const range = getRange();
45
-
46
- // Left part
47
- const leftEdge = Select.isMarker(font.previousSibling)
48
- ? font.previousSibling
49
- : font;
50
-
51
- range.setStartBefore(wrapper);
52
- range.setEndBefore(leftEdge);
30
+ jodit: IJodit
31
+ ): void {
32
+ const range = jodit.s.createRange();
53
33
 
54
- extractAndMove(wrapper, range, true);
34
+ // Left part
35
+ const leftEdge = Select.isMarker(font.previousSibling)
36
+ ? font.previousSibling
37
+ : font;
55
38
 
56
- // Right part
57
- const rightEdge = Select.isMarker(font.nextSibling)
58
- ? font.nextSibling
59
- : font;
39
+ range.setStartBefore(wrapper);
40
+ range.setEndBefore(leftEdge);
60
41
 
61
- range.setStartAfter(rightEdge);
62
- range.setEndAfter(wrapper);
42
+ extractAndMove(wrapper, range, true);
63
43
 
64
- extractAndMove(wrapper, range, false);
44
+ // Right part
45
+ const rightEdge = Select.isMarker(font.nextSibling)
46
+ ? font.nextSibling
47
+ : font;
65
48
 
66
- return wrapper;
67
- }
49
+ range.setStartAfter(rightEdge);
50
+ range.setEndAfter(wrapper);
68
51
 
69
- return null;
52
+ extractAndMove(wrapper, range, false);
70
53
  }
71
54
 
72
55
  /**
@@ -0,0 +1,66 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * Released under MIT see LICENSE.txt in the project root for license information.
4
+ * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+
7
+ import type { CanUndef, IDictionary } from '../../../../types';
8
+
9
+ /**
10
+ * A state machine implementation for applying styles.
11
+ */
12
+ export class FiniteStateMachine {
13
+ setState(state: string, subState?: string): void {
14
+ this.state = state;
15
+
16
+ if (subState != null) {
17
+ this.subState = subState;
18
+ }
19
+ }
20
+
21
+ private subState: string = '';
22
+
23
+ getState(): string {
24
+ return this.state;
25
+ }
26
+
27
+ getSubState(): string {
28
+ return this.subState;
29
+ }
30
+
31
+ private silent: boolean = true;
32
+ disableSilent(): void {
33
+ this.silent = false;
34
+ }
35
+
36
+ constructor(
37
+ private state: string,
38
+ private readonly transitions: IDictionary<
39
+ IDictionary<(this: FiniteStateMachine, ...attrs: any[]) => any>
40
+ >
41
+ ) {}
42
+
43
+ dispatch<T>(actionName: string, ...attrs: any[]): CanUndef<T> {
44
+ const action = this.transitions[this.state][actionName];
45
+
46
+ if (action) {
47
+ if (!this.silent) {
48
+ console.log('State: ' + this.state, 'Action: ' + actionName);
49
+ }
50
+
51
+ const res = action.call(this, ...attrs);
52
+
53
+ if (!this.silent) {
54
+ console.log('State: ' + this.state);
55
+ }
56
+
57
+ return <T>res;
58
+ }
59
+
60
+ if (!this.silent) {
61
+ throw new Error('invalid action: ' + this.state + '.' + actionName);
62
+ }
63
+
64
+ return;
65
+ }
66
+ }
@@ -4,11 +4,18 @@
4
4
  * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
- export * from './get-suit-parent';
7
+ export * from './toggle/toggle-css';
8
+ export * from './toggle/toggle-ordered-list';
9
+ export * from './element-has-same-style';
10
+ export * from './extract';
11
+ export * from './finite-state-machine';
8
12
  export * from './get-suit-child';
9
- export * from './check-special-elements';
10
- export * from './get-closest-wrapper';
13
+ export * from './get-suit-parent';
14
+ export * from './is-inside-invisible-element';
15
+ export * from './is-normal-node';
16
+ export * from './is-suit-element';
17
+ export * from './toggle-commit-styles';
11
18
  export * from './unwrap-children';
19
+ export * from './wrap-and-commit-style';
20
+ export * from './wrap-ordered-list';
12
21
  export * from './wrap-unwrapped-text';
13
- export * from './post-process-list-element';
14
- export * from './toggle-styles';
@@ -9,7 +9,7 @@ import { Dom } from '../../../dom';
9
9
  /**
10
10
  * Check if FONT inside STYLE or SCRIPT element
11
11
  */
12
- export function checkSpecialElements(
12
+ export function isInsideInvisibleElement(
13
13
  font: HTMLElement,
14
14
  root: HTMLElement
15
15
  ): boolean {
@@ -36,7 +36,9 @@ export function isSuitElement(
36
36
  options.style && elementHasSameStyle(elm, options.style)
37
37
  );
38
38
 
39
- const elmIsSame = elm.nodeName.toLowerCase() === element;
39
+ const elmIsSame =
40
+ elm.nodeName.toLowerCase() === element ||
41
+ (Dom.isTag(elm, ['ul', 'ol']) && commitStyle.elementIsList);
40
42
 
41
43
  if (
42
44
  ((!elementIsDefault || !strict) && elmIsSame) ||
@@ -50,6 +52,15 @@ export function isSuitElement(
50
52
  );
51
53
  }
52
54
 
55
+ /**
56
+ * Внутри родительского элемента есть блок с теми же стилями
57
+ * @example
58
+ * For selection:
59
+ * ```html
60
+ * <p>|test<strong>test</strong>|</p>
61
+ * ```
62
+ * Apply `{element:'strong'}`
63
+ */
53
64
  export function isSameStyleChild(
54
65
  commitStyle: CommitStyle,
55
66
  elm: Nullable<Node>