jodit 3.8.7 → 3.9.4

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 (180) hide show
  1. package/.github/workflows/tests.yml +23 -0
  2. package/.idea/dictionaries/v_chupurnov.xml +1 -0
  3. package/.idea/workspace.xml +340 -298
  4. package/CHANGELOG.MD +132 -24
  5. package/README.md +3 -4
  6. package/build/jodit.css +92 -34
  7. package/build/jodit.es2018.css +65 -30
  8. package/build/jodit.es2018.en.css +65 -30
  9. package/build/jodit.es2018.en.js +1214 -693
  10. package/build/jodit.es2018.en.min.css +1 -1
  11. package/build/jodit.es2018.en.min.js +1 -1
  12. package/build/jodit.es2018.js +1214 -693
  13. package/build/jodit.es2018.min.css +1 -1
  14. package/build/jodit.es2018.min.js +1 -1
  15. package/build/jodit.js +2271 -1628
  16. package/build/jodit.min.css +2 -2
  17. package/build/jodit.min.js +1 -1
  18. package/index.d.ts +10 -0
  19. package/package.json +14 -13
  20. package/src/config.ts +1 -1
  21. package/src/core/async.ts +7 -5
  22. package/src/core/constants.ts +2 -0
  23. package/src/core/dom.ts +123 -102
  24. package/src/core/events/{events-native.ts → event-emitter.ts} +14 -9
  25. package/src/core/events/index.ts +1 -1
  26. package/src/core/global.ts +2 -2
  27. package/src/core/helpers/array/to-array.ts +1 -0
  28. package/src/core/helpers/data-bind.ts +2 -2
  29. package/src/core/helpers/size/index.ts +1 -0
  30. package/src/core/helpers/size/object-size.ts +22 -0
  31. package/src/core/helpers/utils/utils.ts +20 -4
  32. package/src/core/request/ajax.ts +212 -0
  33. package/src/core/request/config.ts +37 -0
  34. package/{build-system/minimizer/index.js → src/core/request/index.ts} +2 -1
  35. package/src/core/request/response.ts +39 -0
  36. package/src/core/selection/select.ts +60 -27
  37. package/src/core/selection/style/api/element-has-same-style.ts +13 -0
  38. package/src/core/selection/style/api/{get-closest-wrapper.ts → extract.ts} +26 -43
  39. package/src/core/selection/style/api/finite-state-machine.ts +66 -0
  40. package/src/core/selection/style/api/get-suit-parent.ts +1 -1
  41. package/src/core/selection/style/api/index.ts +12 -5
  42. package/src/core/selection/style/api/{check-special-elements.ts → is-inside-invisible-element.ts} +1 -1
  43. package/src/core/selection/style/api/is-suit-element.ts +36 -5
  44. package/src/core/selection/style/api/toggle/toggle-css.ts +134 -0
  45. package/src/core/selection/style/api/toggle/toggle-ordered-list.ts +49 -0
  46. package/src/core/selection/style/api/toggle-commit-styles.ts +27 -0
  47. package/src/core/selection/style/api/unwrap-children.ts +45 -16
  48. package/src/core/selection/style/api/wrap-and-commit-style.ts +68 -0
  49. package/src/core/selection/style/api/wrap-ordered-list.ts +37 -0
  50. package/src/core/selection/style/api/wrap-unwrapped-text.ts +29 -27
  51. package/src/core/selection/style/apply-style.ts +161 -91
  52. package/src/core/selection/style/commit-style.ts +13 -0
  53. package/src/core/traits/elms.ts +1 -0
  54. package/src/core/ui/button/button/button.less +2 -0
  55. package/src/core/ui/helpers/buttons.ts +14 -6
  56. package/src/core/ui/helpers/get-control-type.ts +3 -1
  57. package/src/core/ui/list/list.less +1 -0
  58. package/src/core/ui/popup/popup.less +5 -3
  59. package/src/core/view/view-with-toolbar.ts +4 -0
  60. package/src/core/view/view.ts +3 -3
  61. package/src/modules/context-menu/context-menu.ts +1 -1
  62. package/src/modules/file-browser/README.MD +1 -1
  63. package/src/modules/file-browser/data-provider.ts +22 -42
  64. package/src/modules/file-browser/file-browser.ts +3 -0
  65. package/src/modules/index.ts +1 -1
  66. package/src/modules/status-bar/status-bar.less +27 -1
  67. package/src/modules/status-bar/status-bar.ts +15 -1
  68. package/src/modules/table.ts +197 -168
  69. package/src/modules/uploader/uploader.ts +4 -3
  70. package/src/modules/widget/tabs/tabs.less +1 -0
  71. package/src/plugins/bold.ts +2 -2
  72. package/src/plugins/fix/clean-html.ts +37 -16
  73. package/src/plugins/font.ts +11 -1
  74. package/src/plugins/indent.ts +25 -18
  75. package/src/plugins/index.ts +1 -0
  76. package/src/plugins/mobile.ts +10 -14
  77. package/src/plugins/ordered-list.ts +40 -1
  78. package/src/plugins/powered-by-jodit.ts +39 -0
  79. package/src/plugins/print/preview.ts +9 -2
  80. package/src/plugins/resizer/resizer.less +10 -7
  81. package/src/plugins/resizer/resizer.ts +12 -14
  82. package/src/plugins/size/assests/resize-handler.svg +4 -0
  83. package/src/plugins/size/resize-handler.ts +5 -5
  84. package/src/plugins/size/size.less +6 -8
  85. package/src/plugins/size/size.ts +1 -3
  86. package/src/plugins/source/source.ts +16 -2
  87. package/src/plugins/table/config.ts +3 -1
  88. package/src/plugins/table/select-cells.ts +23 -5
  89. package/src/plugins/table/table.less +0 -1
  90. package/src/styles/themes/dark.less +11 -1
  91. package/src/types/ajax.d.ts +15 -6
  92. package/src/types/async.d.ts +5 -4
  93. package/src/types/events.d.ts +12 -12
  94. package/src/types/style.d.ts +2 -0
  95. package/src/types/toolbar.d.ts +2 -1
  96. package/src/types/view.d.ts +3 -2
  97. package/types/core/async.d.ts +3 -3
  98. package/types/core/constants.d.ts +1 -0
  99. package/types/core/dom.d.ts +27 -20
  100. package/types/core/events/{events-native.d.ts → event-emitter.d.ts} +8 -3
  101. package/types/core/events/index.d.ts +1 -1
  102. package/types/core/global.d.ts +2 -2
  103. package/types/core/helpers/size/index.d.ts +1 -0
  104. package/{src/types/core.js → types/core/helpers/size/object-size.d.ts} +2 -3
  105. package/types/core/helpers/utils/utils.d.ts +12 -4
  106. package/types/core/{ajax.d.ts → request/ajax.d.ts} +5 -15
  107. package/types/core/request/config.d.ts +14 -0
  108. package/{build-system/rules/css.js → types/core/request/index.d.ts} +2 -7
  109. package/types/core/request/response.d.ts +16 -0
  110. package/types/core/selection/style/api/element-has-same-style.d.ts +4 -0
  111. package/types/core/selection/style/api/{get-closest-wrapper.d.ts → extract.d.ts} +6 -5
  112. package/types/core/selection/style/api/finite-state-machine.d.ts +21 -0
  113. package/types/core/selection/style/api/index.d.ts +12 -5
  114. package/types/core/selection/style/api/{check-special-elements.d.ts → is-inside-invisible-element.d.ts} +1 -1
  115. package/types/core/selection/style/api/is-suit-element.d.ts +10 -0
  116. package/types/core/selection/style/api/toggle/toggle-css.d.ts +11 -0
  117. package/types/core/selection/style/api/toggle/toggle-ordered-list.d.ts +11 -0
  118. package/types/core/selection/style/api/{toggle-styles.d.ts → toggle-commit-styles.d.ts} +1 -3
  119. package/types/core/selection/style/api/{post-process-list-element.d.ts → wrap-and-commit-style.d.ts} +3 -3
  120. package/types/core/selection/style/api/wrap-ordered-list.d.ts +12 -0
  121. package/types/core/selection/style/api/wrap-unwrapped-text.d.ts +2 -2
  122. package/types/core/selection/style/apply-style.d.ts +1 -4
  123. package/types/core/selection/style/commit-style.d.ts +7 -0
  124. package/types/core/ui/helpers/buttons.d.ts +2 -2
  125. package/types/core/view/view-with-toolbar.d.ts +2 -1
  126. package/types/core/view/view.d.ts +2 -2
  127. package/types/modules/file-browser/data-provider.d.ts +1 -1
  128. package/types/modules/index.d.ts +1 -1
  129. package/types/modules/status-bar/status-bar.d.ts +6 -1
  130. package/types/modules/table.d.ts +2 -2
  131. package/types/plugins/fix/clean-html.d.ts +4 -0
  132. package/types/plugins/index.d.ts +1 -0
  133. package/types/plugins/ordered-list.d.ts +8 -1
  134. package/{build-system/plugins/banner.js → types/plugins/powered-by-jodit.d.ts} +7 -10
  135. package/types/plugins/size/resize-handler.d.ts +1 -1
  136. package/types/plugins/source/source.d.ts +1 -1
  137. package/types/types/ajax.d.ts +15 -6
  138. package/types/types/async.d.ts +5 -4
  139. package/types/types/events.d.ts +12 -12
  140. package/types/types/style.d.ts +2 -0
  141. package/types/types/toolbar.d.ts +2 -1
  142. package/types/types/view.d.ts +3 -2
  143. package/.editorconfig +0 -15
  144. package/.eslintignore +0 -3
  145. package/.eslintrc.js +0 -109
  146. package/.prettierrc.json +0 -9
  147. package/.stylelintrc.json +0 -16
  148. package/app.css +0 -112
  149. package/build-system/index.js +0 -78
  150. package/build-system/loaders/css-variables-prefixes.js +0 -12
  151. package/build-system/loaders/lang-loader.js +0 -57
  152. package/build-system/loaders/style.js +0 -31
  153. package/build-system/loaders/svg-loader.js +0 -21
  154. package/build-system/minimizer/css.js +0 -20
  155. package/build-system/minimizer/js.js +0 -41
  156. package/build-system/plugins/define.js +0 -22
  157. package/build-system/plugins/extract-css.js +0 -21
  158. package/build-system/plugins/index.js +0 -31
  159. package/build-system/plugins/post-build.js +0 -52
  160. package/build-system/rules/extra-typescript.js +0 -22
  161. package/build-system/rules/index.js +0 -17
  162. package/build-system/rules/internal-typescript.js +0 -23
  163. package/build-system/rules/langs.js +0 -20
  164. package/build-system/rules/svg.js +0 -16
  165. package/build-system/utils/filename.js +0 -14
  166. package/build-system/utils/post-build.js +0 -28
  167. package/build-system/variables.js +0 -51
  168. package/composer.json +0 -12
  169. package/src/core/ajax.ts +0 -269
  170. package/src/core/selection/style/api/post-process-list-element.ts +0 -33
  171. package/src/core/selection/style/api/toggle-styles.ts +0 -74
  172. package/src/types/core.d.ts +0 -7
  173. package/src/types/core.js.map +0 -1
  174. package/src/types/storage.d.ts +0 -13
  175. package/src/types/storage.js +0 -8
  176. package/src/types/storage.js.map +0 -1
  177. package/types/types/core.js +0 -8
  178. package/types/types/core.js.map +0 -1
  179. package/types/types/storage.js +0 -8
  180. package/types/types/storage.js.map +0 -1
