jodit 3.9.3 → 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.
- package/.idea/workspace.xml +129 -121
- package/CHANGELOG.MD +21 -5
- package/build/jodit.css +92 -33
- package/build/jodit.es2018.css +65 -29
- package/build/jodit.es2018.en.css +65 -29
- package/build/jodit.es2018.en.js +854 -466
- package/build/jodit.es2018.en.min.css +1 -1
- package/build/jodit.es2018.en.min.js +1 -1
- package/build/jodit.es2018.js +854 -466
- package/build/jodit.es2018.min.css +1 -1
- package/build/jodit.es2018.min.js +1 -1
- package/build/jodit.js +1804 -1360
- package/build/jodit.min.css +2 -2
- package/build/jodit.min.js +1 -1
- package/index.d.ts +10 -0
- package/package.json +1 -1
- package/src/config.ts +1 -1
- package/src/core/dom.ts +10 -3
- package/src/core/helpers/size/index.ts +1 -0
- package/src/core/helpers/size/object-size.ts +22 -0
- package/src/core/selection/select.ts +1 -0
- package/src/core/selection/style/api/{get-closest-wrapper.ts → extract.ts} +26 -43
- package/src/core/selection/style/api/finite-state-machine.ts +66 -0
- package/src/core/selection/style/api/index.ts +12 -5
- package/src/core/selection/style/api/{check-special-elements.ts → is-inside-invisible-element.ts} +1 -1
- package/src/core/selection/style/api/is-suit-element.ts +12 -1
- package/src/core/selection/style/api/toggle/toggle-css.ts +134 -0
- package/src/core/selection/style/api/toggle/toggle-ordered-list.ts +49 -0
- package/src/core/selection/style/api/toggle-commit-styles.ts +27 -0
- package/src/core/selection/style/api/wrap-and-commit-style.ts +68 -0
- package/src/core/selection/style/api/wrap-ordered-list.ts +37 -0
- package/src/core/selection/style/api/wrap-unwrapped-text.ts +1 -4
- package/src/core/selection/style/apply-style.ts +161 -97
- package/src/core/selection/style/commit-style.ts +13 -0
- package/src/core/ui/button/button/button.less +2 -0
- package/src/core/ui/helpers/buttons.ts +14 -6
- package/src/core/ui/list/list.less +1 -0
- package/src/core/ui/popup/popup.less +5 -3
- package/src/core/view/view-with-toolbar.ts +4 -0
- package/src/modules/status-bar/status-bar.less +27 -1
- package/src/modules/status-bar/status-bar.ts +15 -1
- package/src/modules/widget/tabs/tabs.less +1 -0
- package/src/plugins/bold.ts +2 -2
- package/src/plugins/font.ts +11 -1
- package/src/plugins/index.ts +1 -0
- package/src/plugins/mobile.ts +10 -14
- package/src/plugins/ordered-list.ts +40 -1
- package/src/plugins/powered-by-jodit.ts +39 -0
- package/src/plugins/print/preview.ts +9 -2
- package/src/plugins/resizer/resizer.less +10 -7
- package/src/plugins/resizer/resizer.ts +12 -14
- package/src/plugins/size/assests/resize-handler.svg +4 -0
- package/src/plugins/size/resize-handler.ts +4 -4
- package/src/plugins/size/size.less +6 -8
- package/src/plugins/source/source.ts +15 -1
- package/src/styles/themes/dark.less +11 -1
- package/src/types/style.d.ts +2 -0
- package/src/types/toolbar.d.ts +2 -1
- package/src/types/view.d.ts +1 -0
- package/types/core/dom.d.ts +2 -1
- package/types/core/helpers/size/index.d.ts +1 -0
- package/types/core/helpers/size/object-size.d.ts +7 -0
- package/types/core/selection/style/api/{get-closest-wrapper.d.ts → extract.d.ts} +6 -5
- package/types/core/selection/style/api/finite-state-machine.d.ts +21 -0
- package/types/core/selection/style/api/index.d.ts +12 -5
- package/types/core/selection/style/api/{check-special-elements.d.ts → is-inside-invisible-element.d.ts} +1 -1
- package/types/core/selection/style/api/is-suit-element.d.ts +9 -0
- package/types/core/selection/style/api/toggle/toggle-css.d.ts +11 -0
- package/types/core/selection/style/api/toggle/toggle-ordered-list.d.ts +11 -0
- package/types/core/selection/style/api/{toggle-styles.d.ts → toggle-commit-styles.d.ts} +1 -3
- package/types/core/selection/style/api/{post-process-list-element.d.ts → wrap-and-commit-style.d.ts} +3 -3
- package/types/core/selection/style/api/wrap-ordered-list.d.ts +12 -0
- package/types/core/selection/style/apply-style.d.ts +1 -4
- package/types/core/selection/style/commit-style.d.ts +7 -0
- package/types/core/ui/helpers/buttons.d.ts +2 -2
- package/types/core/view/view-with-toolbar.d.ts +2 -1
- package/types/modules/status-bar/status-bar.d.ts +6 -1
- package/types/plugins/index.d.ts +1 -0
- package/types/plugins/ordered-list.d.ts +8 -1
- package/types/plugins/powered-by-jodit.d.ts +12 -0
- package/types/types/style.d.ts +2 -0
- package/types/types/toolbar.d.ts +2 -1
- package/types/types/view.d.ts +1 -0
- package/src/core/selection/style/api/post-process-list-element.ts +0 -33
- package/src/core/selection/style/api/toggle-styles.ts +0 -74
|
@@ -4,132 +4,196 @@
|
|
|
4
4
|
* Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { IJodit, Nullable } from '../../../types';
|
|
7
|
+
import type { IJodit, Nullable, CanUndef, CommitMode } from '../../../types';
|
|
8
8
|
import type { CommitStyle } from './commit-style';
|
|
9
|
-
import {
|
|
10
|
-
import { attr, css, normalizeNode } from '../../helpers';
|
|
9
|
+
import { normalizeNode } from '../../helpers';
|
|
11
10
|
import {
|
|
12
11
|
getSuitParent,
|
|
13
12
|
getSuitChild,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
unwrapChildren
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
45
|
+
nextFont(gen: Generator<HTMLElement>): CanUndef<HTMLElement> {
|
|
46
|
+
const font = gen.next();
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
if (font.done) {
|
|
49
|
+
this.setState('end');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
32
52
|
|
|
33
|
-
|
|
53
|
+
if (
|
|
54
|
+
isInsideInvisibleElement(font.value, editor) ||
|
|
55
|
+
Dom.isEmptyContent(font.value)
|
|
56
|
+
) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
34
59
|
|
|
35
|
-
|
|
36
|
-
let font = gen.next();
|
|
60
|
+
this.setState('check');
|
|
37
61
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
62
|
+
return font.value;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
42
65
|
|
|
43
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
function applyToElement(
|
|
51
|
-
style: CommitStyle,
|
|
52
|
-
font: HTMLElement,
|
|
53
|
-
range: () => Range,
|
|
54
|
-
jodit: IJodit,
|
|
55
|
-
wrap: Nullable<boolean>
|
|
56
|
-
): Nullable<boolean> {
|
|
57
|
-
const root = jodit.editor;
|
|
58
|
-
|
|
59
|
-
if (checkSpecialElements(font, root)) {
|
|
60
|
-
return wrap;
|
|
61
|
-
}
|
|
72
|
+
if (elm) {
|
|
73
|
+
this.setState('wholeElement');
|
|
74
|
+
return elm;
|
|
75
|
+
}
|
|
62
76
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
elm = Dom.closest(
|
|
78
|
+
font,
|
|
79
|
+
node => isSuitElement(cs, node, true),
|
|
80
|
+
jodit.editor
|
|
81
|
+
);
|
|
67
82
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
if (elm) {
|
|
84
|
+
if (!cs.elementIsBlock) {
|
|
85
|
+
extractSelectedPart(elm, font, jodit);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
71
88
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
89
|
+
if (cs.elementIsList && Dom.isTag(elm, ['ul', 'ol'])) {
|
|
90
|
+
this.setState('orderList');
|
|
91
|
+
return font;
|
|
92
|
+
}
|
|
75
93
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
if (elm) {
|
|
95
|
+
this.setState('wholeElement');
|
|
96
|
+
return elm;
|
|
97
|
+
}
|
|
79
98
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
if (unwrapChildren(cs, font)) {
|
|
100
|
+
this.setState('endProcess');
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
83
103
|
|
|
84
|
-
|
|
104
|
+
this.setState('wrap');
|
|
105
|
+
return font;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
85
108
|
|
|
86
|
-
|
|
87
|
-
|
|
109
|
+
wholeElement: {
|
|
110
|
+
toggleStyles(toggleElm: HTMLElement): void {
|
|
111
|
+
let mode: CommitMode = INITIAL;
|
|
88
112
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
ulReg.test(style.element) ||
|
|
95
|
-
!ulReg.test(node.nodeName)
|
|
96
|
-
) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
113
|
+
if (toggleCommitStyles(cs, toggleElm)) {
|
|
114
|
+
mode = UNWRAP;
|
|
115
|
+
} else {
|
|
116
|
+
mode = toggleCSS(cs, toggleElm, jodit, mode);
|
|
99
117
|
}
|
|
100
118
|
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
);
|
|
119
|
+
this.setState('generator', mode);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
105
122
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
}
|
|
123
|
+
orderList: {
|
|
124
|
+
toggleStyles(font: HTMLElement): void {
|
|
125
|
+
let mode: CommitMode = INITIAL;
|
|
126
|
+
const li = Dom.closest(font, 'li', jodit.editor);
|
|
112
127
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
true
|
|
118
|
-
);
|
|
128
|
+
if (!li) {
|
|
129
|
+
this.setState('generator');
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
119
132
|
|
|
120
|
-
|
|
133
|
+
const ul = Dom.closest(font, ['ul', 'ol'], jodit.editor);
|
|
121
134
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
if (!ul) {
|
|
136
|
+
this.setState('generator');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
125
139
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
+
},
|
|
129
150
|
|
|
130
|
-
|
|
131
|
-
|
|
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
|
+
}
|
|
132
196
|
}
|
|
133
197
|
|
|
134
|
-
|
|
198
|
+
fsm.dispatch('finalize', gen);
|
|
135
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
|
}
|
|
@@ -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
|
|
22
|
-
buttons: ButtonsGroups
|
|
23
|
-
|
|
24
|
-
|
|
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.
|
|
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
|
+
}
|
|
@@ -7,16 +7,18 @@
|
|
|
7
7
|
@import (reference) '../../../styles/variables';
|
|
8
8
|
@import (reference) '../../../styles/mixins';
|
|
9
9
|
|
|
10
|
-
|
|
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
|
*/
|
|
@@ -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) {
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import './status-bar.less';
|
|
8
8
|
|
|
9
|
-
import type { IJodit, IStatusBar } from '../../types';
|
|
9
|
+
import type { IJodit, IStatusBar, IDictionary } from '../../types';
|
|
10
10
|
import { ViewComponent, STATUSES } from '../../core/component';
|
|
11
11
|
import { Dom } from '../../core/dom';
|
|
12
|
+
import { Mods } from '../../core/traits';
|
|
12
13
|
|
|
13
14
|
export class StatusBar extends ViewComponent<IJodit> implements IStatusBar {
|
|
14
15
|
className(): string {
|
|
@@ -38,6 +39,19 @@ export class StatusBar extends ViewComponent<IJodit> implements IStatusBar {
|
|
|
38
39
|
return !this.container.classList.contains('jodit_hidden');
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
readonly mods: IDictionary<string | boolean | null> = {};
|
|
43
|
+
|
|
44
|
+
/** @see [[Mods.setMod]] */
|
|
45
|
+
setMod(name: string, value: string | boolean | null): this {
|
|
46
|
+
Mods.setMod.call(this, name, value);
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @see [[Mods.getMod]] */
|
|
51
|
+
getMod(name: string): string | boolean | null {
|
|
52
|
+
return Mods.getMod.call(this, name);
|
|
53
|
+
}
|
|
54
|
+
|
|
41
55
|
/**
|
|
42
56
|
* Height of statusbar
|
|
43
57
|
*/
|
package/src/plugins/bold.ts
CHANGED
|
@@ -40,7 +40,7 @@ Config.prototype.controls.underline = {
|
|
|
40
40
|
tagRegExp: /^(u)$/i,
|
|
41
41
|
tags: ['u'],
|
|
42
42
|
css: {
|
|
43
|
-
'text-decoration': 'underline'
|
|
43
|
+
'text-decoration-line': 'underline'
|
|
44
44
|
},
|
|
45
45
|
tooltip: 'Underline'
|
|
46
46
|
} as IControlType;
|
|
@@ -49,7 +49,7 @@ Config.prototype.controls.strikethrough = {
|
|
|
49
49
|
tagRegExp: /^(s)$/i,
|
|
50
50
|
tags: ['s'],
|
|
51
51
|
css: {
|
|
52
|
-
'text-decoration': 'line-through'
|
|
52
|
+
'text-decoration-line': 'line-through'
|
|
53
53
|
},
|
|
54
54
|
tooltip: 'Strike through'
|
|
55
55
|
} as IControlType;
|
package/src/plugins/font.ts
CHANGED
|
@@ -114,7 +114,17 @@ Config.prototype.controls.font = {
|
|
|
114
114
|
},
|
|
115
115
|
|
|
116
116
|
childTemplate: (editor, key: string, value: string) => {
|
|
117
|
-
|
|
117
|
+
let isAvailable = false;
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
isAvailable =
|
|
121
|
+
key.indexOf('dings') === -1 &&
|
|
122
|
+
document.fonts.check(`16px ${key}`, value);
|
|
123
|
+
} catch {}
|
|
124
|
+
|
|
125
|
+
return `<span style="${
|
|
126
|
+
isAvailable ? `font-family: ${key}!important;` : ''
|
|
127
|
+
}">${value}</span>`;
|
|
118
128
|
},
|
|
119
129
|
|
|
120
130
|
data: {
|
package/src/plugins/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export { link } from './link/link';
|
|
|
34
34
|
export * from './media';
|
|
35
35
|
export { mobile } from './mobile';
|
|
36
36
|
export { orderedList } from './ordered-list';
|
|
37
|
+
export { poweredByJodit } from './powered-by-jodit';
|
|
37
38
|
export { placeholder } from './placeholder/placeholder';
|
|
38
39
|
export { redoUndo } from './redo-undo';
|
|
39
40
|
export { resizer } from './resizer/resizer';
|
package/src/plugins/mobile.ts
CHANGED
|
@@ -13,10 +13,10 @@ import type {
|
|
|
13
13
|
} from '../types/';
|
|
14
14
|
import { Config } from '../config';
|
|
15
15
|
import * as consts from '../core/constants';
|
|
16
|
-
import { splitArray } from '../core/helpers/';
|
|
16
|
+
import { splitArray, toArray } from '../core/helpers/';
|
|
17
17
|
import { makeCollection } from '../modules/toolbar/factory';
|
|
18
18
|
import { UIList } from '../core/ui';
|
|
19
|
-
import { flatButtonsSet
|
|
19
|
+
import { flatButtonsSet } from '../core/ui/helpers/buttons';
|
|
20
20
|
|
|
21
21
|
declare module '../config' {
|
|
22
22
|
interface Config {
|
|
@@ -117,18 +117,14 @@ export function mobile(editor: IJodit): void {
|
|
|
117
117
|
'getDiffButtons.mobile',
|
|
118
118
|
(toolbar: IToolbarCollection): void | ButtonsGroups => {
|
|
119
119
|
if (toolbar === editor.toolbar) {
|
|
120
|
-
const buttons
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
btn => !flatStore.has(btn)
|
|
129
|
-
)
|
|
130
|
-
});
|
|
131
|
-
} else if (!flatStore.has(item)) {
|
|
120
|
+
const buttons = flatButtonsSet(
|
|
121
|
+
splitArray(editor.o.buttons),
|
|
122
|
+
editor
|
|
123
|
+
),
|
|
124
|
+
flatStore = flatButtonsSet(store, editor);
|
|
125
|
+
|
|
126
|
+
return toArray(buttons).reduce((acc, item) => {
|
|
127
|
+
if (!flatStore.has(item)) {
|
|
132
128
|
acc.push(item);
|
|
133
129
|
}
|
|
134
130
|
|
|
@@ -8,6 +8,8 @@ import type { IControlType, IJodit, Nullable } from '../types';
|
|
|
8
8
|
import { Config } from '../config';
|
|
9
9
|
import { Dom } from '../core/dom';
|
|
10
10
|
import { dataBind, toArray } from '../core/helpers';
|
|
11
|
+
import { Plugin } from '../core/plugin';
|
|
12
|
+
import { autobind } from '../core/decorators';
|
|
11
13
|
|
|
12
14
|
const exec: IControlType<IJodit>['exec'] = (jodit, _, { control }): void => {
|
|
13
15
|
const key = `button${control.command}`;
|
|
@@ -52,7 +54,44 @@ Config.prototype.controls.ol = {
|
|
|
52
54
|
/**
|
|
53
55
|
* Process commands insertOrderedList and insertUnOrderedList
|
|
54
56
|
*/
|
|
55
|
-
export
|
|
57
|
+
export class orderedList extends Plugin {
|
|
58
|
+
override buttons: Plugin['buttons'] = [
|
|
59
|
+
{
|
|
60
|
+
name: 'ul',
|
|
61
|
+
group: 'list'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'ol',
|
|
65
|
+
group: 'list'
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
protected afterInit(jodit: IJodit): void {
|
|
70
|
+
jodit
|
|
71
|
+
.registerCommand('insertUnorderedList', this.onCommand)
|
|
72
|
+
.registerCommand('insertOrderedList', this.onCommand);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@autobind
|
|
76
|
+
private onCommand(command: string, _: unknown, type: string): false {
|
|
77
|
+
this.jodit.s.applyStyle(
|
|
78
|
+
{
|
|
79
|
+
listStyleType: type ?? null
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
element: command === 'insertunorderedlist' ? 'ul' : 'ol'
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
this.jodit.setEditorValue();
|
|
87
|
+
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected beforeDestruct(jodit: IJodit): void {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function orderedList1(editor: IJodit): void {
|
|
56
95
|
const isOurCommand = (command: string) =>
|
|
57
96
|
/insert(un)?orderedlist/i.test(command),
|
|
58
97
|
getListWrapper = () =>
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { IJodit } from '../types';
|
|
8
|
+
|
|
9
|
+
declare module '../config' {
|
|
10
|
+
interface Config {
|
|
11
|
+
hidePoweredByJodit: boolean;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function poweredByJodit(jodit: IJodit): void {
|
|
16
|
+
if (
|
|
17
|
+
!jodit.o.hidePoweredByJodit &&
|
|
18
|
+
!jodit.o.inline &&
|
|
19
|
+
(jodit.o.showCharsCounter ||
|
|
20
|
+
jodit.o.showWordsCounter ||
|
|
21
|
+
jodit.o.showXPathInStatusbar)
|
|
22
|
+
) {
|
|
23
|
+
jodit.hookStatus('ready', () => {
|
|
24
|
+
jodit.statusbar.append(
|
|
25
|
+
jodit.create.fromHTML(
|
|
26
|
+
`<a
|
|
27
|
+
tabindex="-1"
|
|
28
|
+
style="text-transform: uppercase"
|
|
29
|
+
class="jodit-status-bar-link"
|
|
30
|
+
target="_blank"
|
|
31
|
+
href="https://xdsoft.net/jodit/">
|
|
32
|
+
Powered by Jodit
|
|
33
|
+
</a>`
|
|
34
|
+
),
|
|
35
|
+
true
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|