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.
- package/.idea/workspace.xml +306 -295
- package/CHANGELOG.MD +349 -119
- package/build/jodit.css +675 -538
- package/build/jodit.es2018.css +536 -436
- package/build/jodit.es2018.en.css +536 -436
- package/build/jodit.es2018.en.js +1529 -738
- package/build/jodit.es2018.en.min.css +1 -1
- package/build/jodit.es2018.en.min.js +1 -1
- package/build/jodit.es2018.js +1533 -742
- package/build/jodit.es2018.min.css +1 -1
- package/build/jodit.es2018.min.js +1 -1
- package/build/jodit.js +2598 -1680
- package/build/jodit.min.css +2 -2
- package/build/jodit.min.js +1 -1
- package/index.d.ts +10 -0
- package/package.json +10 -10
- package/src/config.ts +19 -20
- package/src/core/component/component.ts +16 -15
- package/src/core/component/statuses.ts +6 -6
- package/src/core/dom.ts +16 -4
- package/src/core/events/event-emitter.ts +4 -2
- package/src/core/global.ts +13 -2
- package/src/core/helpers/append-script.ts +14 -0
- package/src/core/helpers/selector.ts +8 -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/storage/engines/local-storage-provider.ts +9 -3
- package/src/core/storage/engines/memory-storage-provider.ts +6 -3
- package/src/core/storage/storage.ts +7 -4
- package/src/core/ui/button/button/button.less +10 -8
- package/src/core/ui/button/button/button.ts +9 -9
- package/src/core/ui/button/group/group.ts +2 -2
- package/src/core/ui/element.ts +4 -3
- package/src/core/ui/form/block/block.ts +1 -1
- package/src/core/ui/form/form.ts +8 -0
- package/src/core/ui/form/inputs/area/area.less +5 -0
- package/src/core/ui/form/inputs/area/area.ts +22 -1
- package/src/core/ui/form/inputs/checkbox/checkbox.less +50 -0
- package/src/core/ui/form/inputs/checkbox/checkbox.ts +48 -4
- package/src/core/ui/form/inputs/input/input.less +1 -1
- package/src/core/ui/form/inputs/input/input.ts +14 -4
- package/src/core/ui/helpers/buttons.ts +14 -6
- package/src/core/ui/icon.ts +3 -1
- package/src/core/ui/index.ts +1 -3
- package/src/core/ui/list/group.less +8 -2
- package/src/core/ui/list/group.ts +2 -2
- package/src/{modules/file-browser/consts.ts → core/ui/list/index.ts} +4 -4
- package/src/core/ui/list/list.less +10 -1
- package/src/core/ui/list/list.ts +20 -3
- package/src/core/ui/{separator.ts → list/separator.ts} +2 -2
- package/src/core/ui/list/spacer.ts +15 -0
- package/src/core/ui/popup/popup.less +5 -3
- package/src/core/ui/popup/popup.ts +53 -1
- package/src/core/view/view-with-toolbar.ts +6 -1
- package/src/jodit.ts +17 -14
- package/src/modules/dialog/dialog.less +1 -16
- package/src/modules/dialog/dialog.ts +10 -3
- package/src/modules/file-browser/builders/context-menu.ts +29 -22
- package/src/modules/file-browser/config.ts +10 -2
- package/src/modules/file-browser/file-browser.ts +50 -29
- package/src/modules/file-browser/listeners/native-listeners.ts +37 -19
- package/src/modules/file-browser/listeners/state-listeners.ts +48 -22
- package/src/modules/file-browser/styles/file-browser.less +4 -291
- package/src/modules/file-browser/styles/preview.less +11 -8
- package/src/modules/file-browser/ui/files/files.less +174 -0
- package/src/modules/file-browser/ui/files/files.ts +14 -0
- package/src/modules/file-browser/ui/index.ts +8 -0
- package/src/modules/file-browser/ui/tree/tree.less +118 -0
- package/src/modules/file-browser/ui/tree/tree.ts +14 -0
- package/src/modules/status-bar/status-bar.less +27 -1
- package/src/modules/status-bar/status-bar.ts +15 -1
- package/src/modules/toolbar/collection/collection.ts +17 -8
- package/src/modules/toolbar/collection/editor-collection.ts +27 -2
- package/src/modules/widget/file-selector/file-selector.ts +1 -1
- package/src/modules/widget/tabs/tabs.less +2 -1
- package/src/modules/widget/tabs/tabs.ts +5 -3
- package/src/plugins/add-new-line/add-new-line.ts +1 -0
- package/src/plugins/bold.ts +2 -2
- package/src/plugins/clipboard/drag-and-drop.ts +4 -1
- package/src/plugins/clipboard/paste/paste.ts +1 -1
- package/src/plugins/font.ts +11 -1
- package/src/plugins/image/image-properties/image-properties.ts +7 -0
- package/src/plugins/index.ts +1 -0
- package/src/plugins/inline-popup/config/config.ts +1 -0
- package/src/plugins/inline-popup/config/items/toolbar.ts +33 -0
- package/src/plugins/inline-popup/inline-popup.ts +17 -0
- package/src/plugins/keyboard/delete.ts +30 -8
- package/src/plugins/link/template.ts +2 -2
- 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 +103 -48
- package/src/plugins/resizer/resizer.less +10 -7
- package/src/plugins/resizer/resizer.ts +12 -14
- package/src/plugins/size/resize-handler.ts +4 -1
- package/src/plugins/size/size.less +2 -19
- package/src/plugins/size/size.ts +6 -1
- package/src/plugins/source/const.ts +7 -0
- package/src/plugins/source/editor/engines/ace.ts +5 -0
- package/src/plugins/source/source.ts +33 -7
- package/src/plugins/sticky/sticky.ts +2 -0
- package/src/styles/icons/index.ts +2 -0
- package/src/styles/icons/resize-handler.svg +4 -0
- package/src/styles/jodit.less +6 -0
- package/src/styles/mixins.less +20 -0
- package/src/styles/themes/dark.less +11 -1
- package/src/types/ajax.d.ts +0 -1
- package/src/types/file-browser.d.ts +13 -1
- package/src/types/jodit.d.ts +4 -1
- package/src/types/popup.d.ts +1 -0
- package/src/types/select.d.ts +2 -0
- package/src/types/storage.ts +3 -3
- package/src/types/style.d.ts +8 -0
- package/src/types/toolbar.d.ts +9 -2
- package/src/types/types.d.ts +1 -1
- package/src/types/ui.d.ts +23 -4
- package/src/types/view.d.ts +1 -0
- package/types/core/component/component.d.ts +10 -5
- package/types/core/component/statuses.d.ts +6 -6
- package/types/core/dom.d.ts +3 -2
- package/types/core/helpers/append-script.d.ts +1 -0
- package/types/core/helpers/selector.d.ts +2 -3
- 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/storage/engines/local-storage-provider.d.ts +3 -3
- package/types/core/storage/engines/memory-storage-provider.d.ts +3 -3
- package/types/core/storage/storage.d.ts +3 -3
- package/types/core/ui/button/button/button.d.ts +3 -3
- package/types/core/ui/form/form.d.ts +1 -0
- package/types/core/ui/form/inputs/area/area.d.ts +7 -1
- package/types/core/ui/form/inputs/checkbox/checkbox.d.ts +10 -3
- package/types/core/ui/helpers/buttons.d.ts +2 -2
- package/types/core/ui/icon.d.ts +1 -1
- package/types/core/ui/index.d.ts +1 -3
- package/types/core/ui/list/group.d.ts +2 -1
- package/types/core/ui/list/index.d.ts +9 -0
- package/types/core/ui/{separator.d.ts → list/separator.d.ts} +1 -1
- package/types/core/ui/list/spacer.d.ts +9 -0
- package/types/core/ui/popup/popup.d.ts +2 -1
- package/types/core/view/view-with-toolbar.d.ts +4 -2
- package/types/jodit.d.ts +6 -6
- package/types/modules/file-browser/file-browser.d.ts +3 -2
- package/types/modules/file-browser/listeners/native-listeners.d.ts +5 -1
- package/types/modules/file-browser/ui/files/files.d.ts +10 -0
- package/types/modules/file-browser/ui/index.d.ts +7 -0
- package/types/modules/file-browser/ui/tree/tree.d.ts +10 -0
- package/types/modules/status-bar/status-bar.d.ts +6 -1
- package/types/modules/toolbar/button/button.d.ts +1 -1
- package/types/modules/toolbar/collection/collection.d.ts +5 -2
- package/types/modules/toolbar/collection/editor-collection.d.ts +9 -1
- package/types/modules/widget/tabs/tabs.d.ts +2 -1
- package/types/plugins/index.d.ts +1 -0
- package/types/plugins/inline-popup/inline-popup.d.ts +4 -0
- package/types/plugins/keyboard/delete.d.ts +2 -0
- package/types/plugins/ordered-list.d.ts +8 -1
- package/types/plugins/powered-by-jodit.d.ts +12 -0
- package/types/plugins/source/const.d.ts +6 -0
- package/types/plugins/source/editor/engines/ace.d.ts +1 -0
- package/types/plugins/source/source.d.ts +1 -0
- package/types/styles/icons/index.d.ts +2 -1
- package/types/types/storage.d.ts +3 -3
- package/types/types/{ajax.d.ts → types/ajax.d.ts} +0 -1
- package/types/types/{async.d.ts → types/async.d.ts} +0 -0
- package/types/types/{context.d.ts → types/context.d.ts} +0 -0
- package/types/types/{core.ts → types/core.ts} +0 -0
- package/types/types/{create.d.ts → types/create.d.ts} +0 -0
- package/types/types/{dialog.d.ts → types/dialog.d.ts} +0 -0
- package/types/types/{events.d.ts → types/events.d.ts} +0 -0
- package/types/types/{file-browser.d.ts → types/file-browser.d.ts} +13 -1
- package/types/types/{form.d.ts → types/form.d.ts} +0 -0
- package/types/types/{index.d.ts → types/index.d.ts} +0 -0
- package/types/types/{jodit.d.ts → types/jodit.d.ts} +4 -1
- package/types/types/{observe.d.ts → types/observe.d.ts} +0 -0
- package/types/types/{plugin.d.ts → types/plugin.d.ts} +0 -0
- package/types/types/{popup.d.ts → types/popup.d.ts} +1 -0
- package/types/types/{select.d.ts → types/select.d.ts} +2 -0
- package/types/types/{source.d.ts → types/source.d.ts} +0 -0
- package/types/types/{storage.ts → types/storage.ts} +3 -3
- package/types/types/{style.d.ts → types/style.d.ts} +8 -0
- package/types/types/{toolbar.d.ts → types/toolbar.d.ts} +9 -2
- package/types/types/{traits.d.ts → types/traits.d.ts} +0 -0
- package/types/types/{types.d.ts → types/types.d.ts} +1 -1
- package/types/types/{ui.d.ts → types/ui.d.ts} +23 -4
- package/types/types/{uploader.d.ts → types/uploader.d.ts} +0 -0
- package/types/types/{view.d.ts → 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
- package/types/modules/file-browser/consts.d.ts +0 -8
|
@@ -0,0 +1,134 @@
|
|
|
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 { CommitMode, IJodit } from '../../../../../types';
|
|
8
|
+
import type { CommitStyle } from '../../commit-style';
|
|
9
|
+
import {
|
|
10
|
+
attr,
|
|
11
|
+
css,
|
|
12
|
+
dataBind,
|
|
13
|
+
kebabCase,
|
|
14
|
+
normalizeCssValue,
|
|
15
|
+
size
|
|
16
|
+
} from '../../../../helpers';
|
|
17
|
+
import { Dom } from '../../../../dom';
|
|
18
|
+
import { CHANGE, UNSET, UNWRAP } from '../../commit-style';
|
|
19
|
+
import { getContainer } from '../../../../global';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Toggles css and classname
|
|
23
|
+
*/
|
|
24
|
+
export function toggleCSS(
|
|
25
|
+
commitStyle: CommitStyle,
|
|
26
|
+
elm: HTMLElement,
|
|
27
|
+
jodit: IJodit,
|
|
28
|
+
mode: CommitMode,
|
|
29
|
+
dry: boolean = false
|
|
30
|
+
): CommitMode {
|
|
31
|
+
const { style, className } = commitStyle.options;
|
|
32
|
+
|
|
33
|
+
if (style && size(style) > 0) {
|
|
34
|
+
Object.keys(style).forEach((rule: string) => {
|
|
35
|
+
const inlineValue = elm.style.getPropertyValue(kebabCase(rule));
|
|
36
|
+
|
|
37
|
+
if (inlineValue === '' && style[rule] == null) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (
|
|
42
|
+
getNativeCSSValue(jodit, elm, rule) ===
|
|
43
|
+
normalizeCssValue(rule, style[rule] as string)
|
|
44
|
+
) {
|
|
45
|
+
!dry && css(elm, rule, null);
|
|
46
|
+
mode = UNSET;
|
|
47
|
+
mode = removeExtraCSS(commitStyle, elm, mode);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
mode = CHANGE;
|
|
52
|
+
!dry && css(elm, rule, style[rule]);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (className) {
|
|
57
|
+
if (elm.classList.contains(className)) {
|
|
58
|
+
elm.classList.remove(className);
|
|
59
|
+
mode = UNSET;
|
|
60
|
+
} else {
|
|
61
|
+
elm.classList.add(className);
|
|
62
|
+
mode = CHANGE;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return mode;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* If the element has an empty style attribute, it removes the attribute,
|
|
71
|
+
* and if it is default, it removes the element itself
|
|
72
|
+
*/
|
|
73
|
+
function removeExtraCSS(
|
|
74
|
+
commitStyle: CommitStyle,
|
|
75
|
+
elm: HTMLElement,
|
|
76
|
+
mode: CommitMode
|
|
77
|
+
): CommitMode {
|
|
78
|
+
if (!attr(elm, 'style')) {
|
|
79
|
+
attr(elm, 'style', null);
|
|
80
|
+
|
|
81
|
+
if (elm.tagName.toLowerCase() === commitStyle.defaultTag) {
|
|
82
|
+
Dom.unwrap(elm);
|
|
83
|
+
mode = UNWRAP;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return mode;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Creates an iframe into which elements will be inserted to test their default styles in the browser
|
|
92
|
+
*/
|
|
93
|
+
function getShadowRoot(jodit: IJodit): HTMLElement {
|
|
94
|
+
if (dataBind(jodit, 'shadowRoot') !== undefined) {
|
|
95
|
+
return dataBind(jodit, 'shadowRoot');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const container = getContainer(jodit, function Utils() {});
|
|
99
|
+
|
|
100
|
+
const iframe = document.createElement('iframe');
|
|
101
|
+
css(iframe, {
|
|
102
|
+
width: 0,
|
|
103
|
+
height: 0,
|
|
104
|
+
position: 'absolute',
|
|
105
|
+
border: 0
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
iframe.src = 'about:blank';
|
|
109
|
+
container.appendChild(iframe);
|
|
110
|
+
|
|
111
|
+
const doc = iframe.contentWindow?.document;
|
|
112
|
+
|
|
113
|
+
const shadowRoot = !doc ? jodit.od.body : doc.body;
|
|
114
|
+
dataBind(jodit, 'shadowRoot', shadowRoot);
|
|
115
|
+
|
|
116
|
+
return shadowRoot;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* `strong -> fontWeight 700`
|
|
121
|
+
*/
|
|
122
|
+
function getNativeCSSValue(
|
|
123
|
+
jodit: IJodit,
|
|
124
|
+
elm: HTMLElement,
|
|
125
|
+
key: string
|
|
126
|
+
): ReturnType<typeof css> {
|
|
127
|
+
const newElm = jodit.create.element(elm.tagName.toLowerCase());
|
|
128
|
+
newElm.style.cssText = elm.style.cssText;
|
|
129
|
+
const root = getShadowRoot(jodit);
|
|
130
|
+
root.appendChild(newElm);
|
|
131
|
+
const result = css(newElm, key);
|
|
132
|
+
Dom.safeRemove(newElm);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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, CommitMode } from '../../../../../types';
|
|
8
|
+
import type { CommitStyle } from '../../commit-style';
|
|
9
|
+
import { Dom } from '../../../../dom';
|
|
10
|
+
import { extractSelectedPart } from '../extract';
|
|
11
|
+
import { CHANGE, INITIAL, REPLACE } from '../../commit-style';
|
|
12
|
+
import { toggleCSS } from './toggle-css';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Replaces `ul->ol` or `ol->ul`, apply styles to the list, or remove a list item from it
|
|
16
|
+
*/
|
|
17
|
+
export function toggleOrderedList(
|
|
18
|
+
style: CommitStyle,
|
|
19
|
+
li: HTMLElement,
|
|
20
|
+
jodit: IJodit,
|
|
21
|
+
mode: CommitMode
|
|
22
|
+
): CommitMode {
|
|
23
|
+
if (!li) {
|
|
24
|
+
return mode;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const list = li.parentElement;
|
|
28
|
+
|
|
29
|
+
if (!list) {
|
|
30
|
+
return mode;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ul => ol, ol => ul
|
|
34
|
+
if (list.tagName.toLowerCase() !== style.element) {
|
|
35
|
+
const newList = Dom.replace(list, style.element, jodit.createInside);
|
|
36
|
+
toggleCSS(style, newList, jodit, mode);
|
|
37
|
+
return REPLACE;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (toggleCSS(style, li.parentElement, jodit, INITIAL, true) === CHANGE) {
|
|
41
|
+
return toggleCSS(style, li.parentElement, jodit, mode);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
extractSelectedPart(list, li, jodit);
|
|
45
|
+
Dom.unwrap(li.parentElement);
|
|
46
|
+
Dom.replace(li, jodit.o.enter, jodit.createInside);
|
|
47
|
+
|
|
48
|
+
return mode;
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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 { CommitStyle } from '../commit-style';
|
|
8
|
+
import { Dom } from '../../../dom';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Add or remove styles to element
|
|
12
|
+
* @param elm - The element to switch styles
|
|
13
|
+
*/
|
|
14
|
+
export function toggleCommitStyles(
|
|
15
|
+
commitStyle: CommitStyle,
|
|
16
|
+
elm: HTMLElement
|
|
17
|
+
): boolean {
|
|
18
|
+
if (
|
|
19
|
+
commitStyle.elementIsBlock ||
|
|
20
|
+
(Dom.isTag(elm, commitStyle.element) && !commitStyle.elementIsDefault)
|
|
21
|
+
) {
|
|
22
|
+
Dom.unwrap(elm);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
import type { CommitStyle } from '../commit-style';
|
|
9
|
+
import { Dom } from '../../../dom';
|
|
10
|
+
import { wrapUnwrappedText } from './wrap-unwrapped-text';
|
|
11
|
+
import { attr } from '../../../helpers';
|
|
12
|
+
import { wrapOrderedList } from './wrap-ordered-list';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Replaces the parent tag with the applicable one, or wraps the text and also replaces the tag
|
|
16
|
+
*/
|
|
17
|
+
export function wrapAndCommitStyle(
|
|
18
|
+
commitStyle: CommitStyle,
|
|
19
|
+
font: HTMLElement,
|
|
20
|
+
jodit: IJodit
|
|
21
|
+
): HTMLElement {
|
|
22
|
+
const wrapper = findOrCreateWrapper(commitStyle, font, jodit);
|
|
23
|
+
|
|
24
|
+
return commitStyle.elementIsList
|
|
25
|
+
? wrapOrderedList(commitStyle, wrapper, jodit)
|
|
26
|
+
: Dom.replace(wrapper, commitStyle.element, jodit.createInside, true);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* If we apply a block element, then it finds the closest block parent (exclude table cell etc.),
|
|
31
|
+
* otherwise it wraps free text in an element.
|
|
32
|
+
*/
|
|
33
|
+
function findOrCreateWrapper(
|
|
34
|
+
commitStyle: CommitStyle,
|
|
35
|
+
font: HTMLElement,
|
|
36
|
+
jodit: IJodit
|
|
37
|
+
): HTMLElement {
|
|
38
|
+
if (commitStyle.elementIsBlock) {
|
|
39
|
+
const box = Dom.up(
|
|
40
|
+
font,
|
|
41
|
+
node =>
|
|
42
|
+
Dom.isBlock(node) &&
|
|
43
|
+
!Dom.isTag(node, [
|
|
44
|
+
'td',
|
|
45
|
+
'th',
|
|
46
|
+
'tr',
|
|
47
|
+
'tbody',
|
|
48
|
+
'table',
|
|
49
|
+
'li',
|
|
50
|
+
'ul',
|
|
51
|
+
'ol'
|
|
52
|
+
]),
|
|
53
|
+
jodit.editor
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (box) {
|
|
57
|
+
return box;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (commitStyle.elementIsBlock) {
|
|
62
|
+
return wrapUnwrappedText(commitStyle, font, jodit, jodit.s.createRange);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
attr(font, 'size', null);
|
|
66
|
+
|
|
67
|
+
return font;
|
|
68
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
import { Dom } from '../../../dom';
|
|
9
|
+
import type { CommitStyle } from '../commit-style';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Replaces non-leaf items with leaf items and either creates a new list or
|
|
13
|
+
* adds a new item to the nearest old list
|
|
14
|
+
*/
|
|
15
|
+
export function wrapOrderedList(
|
|
16
|
+
commitStyle: CommitStyle,
|
|
17
|
+
wrapper: HTMLElement,
|
|
18
|
+
jodit: IJodit
|
|
19
|
+
): HTMLElement {
|
|
20
|
+
const newWrapper = Dom.replace(wrapper, 'li', jodit.createInside);
|
|
21
|
+
|
|
22
|
+
let list =
|
|
23
|
+
newWrapper.previousElementSibling || newWrapper.nextElementSibling;
|
|
24
|
+
|
|
25
|
+
if (!Dom.isTag(list, ['ul', 'ol'])) {
|
|
26
|
+
list = jodit.createInside.element(commitStyle.element);
|
|
27
|
+
Dom.before(newWrapper, list);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (newWrapper.previousElementSibling === list) {
|
|
31
|
+
Dom.append(list, newWrapper);
|
|
32
|
+
} else {
|
|
33
|
+
Dom.prepend(list, newWrapper);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return <HTMLElement>list;
|
|
37
|
+
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import type { IJodit, Nullable } from '../../../../types';
|
|
8
8
|
import type { CommitStyle } from '../commit-style';
|
|
9
9
|
import { Dom } from '../../../dom';
|
|
10
|
-
import { postProcessListElement } from './post-process-list-element';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Wrap text or inline elements inside Block element
|
|
@@ -58,13 +57,11 @@ export function wrapUnwrappedText(
|
|
|
58
57
|
range.setEndAfter(end);
|
|
59
58
|
const fragment = range.extractContents();
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
const wrapper = ci.element(style.element);
|
|
62
61
|
wrapper.appendChild(fragment);
|
|
63
62
|
range.insertNode(wrapper);
|
|
64
63
|
|
|
65
64
|
if (style.elementIsBlock) {
|
|
66
|
-
wrapper = postProcessListElement(style, wrapper, ci);
|
|
67
|
-
|
|
68
65
|
if (
|
|
69
66
|
Dom.isEmpty(wrapper) &&
|
|
70
67
|
!Dom.isTag(wrapper.firstElementChild, 'br')
|
|
@@ -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
|
}
|
|
@@ -43,7 +43,7 @@ export const canUsePersistentStorage: BooleanFunction = (() => {
|
|
|
43
43
|
* Persistent storage in localStorage
|
|
44
44
|
*/
|
|
45
45
|
export class LocalStorageProvider<T = StorageValueType> implements IStorage<T> {
|
|
46
|
-
set(key: string, value: T):
|
|
46
|
+
set(key: string, value: T): IStorage<T> {
|
|
47
47
|
try {
|
|
48
48
|
const buffer = localStorage.getItem(this.rootKey);
|
|
49
49
|
|
|
@@ -53,12 +53,16 @@ export class LocalStorageProvider<T = StorageValueType> implements IStorage<T> {
|
|
|
53
53
|
|
|
54
54
|
localStorage.setItem(this.rootKey, JSON.stringify(json));
|
|
55
55
|
} catch {}
|
|
56
|
+
|
|
57
|
+
return this;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
delete(key: string):
|
|
60
|
+
delete(key: string): IStorage<T> {
|
|
59
61
|
try {
|
|
60
62
|
localStorage.removeItem(this.rootKey);
|
|
61
63
|
} catch {}
|
|
64
|
+
|
|
65
|
+
return this;
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
get<R = T>(key: string): R | void {
|
|
@@ -77,9 +81,11 @@ export class LocalStorageProvider<T = StorageValueType> implements IStorage<T> {
|
|
|
77
81
|
|
|
78
82
|
constructor(readonly rootKey: string) {}
|
|
79
83
|
|
|
80
|
-
clear():
|
|
84
|
+
clear(): IStorage<T> {
|
|
81
85
|
try {
|
|
82
86
|
localStorage.removeItem(this.rootKey);
|
|
83
87
|
} catch {}
|
|
88
|
+
|
|
89
|
+
return this;
|
|
84
90
|
}
|
|
85
91
|
}
|