@@ -4,126 +4,196 @@
4
4
  * Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
 
7
- import type { ICreate, IJodit, Nullable } from '../../../types';
7
+ import type { IJodit, Nullable, CanUndef, CommitMode } from '../../../types';
8
8
  import type { CommitStyle } from './commit-style';
9
- import { Dom } from '../../dom';
10
- import { attr, css, normalizeNode } from '../../helpers';
9
+ import { normalizeNode } from '../../helpers';
11
10
  import {
12
11
  getSuitParent,
13
12
  getSuitChild,
14
- checkSpecialElements,
15
- getClosestWrapper,
16
- unwrapChildren,
17
- wrapUnwrappedText,
18
- postProcessListElement,
19
- toggleStyles
13
+ isInsideInvisibleElement,
14
+ toggleCommitStyles,
15
+ unwrapChildren
16
+ } from './api';
17
+ import { CHANGE, INITIAL, REPLACE, UNWRAP, WRAP } from './commit-style';
18
+ import { Dom } from '../../dom';
19
+ import {
20
+ toggleOrderedList,
21
+ wrapAndCommitStyle,
22
+ isSuitElement,
23
+ extractSelectedPart,
24
+ toggleCSS,
25
+ FiniteStateMachine
20
26
  } from './api';
21
27
 
22
- /**
23
- * Apply options to selection
24
- */
25
- export function ApplyStyle(jodit: IJodit, style: CommitStyle): void {
26
- const { s: sel, editor: root, createInside: ci } = jodit,
27
- rng = () => sel.createRange();
28
+ export function ApplyStyle(jodit: IJodit, cs: CommitStyle): void {
29
+ const { s: sel, editor } = jodit;
30
+
31
+ const fsm = new FiniteStateMachine('start', {
32
+ start: {
33
+ start() {
34
+ sel.save();
35
+ normalizeNode(editor.firstChild); // FF fix for test "commandsTest - Exec command "bold"
36
+ this.setState('generator');
37
+ }
38
+ },
39
+
40
+ generator: {
41
+ initGenerator() {
42
+ return jodit.s.wrapInTagGen();
43
+ },
28
44
 
29
- let wrap: Nullable<boolean> = null;
45
+ nextFont(gen: Generator<HTMLElement>): CanUndef<HTMLElement> {
46
+ const font = gen.next();
30
47
 
31
- sel.save();
48
+ if (font.done) {
49
+ this.setState('end');
50
+ return;
51
+ }
32
52
 
33
- normalizeNode(sel.area.firstChild); // FF fix for test "commandsTest - Exec command "bold"
53
+ if (
54
+ isInsideInvisibleElement(font.value, editor) ||
55
+ Dom.isEmptyContent(font.value)
56
+ ) {
57
+ return;
58
+ }
34
59
 
35
- const gen = jodit.s.wrapInTagGen();
36
- let font = gen.next();
60
+ this.setState('check');
37
61
 
38
- while (!font.done) {
39
- wrap = applyToElement(style, font.value, root, rng, ci, wrap);
40
- font = gen.next();
41
- }
62
+ return font.value;
63
+ }
64
+ },
42
65
 
43
- sel.restore();
44
- }
66
+ check: {
67
+ work(font: HTMLElement): Nullable<HTMLElement> {
68
+ let elm =
69
+ getSuitParent(cs, font, jodit.editor) ||
70
+ getSuitChild(cs, font);
45
71
 
46
- /**
47
- * Apply options to all selected fragment
48
- * @param font - a fake element that wraps all parts of the selection
49
- */
50
- function applyToElement(
51
- style: CommitStyle,
52
- font: HTMLElement,
53
- root: HTMLElement,
54
- range: () => Range,
55
- ci: ICreate,
56
- wrap: Nullable<boolean>
57
- ): Nullable<boolean> {
58
- if (checkSpecialElements(font, root)) {
59
- return wrap;
60
- }
72
+ if (elm) {
73
+ this.setState('wholeElement');
74
+ return elm;
75
+ }
61
76
 
62
- const toggleNode =
63
- getSuitParent(style, font, root) ||
64
- getSuitChild(style, font) ||
65
- getClosestWrapper(style, font, root, range);
77
+ elm = Dom.closest(
78
+ font,
79
+ node => isSuitElement(cs, node, true),
80
+ jodit.editor
81
+ );
66
82
 
67
- if (toggleNode) {
68
- return toggleStyles(style, toggleNode, wrap);
69
- }
83
+ if (elm) {
84
+ if (!cs.elementIsBlock) {
85
+ extractSelectedPart(elm, font, jodit);
86
+ }
87
+ }
70
88
 
71
- if (unwrapChildren(style, font)) {
72
- return wrap;
73
- }
89
+ if (cs.elementIsList && Dom.isTag(elm, ['ul', 'ol'])) {
90
+ this.setState('orderList');
91
+ return font;
92
+ }
74
93
 
75
- if (wrap == null) {
76
- wrap = true;
77
- }
94
+ if (elm) {
95
+ this.setState('wholeElement');
96
+ return elm;
97
+ }
78
98
 
79
- if (!wrap) {
80
- return wrap;
81
- }
99
+ if (unwrapChildren(cs, font)) {
100
+ this.setState('endProcess');
101
+ return null;
102
+ }
82
103
 
83
- let wrapper = font;
104
+ this.setState('wrap');
105
+ return font;
106
+ }
107
+ },
84
108
 
85
- if (style.elementIsBlock) {
86
- const ulReg = /^(ul|ol|li|td|th|tr|tbody|table)$/i;
109
+ wholeElement: {
110
+ toggleStyles(toggleElm: HTMLElement): void {
111
+ let mode: CommitMode = INITIAL;
87
112
 
88
- const box = Dom.up(
89
- font,
90
- node => {
91
- if (Dom.isBlock(node)) {
92
- if (
93
- ulReg.test(style.element) ||
94
- !ulReg.test(node.nodeName)
95
- ) {
96
- return true;
97
- }
113
+ if (toggleCommitStyles(cs, toggleElm)) {
114
+ mode = UNWRAP;
115
+ } else {
116
+ mode = toggleCSS(cs, toggleElm, jodit, mode);
98
117
  }
99
118
 
100
- return false;
101
- },
102
- root
103
- );
119
+ this.setState('generator', mode);
120
+ }
121
+ },
104
122
 
105
- if (box) {
106
- wrapper = box;
107
- } else {
108
- wrapper = wrapUnwrappedText(style, font, root, ci, range);
109
- }
110
- }
123
+ orderList: {
124
+ toggleStyles(font: HTMLElement): void {
125
+ let mode: CommitMode = INITIAL;
126
+ const li = Dom.closest(font, 'li', jodit.editor);
111
127
 
112
- const newWrapper = Dom.replace(wrapper, style.element, ci, true);
128
+ if (!li) {
129
+ this.setState('generator');
130
+ return;
131
+ }
113
132
 
114
- attr(newWrapper, 'size', null);
133
+ const ul = Dom.closest(font, ['ul', 'ol'], jodit.editor);
115
134
 
116
- if (style.elementIsBlock) {
117
- postProcessListElement(style, newWrapper, ci);
118
- }
135
+ if (!ul) {
136
+ this.setState('generator');
137
+ return;
138
+ }
119
139
 
120
- if (style.options.style && style.elementIsDefault) {
121
- css(newWrapper, style.options.style);
122
- }
140
+ mode = toggleOrderedList(cs, li, jodit, mode);
141
+
142
+ if (mode === REPLACE || mode === UNWRAP || mode === CHANGE) {
143
+ this.setState('endWhile');
144
+ return;
145
+ }
146
+
147
+ this.setState('generator');
148
+ }
149
+ },
123
150
 
124
- if (style.options.className) {
125
- newWrapper.classList.toggle(style.options.className);
151
+ wrap: {
152
+ toggleStyles(font: HTMLElement): void {
153
+ if (this.getSubState() !== 'unwrap') {
154
+ const toggleElm = wrapAndCommitStyle(cs, font, jodit);
155
+ toggleCSS(cs, toggleElm, jodit, WRAP);
156
+ }
157
+
158
+ this.setState('generator');
159
+ }
160
+ },
161
+
162
+ endWhile: {
163
+ nextFont(gen: Generator<HTMLElement>): void {
164
+ const font = gen.next();
165
+
166
+ if (font.done) {
167
+ this.setState('end');
168
+ }
169
+ }
170
+ },
171
+
172
+ endProcess: {
173
+ toggleStyles() {
174
+ this.setState('generator');
175
+ }
176
+ },
177
+
178
+ end: {
179
+ finalize() {
180
+ sel.restore();
181
+ }
182
+ }
183
+ });
184
+
185
+ fsm.dispatch('start');
186
+
187
+ const gen = fsm.dispatch('initGenerator');
188
+
189
+ while (fsm.getState() !== 'end') {
190
+ const font = fsm.dispatch<HTMLElement>('nextFont', gen);
191
+
192
+ if (font) {
193
+ const wrapper = fsm.dispatch<HTMLElement>('work', font);
194
+ fsm.dispatch('toggleStyles', wrapper);
195
+ }
126
196
  }
127
197
 
128
- return wrap;
198
+ fsm.dispatch('finalize', gen);
129
199
  }
@@ -8,7 +8,20 @@ import type { HTMLTagNames, IJodit, IStyleOptions } from '../../../types';
8
8
  import { IS_BLOCK } from '../../constants';
9
9
  import { ApplyStyle } from './apply-style';
10
10
 
11
+ export const WRAP = 'wrap';
12
+ export const UNWRAP = 'unwrap';
13
+ export const CHANGE = 'change';
14
+ export const UNSET = 'unset';
15
+ export const INITIAL = 'initial';
16
+ export const REPLACE = 'replace';
17
+
11
18
  export class CommitStyle {
19
+ get elementIsList(): boolean {
20
+ return Boolean(
21
+ this.options.element && ['ul', 'ol'].includes(this.options.element)
22
+ );
23
+ }
24
+
12
25
  get element(): HTMLTagNames {
13
26
  return this.options.element || this.defaultTag;
14
27
  }
@@ -9,6 +9,7 @@ import { toArray } from '../helpers/array/to-array';
9
9
 
10
10
  export abstract class Elms implements IElms {
11
11
  abstract getElm(elementName: string): HTMLElement;
12
+
12
13
  abstract getElms(elementName: string): HTMLElement[];
13
14
 
14
15
  /**
@@ -31,6 +31,8 @@
31
31
  }
32
32
 
33
33
  .jodit-ui-button-interaction() {
34
+ cursor: pointer;
35
+
34
36
  &:hover:not([disabled]) {
35
37
  background-color: var(--color-button-background-hover);
36
38
  opacity: 1;
@@ -8,7 +8,8 @@ import type {
8
8
  Buttons,
9
9
  ButtonsGroup,
10
10
  ButtonsGroups,
11
- IControlType
11
+ IControlType,
12
+ IJodit
12
13
  } from '../../../types';
13
14
  import { isArray } from '../../helpers/checker';
14
15
 
@@ -18,14 +19,20 @@ export const isButtonGroup = (
18
19
  return isArray((<ButtonsGroup>item).buttons);
19
20
  };
20
21
 
21
- export const flatButtonsSet = (
22
- buttons: ButtonsGroups
23
- ): Set<string | IControlType> =>
24
- new Set(
22
+ export function flatButtonsSet(
23
+ buttons: ButtonsGroups,
24
+ jodit: IJodit
25
+ ): Set<string | IControlType> {
26
+ const groups = jodit.getRegisteredButtonGroups();
27
+
28
+ return new Set(
25
29
  buttons.reduce(
26
30
  (acc: Buttons, item: ButtonsGroup | string | IControlType) => {
27
31
  if (isButtonGroup(item)) {
28
- acc.push(...(<ButtonsGroup>item).buttons);
32
+ acc = acc.concat([
33
+ ...(<ButtonsGroup>item).buttons,
34
+ ...(groups[item.group] ?? [])
35
+ ]);
29
36
  } else {
30
37
  acc.push(item);
31
38
  }
@@ -35,3 +42,4 @@ export const flatButtonsSet = (
35
42
  [] as Buttons
36
43
  )
37
44
  );
45
+ }
@@ -23,7 +23,9 @@ export function getControlType(
23
23
  ): IControlTypeStrong {
24
24
  let buttonControl: IControlTypeStrong;
25
25
 
26
- if (!controls) controls = Config.defaultOptions.controls;
26
+ if (!controls) {
27
+ controls = Config.defaultOptions.controls;
28
+ }
27
29
 
28
30
  if (!isString(button)) {
29
31
  buttonControl = { name: 'empty', ...ConfigFlatten(button) };
@@ -25,6 +25,7 @@
25
25
  width: 100%;
26
26
  height: auto;
27
27
  min-height: var(--button-size);
28
+ cursor: pointer;
28
29
  }
29
30
 
30
31
  &__text:not(:empty) {
@@ -7,16 +7,18 @@
7
7
  @import (reference) '../../../styles/variables';
8
8
  @import (reference) '../../../styles/mixins';
9
9
 
10
- .jodit-popup {
11
- --box-shadow: 0 4px 1px -2px rgba(76, 76, 76, 0.2),
10
+ :root {
11
+ --popup-box-shadow: 0 4px 1px -2px rgba(76, 76, 76, 0.2),
12
12
  0 3px 3px 0 rgba(76, 76, 76, 0.15), 0 1px 4px 0 rgba(76, 76, 76, 0.13);
13
+ }
13
14
 
15
+ .jodit-popup {
14
16
  .jodit-box();
15
17
 
16
18
  position: fixed;
17
19
  z-index: var(--z-index-popup);
18
20
  display: inline-block;
19
- box-shadow: var(--box-shadow);
21
+ box-shadow: var(--popup-box-shadow);
20
22
  transform: translate3d(0, 0, 0);
21
23
 
22
24
  &__content {
@@ -75,6 +75,10 @@ export abstract class ViewWithToolbar extends View implements IViewWithToolbar {
75
75
  registeredButtons: Set<IPluginButton> = new Set();
76
76
  private groupToButtons: IDictionary<string[]> = {};
77
77
 
78
+ getRegisteredButtonGroups(): IDictionary<string[]> {
79
+ return this.groupToButtons;
80
+ }
81
+
78
82
  /**
79
83
  * Register button for group
80
84
  */
@@ -29,7 +29,7 @@ import { BASE_PATH } from '../constants';
29
29
  import {
30
30
  Component,
31
31
  STATUSES,
32
- EventsNative,
32
+ EventEmitter,
33
33
  ProgressBar,
34
34
  Create,
35
35
  Dom,
@@ -124,7 +124,7 @@ export abstract class View extends Component implements IViewBased, Mods, Elms {
124
124
  this.__container = container;
125
125
  }
126
126
 
127
- events!: EventsNative;
127
+ events!: EventEmitter;
128
128
  get e(): this['events'] {
129
129
  return this.events;
130
130
  }
@@ -269,7 +269,7 @@ export abstract class View extends Component implements IViewBased, Mods, Elms {
269
269
  this.initOptions(options);
270
270
  this.initOwners();
271
271
 
272
- this.events = new EventsNative(this.od);
272
+ this.events = new EventEmitter(this.od);
273
273
  this.create = new Create(this.od);
274
274
 
275
275
  this.container = this.c.div();
@@ -37,7 +37,7 @@ export class ContextMenu extends Popup implements IContextMenu {
37
37
  actions: Array<false | IContextMenuAction>
38
38
  ): void {
39
39
  const self = this,
40
- content = this.j.c.div('jodit-context-menu__actions');
40
+ content = this.j.c.div(this.getFullElName('actions'));
41
41
 
42
42
  if (!isArray(actions)) {
43
43
  return;
@@ -97,7 +97,7 @@ Jodit.make('#editor', {
97
97
  - filebrowser.ajax.headers={} An object of additional header key/value pairs toWYSIWYG
98
98
  send along with requests using the `XMLHttpRequest` transport. The header `X-Requested-With: XMLHttpRequest`
99
99
  is always added, but its default `XMLHttpRequest` value can be changed here.
100
- @property {object} filebrowser.resize Settings for AJAX connections toWYSIWYG the server toWYSIWYG resize
100
+ @property {object} `filebrowser.resize` Settings for AJAX connections toWYSIWYG the server toWYSIWYG resize
101
101
  image. By default, the uses {@link Jodit.defaultOptions.filebrowser.ajax|filebrowser.ajax} with argument
102
102
  action=create
103
103
  - filebrowser.crop Settings for AJAX connections toWYSIWYG the server toWYSIWYG crop image.
@@ -29,7 +29,7 @@ import {
29
29
  normalizeRelativePath,
30
30
  set
31
31
  } from '../../core/helpers';
32
- import { Ajax } from '../../core/ajax';
32
+ import { Ajax } from '../../core/request';
33
33
  import { autobind } from '../../core/decorators';
34
34
  import { FileBrowserItem } from './builders/item';
35
35
 
@@ -66,12 +66,10 @@ export default class DataProvider implements IFileBrowserDataProvider {
66
66
  return this.options;
67
67
  }
68
68
 
69
- private ajaxInstances: Map<string, IAjax> = new Map();
69
+ private ajaxInstances: Map<string, IAjax<IFileBrowserAnswer>> = new Map();
70
70
 
71
- protected get<T = IFileBrowserAnswer>(
72
- name: keyof IFileBrowserOptions,
73
- success?: (resp: IFileBrowserAnswer) => void,
74
- error?: (error: Error) => void
71
+ protected get<T extends IFileBrowserAnswer = IFileBrowserAnswer>(
72
+ name: keyof IFileBrowserOptions
75
73
  ): Promise<T> {
76
74
  const ai = this.ajaxInstances;
77
75
 
@@ -98,33 +96,27 @@ export default class DataProvider implements IFileBrowserDataProvider {
98
96
  opts.data = opts.prepareData.call(this, opts.data as IDictionary);
99
97
  }
100
98
 
101
- const ajax = new Ajax(this.parent, opts);
102
-
103
- let promise = ajax.send();
104
-
99
+ const ajax = new Ajax<T>(this.parent, opts);
105
100
  ai.set(name, ajax);
106
101
 
107
- promise = promise.then(resp => {
108
- if (!this.isSuccess(resp)) {
109
- throw new Error(this.getMessage(resp));
110
- }
111
-
112
- return resp;
113
- });
114
-
115
- if (success) {
116
- promise = promise.then(success);
117
- }
118
-
119
- if (error) {
120
- promise = promise.catch(error);
121
- }
102
+ const promise = ajax.send();
122
103
 
123
- return promise.finally(() => {
104
+ promise.finally(() => {
124
105
  ajax.destruct();
125
106
  ai.delete(name);
107
+
126
108
  this.progressHandler(100);
127
109
  });
110
+
111
+ return promise
112
+ .then(resp => resp.json())
113
+ .then(resp => {
114
+ if (resp && !this.isSuccess(resp)) {
115
+ throw new Error(this.getMessage(resp));
116
+ }
117
+
118
+ return resp;
119
+ });
128
120
  }
129
121
 
130
122
  private progressHandler = (ignore: number): void => {};
@@ -297,7 +289,7 @@ export default class DataProvider implements IFileBrowserDataProvider {
297
289
  getPathByUrl(url: string): Promise<any> {
298
290
  set('options.getLocalFileByUrl.data.url', url, this);
299
291
 
300
- return this.get('getLocalFileByUrl', resp => {
292
+ return this.get('getLocalFileByUrl').then(resp => {
301
293
  if (this.isSuccess(resp)) {
302
294
  return resp.data;
303
295
  }
@@ -396,10 +388,6 @@ export default class DataProvider implements IFileBrowserDataProvider {
396
388
  resp = fr.process.call(this, resp);
397
389
  }
398
390
 
399
- if (!this.isSuccess(resp)) {
400
- throw error(this.getMessage(resp));
401
- }
402
-
403
391
  return this.getMessage(resp);
404
392
  });
405
393
  }
@@ -457,10 +445,6 @@ export default class DataProvider implements IFileBrowserDataProvider {
457
445
  resp = fr.process.call(self, resp);
458
446
  }
459
447
 
460
- if (!this.isSuccess(resp)) {
461
- throw error(this.getMessage(resp));
462
- }
463
-
464
448
  return this.getMessage(resp);
465
449
  });
466
450
  }
@@ -496,7 +480,7 @@ export default class DataProvider implements IFileBrowserDataProvider {
496
480
  name: string,
497
481
  newname: string | void,
498
482
  box: ImageBox | void
499
- ): Promise<boolean> {
483
+ ): Promise<true> {
500
484
  if (!this.o[type]) {
501
485
  this.o[type] = {
502
486
  data: {}
@@ -522,12 +506,8 @@ export default class DataProvider implements IFileBrowserDataProvider {
522
506
  query.data.name = name;
523
507
  query.data.source = source;
524
508
 
525
- return this.get(type).then(resp => {
526
- if (this.isSuccess(resp)) {
527
- return true;
528
- }
529
-
530
- throw error(this.getMessage(resp));
509
+ return this.get(type).then(() => {
510
+ return true;
531
511
  });
532
512
  }
533
513
 
@@ -102,8 +102,11 @@ export class FileBrowser extends ViewWithToolbar implements IFileBrowser {
102
102
  }
103
103
 
104
104
  this.tree.classList.add('jodit-filebrowser_active');
105
+
105
106
  Dom.detach(this.tree);
107
+
106
108
  this.tree.appendChild(this.loader.cloneNode(true));
109
+
107
110
  const items = this.loadItems();
108
111
 
109
112
  if (this.o.showFoldersPanel) {
@@ -6,7 +6,7 @@
6
6
 
7
7
  export * from '../core/events';
8
8
  export { Async } from '../core/async';
9
- export { Ajax } from '../core/ajax';
9
+ export * from '../core/request';
10
10
  export { Component, ViewComponent, STATUSES } from '../core/component';
11
11
  export { ContextMenu } from './context-menu/context-menu';
12
12
  export { Alert, Confirm, Prompt, Dialog } from './dialog/';
@@ -10,12 +10,24 @@
10
10
  .jodit-status-bar {
11
11
  display: flex;
12
12
  overflow: hidden;
13
+ height: 20px;
14
+
13
15
  align-items: center;
14
16
  justify-content: flex-start;
17
+
15
18
  padding: 0 calc(var(--padding-default) / 2);
19
+
20
+ &_resize-handle_true {
21
+ padding-right: 14px;
22
+ }
23
+
16
24
  background-color: var(--color-panel);
17
25
  border-radius: 0 0 var(--border-radius-default) var(--border-radius-default);
26
+
27
+ color: var(--color-text-icons);
28
+
18
29
  font-size: var(--font-size-small);
30
+ text-transform: uppercase;
19
31
 
20
32
  &::before {
21
33
  flex: auto;
@@ -48,11 +60,25 @@
48
60
 
49
61
  &:hover {
50
62
  background-color: var(--color-background-gray);
51
- color: var(--color-text);
52
63
  text-decoration: none;
53
64
  }
54
65
  }
55
66
  }
67
+
68
+ a.jodit-status-bar-link {
69
+ cursor: pointer;
70
+
71
+ &,
72
+ &:hover,
73
+ &:visited {
74
+ background-color: transparent;
75
+ color: var(--color-text-icons);
76
+ }
77
+
78
+ &:hover {
79
+ text-decoration: underline;
80
+ }
81
+ }
56
82
  }
57
83
 
58
84
  .jodit-workplace + .jodit-status-bar:not(:empty) {