jodit 3.15.2 → 3.16.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 +301 -299
- package/CHANGELOG.MD +88 -7
- package/CONTRIBUTING.md +97 -0
- package/README.md +7 -7
- package/build/jodit.css +38 -32
- package/build/jodit.es2018.css +37 -31
- package/build/jodit.es2018.en.css +37 -31
- package/build/jodit.es2018.en.js +1981 -1393
- package/build/jodit.es2018.en.min.css +1 -1
- package/build/jodit.es2018.en.min.js +1 -1
- package/build/jodit.es2018.js +2053 -1447
- package/build/jodit.es2018.min.css +1 -1
- package/build/jodit.es2018.min.js +1 -1
- package/build/jodit.js +3475 -2625
- package/build/jodit.min.css +2 -2
- package/build/jodit.min.js +1 -1
- package/build/vdom.css +1 -1
- package/build/vdom.js +32 -20
- package/package.json +13 -13
- package/src/README.md +1 -1
- package/src/config.ts +69 -36
- package/src/core/async/async.ts +46 -24
- package/src/core/constants.ts +1 -0
- package/src/core/decorators/README.md +35 -0
- package/src/core/decorators/cache/cache.ts +1 -1
- package/src/core/decorators/debounce/debounce.ts +20 -9
- package/src/core/decorators/idle/README.md +14 -0
- package/src/core/decorators/idle/idle.ts +1 -1
- package/src/core/decorators/watch/watch.ts +8 -7
- package/src/core/dom/README.md +42 -0
- package/src/core/dom/dom.ts +37 -23
- package/src/core/dom/index.ts +1 -0
- package/src/core/dom/lazy-walker.ts +133 -0
- package/src/core/event-emitter/event-emitter.ts +8 -8
- package/src/core/event-emitter/eventify.ts +73 -0
- package/src/core/event-emitter/index.ts +1 -0
- package/src/core/helpers/html/apply-styles.ts +1 -1
- package/src/core/helpers/html/strip-tags.ts +3 -2
- package/src/core/helpers/string/fuzzy-search-index.ts +58 -0
- package/src/core/helpers/string/i18n.ts +1 -1
- package/src/core/helpers/string/index.ts +3 -2
- package/src/core/helpers/utils/append-script.ts +1 -1
- package/src/core/helpers/utils/css.ts +1 -1
- package/src/core/helpers/utils/selector.ts +1 -1
- package/src/core/helpers/utils/utils.ts +3 -3
- package/src/core/plugin/plugin-system.ts +14 -8
- package/src/core/request/ajax.ts +3 -3
- package/src/core/selection/select.ts +10 -10
- package/src/core/selection/style/api/toggle/toggle-css.ts +5 -2
- package/src/core/selection/style/api/wrap-unwrapped-text.ts +1 -1
- package/src/core/selection/style/apply-style.ts +4 -4
- package/src/core/storage/engines/local-storage-provider.ts +20 -19
- package/src/core/ui/button/button/button.ts +5 -5
- package/src/core/ui/element.ts +2 -2
- package/src/core/ui/form/inputs/input/input.ts +1 -1
- package/src/core/ui/form/inputs/select/select.ts +1 -1
- package/src/core/ui/group/list.ts +2 -2
- package/src/core/vdom/render/index.ts +12 -8
- package/src/core/vdom/v-dom-jodit.ts +1 -1
- package/src/core/view/view.ts +1 -1
- package/src/index.ts +3 -3
- package/src/jodit.ts +72 -55
- package/src/langs/README.md +1 -1
- package/src/langs/ar.js +2 -1
- package/src/langs/cs_cz.js +2 -1
- package/src/langs/de.js +2 -1
- package/src/langs/es.js +2 -1
- package/src/langs/fa.js +2 -1
- package/src/langs/fr.js +2 -1
- package/src/langs/he.js +2 -1
- package/src/langs/hu.js +2 -1
- package/src/langs/id.js +2 -1
- package/src/langs/index.ts +1 -1
- package/src/langs/it.js +2 -1
- package/src/langs/ja.js +2 -1
- package/src/langs/ko.js +2 -1
- package/src/langs/nl.js +2 -1
- package/src/langs/pl.js +2 -1
- package/src/langs/pt_br.js +2 -1
- package/src/langs/ru.js +2 -1
- package/src/langs/tr.js +2 -1
- package/src/langs/zh_cn.js +2 -1
- package/src/langs/zh_tw.js +2 -1
- package/src/modules/dialog/dialog.ts +6 -6
- package/src/modules/dialog/prompt.ts +1 -1
- package/src/modules/file-browser/README.md +2 -2
- package/src/modules/file-browser/builders/context-menu.ts +12 -13
- package/src/modules/file-browser/fetch/load-tree.ts +1 -1
- package/src/modules/file-browser/file-browser.ts +10 -7
- package/src/modules/history/README.md +5 -0
- package/src/modules/{observer → history}/command.ts +5 -5
- package/src/modules/{observer/observer.ts → history/history.ts} +97 -55
- package/src/modules/{observer → history}/snapshot.ts +3 -4
- package/src/modules/{observer → history}/stack.ts +4 -4
- package/src/modules/image-editor/image-editor.ts +8 -8
- package/src/modules/image-editor/templates/form.ts +2 -2
- package/src/modules/index.ts +3 -3
- package/src/modules/status-bar/status-bar.ts +4 -0
- package/src/modules/table/table.ts +2 -2
- package/src/modules/toolbar/button/button.ts +2 -2
- package/src/modules/toolbar/collection/collection.ts +1 -1
- package/src/modules/uploader/helpers/process-old-browser-drag.ts +1 -1
- package/src/modules/uploader/helpers/send-files.ts +1 -1
- package/src/modules/uploader/helpers/send.ts +1 -1
- package/src/modules/uploader/uploader.ts +3 -3
- package/src/modules/widget/color-picker/color-picker.ts +2 -3
- package/src/modules/widget/tabs/tabs.ts +17 -12
- package/src/plugins/add-new-line/add-new-line.ts +8 -8
- package/src/plugins/class-span/class-span.ts +1 -1
- package/src/plugins/clipboard/copy-format.ts +1 -1
- package/src/plugins/clipboard/drag-and-drop-element.ts +4 -2
- package/src/plugins/clipboard/paste/config.ts +19 -3
- package/src/plugins/clipboard/paste/helpers.ts +17 -50
- package/src/plugins/clipboard/paste/interface.ts +6 -0
- package/src/plugins/clipboard/paste/paste.ts +22 -8
- package/src/plugins/clipboard/paste-from-word/config.ts +17 -0
- package/src/plugins/clipboard/paste-from-word/paste-from-word.ts +15 -6
- package/src/plugins/clipboard/paste-storage/paste-storage.ts +6 -6
- package/src/plugins/color/color.ts +2 -2
- package/src/plugins/error-messages/error-messages.ts +2 -2
- package/src/plugins/fix/clean-html/README.md +26 -0
- package/src/plugins/fix/{clean-html.ts → clean-html/clean-html.ts} +59 -142
- package/src/plugins/fix/clean-html/config.ts +106 -0
- package/src/plugins/fix/index.ts +12 -0
- package/src/plugins/fix/wrap-nodes/README.md +27 -0
- package/src/plugins/fix/wrap-nodes/config.ts +24 -0
- package/src/plugins/fix/{wrap-text-nodes.ts → wrap-nodes/wrap-nodes.ts} +9 -4
- package/src/plugins/focus/focus.ts +1 -1
- package/src/plugins/format-block/format-block.ts +1 -1
- package/src/plugins/fullsize/fullsize.ts +4 -4
- package/src/plugins/iframe/iframe.ts +3 -3
- package/src/plugins/image/image-properties/image-properties.ts +12 -13
- package/src/plugins/indent/indent.ts +1 -1
- package/src/plugins/index.ts +2 -2
- package/src/plugins/inline-popup/config/items/a.ts +2 -2
- package/src/plugins/inline-popup/config/items/cells.ts +11 -11
- package/src/plugins/inline-popup/config/items/iframe.ts +1 -1
- package/src/plugins/inline-popup/config/items/img.ts +7 -7
- package/src/plugins/inline-popup/inline-popup.ts +5 -5
- package/src/plugins/keyboard/backspace/backspace.ts +1 -1
- package/src/plugins/keyboard/backspace/cases/check-join-neighbors.ts +1 -1
- package/src/plugins/keyboard/helpers.ts +1 -1
- package/src/plugins/keyboard/hotkeys.ts +1 -1
- package/src/plugins/limit/limit.ts +3 -3
- package/src/plugins/line-height/line-height.ts +1 -1
- package/src/plugins/link/link.ts +8 -8
- package/src/plugins/link/template.ts +2 -2
- package/src/plugins/media/file.ts +1 -1
- package/src/plugins/media/media.ts +1 -1
- package/src/plugins/media/video/config.ts +1 -1
- package/src/plugins/mobile/config.ts +1 -1
- package/src/plugins/mobile/mobile.ts +1 -1
- package/src/plugins/ordered-list/config.ts +61 -0
- package/src/plugins/ordered-list/ordered-list.ts +3 -153
- package/src/plugins/placeholder/placeholder.ts +3 -3
- package/src/plugins/print/helpers.ts +14 -7
- package/src/plugins/print/index.ts +1 -1
- package/src/plugins/print/{preview.less → preview/preview.less} +1 -1
- package/src/plugins/print/{preview.ts → preview/preview.ts} +9 -8
- package/src/plugins/print/print.ts +19 -10
- package/src/plugins/redo-undo/redo-undo.ts +3 -3
- package/src/plugins/resizer/resizer.ts +11 -11
- package/src/plugins/search/README.md +38 -0
- package/src/plugins/search/config.ts +82 -0
- package/src/plugins/search/helpers/index.ts +12 -0
- package/src/plugins/search/helpers/sentence-finder.ts +103 -0
- package/src/plugins/search/helpers/wrap-ranges-texts-in-tmp-span.ts +120 -0
- package/src/plugins/search/search.ts +269 -615
- package/src/plugins/search/ui/search.less +159 -0
- package/src/plugins/search/ui/search.ts +256 -0
- package/src/plugins/select/select.ts +1 -1
- package/src/plugins/size/config.ts +8 -8
- package/src/plugins/size/resize-handler.ts +3 -3
- package/src/plugins/size/size.ts +4 -4
- package/src/plugins/source/editor/engines/ace.ts +9 -9
- package/src/plugins/source/editor/engines/area.ts +3 -3
- package/src/plugins/source/source.ts +6 -6
- package/src/plugins/spellcheck/README.md +1 -0
- package/src/plugins/spellcheck/config.ts +34 -0
- package/src/plugins/spellcheck/spellcheck.svg +4 -0
- package/src/plugins/spellcheck/spellcheck.ts +48 -0
- package/src/plugins/sticky/sticky.ts +3 -3
- package/src/plugins/table/resize-cells.ts +11 -11
- package/src/plugins/table/select-cells.ts +2 -2
- package/src/plugins/tooltip/tooltip.ts +1 -1
- package/src/plugins/xpath/xpath.ts +8 -8
- package/src/polyfills.ts +5 -4
- package/src/styles/icons/README.md +2 -2
- package/src/types/async.d.ts +12 -2
- package/src/types/core.ts +1 -1
- package/src/types/events.d.ts +6 -2
- package/src/types/file-browser.d.ts +1 -2
- package/{types/types/observer.d.ts → src/types/history.d.ts} +11 -7
- package/src/types/index.d.ts +1 -1
- package/src/types/jodit.d.ts +12 -4
- package/src/types/toolbar.d.ts +5 -5
- package/src/types/types.d.ts +11 -4
- package/types/config.d.ts +68 -35
- package/types/core/async/async.d.ts +11 -4
- package/types/core/constants.d.ts +1 -0
- package/types/core/dom/dom.d.ts +3 -5
- package/types/core/dom/index.d.ts +1 -0
- package/types/core/dom/lazy-walker.d.ts +37 -0
- package/types/core/event-emitter/eventify.d.ts +39 -0
- package/types/core/event-emitter/index.d.ts +1 -0
- package/types/core/helpers/string/fuzzy-search-index.d.ts +10 -0
- package/types/core/helpers/string/i18n.d.ts +1 -1
- package/types/core/helpers/string/index.d.ts +3 -2
- package/types/core/helpers/utils/utils.d.ts +1 -1
- package/types/core/selection/select.d.ts +1 -1
- package/types/core/ui/button/button/button.d.ts +4 -4
- package/types/core/view/view.d.ts +1 -1
- package/types/jodit.d.ts +19 -6
- package/types/modules/{observer → history}/command.d.ts +4 -4
- package/types/modules/{observer/observer.d.ts → history/history.d.ts} +17 -9
- package/types/modules/{observer → history}/snapshot.d.ts +1 -1
- package/types/modules/{observer → history}/stack.d.ts +3 -3
- package/types/modules/image-editor/image-editor.d.ts +1 -1
- package/types/modules/index.d.ts +3 -3
- package/types/modules/toolbar/button/button.d.ts +2 -5
- package/types/modules/widget/tabs/tabs.d.ts +1 -1
- package/types/plugins/class-span/class-span.d.ts +1 -1
- package/types/plugins/clipboard/paste/config.d.ts +8 -0
- package/types/plugins/clipboard/paste/helpers.d.ts +2 -2
- package/types/plugins/clipboard/paste/interface.d.ts +5 -0
- package/types/plugins/clipboard/paste-from-word/config.d.ts +5 -0
- package/types/plugins/clipboard/paste-from-word/paste-from-word.d.ts +3 -2
- package/types/plugins/fix/clean-html/clean-html.d.ts +70 -0
- package/types/plugins/fix/{clean-html.d.ts → clean-html/config.d.ts} +2 -57
- package/types/plugins/fix/index.d.ts +10 -0
- package/types/plugins/fix/wrap-nodes/config.d.ts +16 -0
- package/types/plugins/fix/{wrap-text-nodes.d.ts → wrap-nodes/wrap-nodes.d.ts} +5 -2
- package/types/plugins/fullsize/fullsize.d.ts +2 -2
- package/types/plugins/index.d.ts +2 -2
- package/types/plugins/ordered-list/config.d.ts +6 -0
- package/types/plugins/ordered-list/ordered-list.d.ts +1 -1
- package/types/plugins/print/helpers.d.ts +2 -2
- package/types/plugins/print/index.d.ts +1 -1
- package/types/plugins/print/{preview.d.ts → preview/preview.d.ts} +1 -1
- package/types/plugins/search/config.d.ts +36 -0
- package/types/plugins/search/helpers/index.d.ts +10 -0
- package/types/plugins/search/helpers/sentence-finder.d.ts +21 -0
- package/types/plugins/search/helpers/wrap-ranges-texts-in-tmp-span.d.ts +14 -0
- package/types/plugins/search/search.d.ts +25 -39
- package/types/plugins/search/ui/search.d.ts +37 -0
- package/types/plugins/spellcheck/config.d.ts +15 -0
- package/types/plugins/spellcheck/spellcheck.d.ts +19 -0
- package/types/plugins/sticky/sticky.d.ts +2 -2
- package/types/types/async.d.ts +12 -2
- package/types/types/core.d.ts +1 -1
- package/types/types/core.ts +1 -1
- package/types/types/events.d.ts +6 -2
- package/types/types/file-browser.d.ts +1 -2
- package/{src/types/observer.d.ts → types/types/history.d.ts} +11 -7
- package/types/types/index.d.ts +1 -1
- package/types/types/jodit.d.ts +12 -4
- package/types/types/toolbar.d.ts +5 -5
- package/types/types/types.d.ts +11 -4
- package/src/modules/observer/README.md +0 -0
- package/src/plugins/search/search.less +0 -152
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* [[include:src/plugins/fix/clean-html/README.md]]
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
* @module plugins/fix/clean-html
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
import type {
|
|
@@ -15,7 +17,6 @@ import type {
|
|
|
15
17
|
Nullable,
|
|
16
18
|
IPlugin
|
|
17
19
|
} from 'jodit/types';
|
|
18
|
-
import { Config } from 'jodit/config';
|
|
19
20
|
import {
|
|
20
21
|
INVISIBLE_SPACE_REG_EXP as INV_REG,
|
|
21
22
|
IS_INLINE,
|
|
@@ -24,102 +25,11 @@ import {
|
|
|
24
25
|
import { Dom } from 'jodit/modules';
|
|
25
26
|
import { attr, isString, keys, safeHTML, trim } from 'jodit/core/helpers';
|
|
26
27
|
import { Plugin } from 'jodit/core/plugin';
|
|
27
|
-
import { watch, autobind, debounce } from 'jodit/core/decorators';
|
|
28
|
+
import { watch, autobind, debounce, hook } from 'jodit/core/decorators';
|
|
28
29
|
import { findNotEmptySibling } from 'jodit/plugins/keyboard/helpers';
|
|
30
|
+
import { LazyWalker } from 'jodit/core/dom/lazy-walker';
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
interface Config {
|
|
32
|
-
cleanHTML: {
|
|
33
|
-
timeout: number;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Replace   to plain space
|
|
37
|
-
*/
|
|
38
|
-
replaceNBSP: boolean;
|
|
39
|
-
fillEmptyParagraph: boolean;
|
|
40
|
-
removeEmptyElements: boolean;
|
|
41
|
-
replaceOldTags: IDictionary<HTMLTagNames> | false;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Remove onError attributes
|
|
45
|
-
*/
|
|
46
|
-
removeOnError: boolean;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Safe href="javascript:" links
|
|
50
|
-
*/
|
|
51
|
-
safeJavaScriptLink: boolean;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* The allowTags option defines which elements will remain in the
|
|
55
|
-
* edited text when the editor saves. You can use this limit the returned HTML.
|
|
56
|
-
* @example
|
|
57
|
-
* ```javascript
|
|
58
|
-
* var jodit = new Jodit('#editor', {
|
|
59
|
-
* cleanHTML: {
|
|
60
|
-
* cleanOnPaste: false
|
|
61
|
-
* }
|
|
62
|
-
* });
|
|
63
|
-
* ```
|
|
64
|
-
* @example
|
|
65
|
-
* ```javascript
|
|
66
|
-
* var editor = Jodit('#editor', {
|
|
67
|
-
* cleanHTML: {
|
|
68
|
-
* allowTags: 'p,a[href],table,tr,td, img[src=1.png]' // allow only <p>,<a>,<table>,<tr>,<td>,<img> tags and
|
|
69
|
-
* for <a> allow only `href` attribute and <img> allow only `src` attribute == '1.png'
|
|
70
|
-
* }
|
|
71
|
-
* });
|
|
72
|
-
* editor.value = 'Sorry! <strong>Goodby</strong>\
|
|
73
|
-
* <span>mr.</span> <a style="color:red" href="http://xdsoft.net">Freeman</a>';
|
|
74
|
-
* console.log(editor.value); //Sorry! <a href="http://xdsoft.net">Freeman</a>
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```javascript
|
|
79
|
-
* var editor = Jodit('#editor', {
|
|
80
|
-
* cleanHTML: {
|
|
81
|
-
* allowTags: {
|
|
82
|
-
* p: true,
|
|
83
|
-
* a: {
|
|
84
|
-
* href: true
|
|
85
|
-
* },
|
|
86
|
-
* table: true,
|
|
87
|
-
* tr: true,
|
|
88
|
-
* td: true,
|
|
89
|
-
* img: {
|
|
90
|
-
* src: '1.png'
|
|
91
|
-
* }
|
|
92
|
-
* }
|
|
93
|
-
* }
|
|
94
|
-
* });
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
allowTags: false | string | IDictionary<string>;
|
|
98
|
-
denyTags: false | string | IDictionary<string>;
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
Config.prototype.cleanHTML = {
|
|
104
|
-
timeout: 300,
|
|
105
|
-
removeEmptyElements: true,
|
|
106
|
-
fillEmptyParagraph: true,
|
|
107
|
-
replaceNBSP: true,
|
|
108
|
-
replaceOldTags: {
|
|
109
|
-
i: 'em',
|
|
110
|
-
b: 'strong'
|
|
111
|
-
},
|
|
112
|
-
allowTags: false,
|
|
113
|
-
denyTags: false,
|
|
114
|
-
|
|
115
|
-
removeOnError: true,
|
|
116
|
-
safeJavaScriptLink: true
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
Config.prototype.controls.eraser = {
|
|
120
|
-
command: 'removeFormat',
|
|
121
|
-
tooltip: 'Clear Formatting'
|
|
122
|
-
};
|
|
32
|
+
import './config';
|
|
123
33
|
|
|
124
34
|
/**
|
|
125
35
|
* Clean HTML after removeFormat and insertHorizontalRule command
|
|
@@ -203,46 +113,42 @@ export class cleanHtml extends Plugin {
|
|
|
203
113
|
}
|
|
204
114
|
}
|
|
205
115
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (editor.editor.firstChild) {
|
|
209
|
-
node = editor.editor.firstChild as Element;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const remove: Node[] = [];
|
|
213
|
-
const work = this.visitNode(node, current, remove);
|
|
214
|
-
|
|
215
|
-
remove.forEach(Dom.safeRemove);
|
|
216
|
-
|
|
217
|
-
if (remove.length || work) {
|
|
218
|
-
editor.events && editor.e.fire('synchro');
|
|
219
|
-
}
|
|
116
|
+
this.walker.setWork(editor.editor);
|
|
117
|
+
this.currentSelectionNode = current;
|
|
220
118
|
}
|
|
221
119
|
|
|
222
|
-
private
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
120
|
+
private currentSelectionNode: Nullable<Node> = null;
|
|
121
|
+
|
|
122
|
+
private walker: LazyWalker = new LazyWalker(this.j.async, {
|
|
123
|
+
timeout: this.j.o.cleanHTML.timeout
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
@hook('ready')
|
|
127
|
+
protected startWalker(): void {
|
|
128
|
+
this.walker
|
|
129
|
+
.on('visit', this.visitNode)
|
|
130
|
+
.on('end', (affected: boolean): void => {
|
|
131
|
+
this.j.e.fire(
|
|
132
|
+
affected
|
|
133
|
+
? 'internalChange finishedCleanHTMLWorker'
|
|
134
|
+
: 'finishedCleanHTMLWorker'
|
|
135
|
+
);
|
|
136
|
+
});
|
|
228
137
|
}
|
|
229
138
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
remove: Node[]
|
|
234
|
-
): boolean => {
|
|
235
|
-
let work = false;
|
|
139
|
+
@autobind
|
|
140
|
+
private visitNode(nodeElm: Node): boolean {
|
|
141
|
+
let hasChanges = false;
|
|
236
142
|
|
|
237
|
-
|
|
238
|
-
|
|
143
|
+
const newNodeElm = this.replaceIfMatched(nodeElm);
|
|
144
|
+
if (nodeElm !== newNodeElm) {
|
|
145
|
+
nodeElm = newNodeElm;
|
|
146
|
+
hasChanges = true;
|
|
239
147
|
}
|
|
240
148
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
remove.push(nodeElm);
|
|
245
|
-
return this.visitNode(nodeElm.nextSibling, current, remove);
|
|
149
|
+
if (this.isRemovableNode(nodeElm, this.currentSelectionNode)) {
|
|
150
|
+
Dom.safeRemove(nodeElm);
|
|
151
|
+
return true;
|
|
246
152
|
}
|
|
247
153
|
|
|
248
154
|
if (
|
|
@@ -251,14 +157,17 @@ export class cleanHtml extends Plugin {
|
|
|
251
157
|
Dom.isEmpty(nodeElm, /^(img|svg|canvas|input|textarea|form|br)$/)
|
|
252
158
|
) {
|
|
253
159
|
const br = this.j.createInside.element('br');
|
|
254
|
-
|
|
255
160
|
nodeElm.appendChild(br);
|
|
256
|
-
|
|
161
|
+
hasChanges = true;
|
|
257
162
|
}
|
|
258
163
|
|
|
259
164
|
const allow = this.allowTagsHash;
|
|
260
165
|
|
|
261
|
-
if (
|
|
166
|
+
if (
|
|
167
|
+
allow &&
|
|
168
|
+
Dom.isElement(nodeElm) &&
|
|
169
|
+
allow[nodeElm.nodeName] !== true
|
|
170
|
+
) {
|
|
262
171
|
const attrs: NamedNodeMap = (nodeElm as Element).attributes;
|
|
263
172
|
|
|
264
173
|
if (attrs && attrs.length) {
|
|
@@ -273,7 +182,7 @@ export class cleanHtml extends Plugin {
|
|
|
273
182
|
}
|
|
274
183
|
|
|
275
184
|
if (removeAttrs.length) {
|
|
276
|
-
|
|
185
|
+
hasChanges = true;
|
|
277
186
|
}
|
|
278
187
|
|
|
279
188
|
removeAttrs.forEach(attr => {
|
|
@@ -282,26 +191,32 @@ export class cleanHtml extends Plugin {
|
|
|
282
191
|
}
|
|
283
192
|
}
|
|
284
193
|
|
|
285
|
-
|
|
286
|
-
|
|
194
|
+
return hasChanges;
|
|
195
|
+
}
|
|
287
196
|
|
|
288
|
-
|
|
289
|
-
|
|
197
|
+
private allowEdit(): boolean {
|
|
198
|
+
return !(
|
|
199
|
+
this.j.isInDestruct ||
|
|
200
|
+
!this.j.isEditorMode() ||
|
|
201
|
+
this.j.getReadOnly()
|
|
202
|
+
);
|
|
203
|
+
}
|
|
290
204
|
|
|
291
205
|
private static getHash(
|
|
292
206
|
tags: false | string | IDictionary<string>
|
|
293
207
|
): IDictionary | false {
|
|
294
208
|
const attributesReg = /([^[]*)\[([^\]]+)]/;
|
|
295
|
-
const
|
|
209
|
+
const separator = /[\s]*,[\s]*/,
|
|
296
210
|
attrReg = /^(.*)[\s]*=[\s]*(.*)$/;
|
|
211
|
+
|
|
297
212
|
const tagsHash: IDictionary = {};
|
|
298
213
|
|
|
299
214
|
if (isString(tags)) {
|
|
300
|
-
tags.split(
|
|
215
|
+
tags.split(separator).map((elm: string) => {
|
|
301
216
|
elm = trim(elm);
|
|
302
217
|
const attr: RegExpExecArray | null = attributesReg.exec(elm),
|
|
303
218
|
allowAttributes: IDictionary<string | boolean> = {},
|
|
304
|
-
attributeMap = (attrName: string) => {
|
|
219
|
+
attributeMap = (attrName: string): void => {
|
|
305
220
|
attrName = trim(attrName);
|
|
306
221
|
|
|
307
222
|
const val: string[] | null = attrReg.exec(attrName);
|
|
@@ -314,7 +229,8 @@ export class cleanHtml extends Plugin {
|
|
|
314
229
|
};
|
|
315
230
|
|
|
316
231
|
if (attr) {
|
|
317
|
-
const attr2: string[] = attr[2].split(
|
|
232
|
+
const attr2: string[] = attr[2].split(separator);
|
|
233
|
+
|
|
318
234
|
if (attr[1]) {
|
|
319
235
|
attr2.forEach(attributeMap);
|
|
320
236
|
tagsHash[attr[1].toUpperCase()] = allowAttributes;
|
|
@@ -349,7 +265,7 @@ export class cleanHtml extends Plugin {
|
|
|
349
265
|
/**
|
|
350
266
|
* Remove invisible chars if node has another chars
|
|
351
267
|
*/
|
|
352
|
-
private onKeyUpCleanUp = () => {
|
|
268
|
+
private onKeyUpCleanUp = (): void => {
|
|
353
269
|
const editor = this.j;
|
|
354
270
|
|
|
355
271
|
if (!this.allowEdit()) {
|
|
@@ -589,5 +505,6 @@ export class cleanHtml extends Plugin {
|
|
|
589
505
|
/** @override */
|
|
590
506
|
protected override beforeDestruct(): void {
|
|
591
507
|
this.j.e.off('.cleanHtml');
|
|
508
|
+
this.walker.destruct();
|
|
592
509
|
}
|
|
593
510
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
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-2022 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @module plugins/fix/clean-html
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { HTMLTagNames, IDictionary } from 'jodit/types';
|
|
12
|
+
import { Config } from 'jodit/config';
|
|
13
|
+
|
|
14
|
+
declare module 'jodit/config' {
|
|
15
|
+
interface Config {
|
|
16
|
+
cleanHTML: {
|
|
17
|
+
timeout: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Replace &nbsp; to plain space
|
|
21
|
+
*/
|
|
22
|
+
replaceNBSP: boolean;
|
|
23
|
+
fillEmptyParagraph: boolean;
|
|
24
|
+
removeEmptyElements: boolean;
|
|
25
|
+
replaceOldTags: IDictionary<HTMLTagNames> | false;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Remove onError attributes
|
|
29
|
+
*/
|
|
30
|
+
removeOnError: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Safe href="javascript:" links
|
|
34
|
+
*/
|
|
35
|
+
safeJavaScriptLink: boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The allowTags option defines which elements will remain in the
|
|
39
|
+
* edited text when the editor saves. You can use this limit the returned HTML.
|
|
40
|
+
* @example
|
|
41
|
+
* ```javascript
|
|
42
|
+
* var jodit = new Jodit('#editor', {
|
|
43
|
+
* cleanHTML: {
|
|
44
|
+
* cleanOnPaste: false
|
|
45
|
+
* }
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
* @example
|
|
49
|
+
* ```javascript
|
|
50
|
+
* var editor = Jodit('#editor', {
|
|
51
|
+
* cleanHTML: {
|
|
52
|
+
* allowTags: 'p,a[href],table,tr,td, img[src=1.png]' // allow only <p>,<a>,<table>,<tr>,<td>,<img> tags and
|
|
53
|
+
* for <a> allow only `href` attribute and <img> allow only `src` attribute == '1.png'
|
|
54
|
+
* }
|
|
55
|
+
* });
|
|
56
|
+
* editor.value = 'Sorry! <strong>Goodby</strong>\
|
|
57
|
+
* <span>mr.</span> <a style="color:red" href="http://xdsoft.net">Freeman</a>';
|
|
58
|
+
* console.log(editor.value); //Sorry! <a href="http://xdsoft.net">Freeman</a>
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```javascript
|
|
63
|
+
* var editor = Jodit('#editor', {
|
|
64
|
+
* cleanHTML: {
|
|
65
|
+
* allowTags: {
|
|
66
|
+
* p: true,
|
|
67
|
+
* a: {
|
|
68
|
+
* href: true
|
|
69
|
+
* },
|
|
70
|
+
* table: true,
|
|
71
|
+
* tr: true,
|
|
72
|
+
* td: true,
|
|
73
|
+
* img: {
|
|
74
|
+
* src: '1.png'
|
|
75
|
+
* }
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
allowTags: false | string | IDictionary<string>;
|
|
82
|
+
denyTags: false | string | IDictionary<string>;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Config.prototype.cleanHTML = {
|
|
88
|
+
timeout: 300,
|
|
89
|
+
removeEmptyElements: true,
|
|
90
|
+
fillEmptyParagraph: true,
|
|
91
|
+
replaceNBSP: true,
|
|
92
|
+
replaceOldTags: {
|
|
93
|
+
i: 'em',
|
|
94
|
+
b: 'strong'
|
|
95
|
+
},
|
|
96
|
+
allowTags: false,
|
|
97
|
+
denyTags: false,
|
|
98
|
+
|
|
99
|
+
removeOnError: true,
|
|
100
|
+
safeJavaScriptLink: true
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
Config.prototype.controls.eraser = {
|
|
104
|
+
command: 'removeFormat',
|
|
105
|
+
tooltip: 'Clear Formatting'
|
|
106
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
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-2022 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @module plugins/fix
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export * from './clean-html/clean-html';
|
|
12
|
+
export * from './wrap-nodes/wrap-nodes';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
A plugin that ensures that there are no elements in the document that are not surrounded by a block element.
|
|
2
|
+
|
|
3
|
+
For example, the plugin will result in HTML:
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
test <img src="./test.png" />
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Depending on the [[Config.enter]] setting to this view:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<p>test <img src="./test.png" /></p>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
You may encounter a situation where your custom tags will be treated as inline by the plugin.
|
|
16
|
+
And he will also surround them in a block element.
|
|
17
|
+
To prevent this from happening, you can explicitly set in the settings which tags to avoid.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
Jodit.make('#editor', {
|
|
21
|
+
wrapNodes: {
|
|
22
|
+
exclude: ['hr', 'style', 'my-component']
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Plugin settings are under the namespace [[Config.wrapNodes]]
|
|
@@ -0,0 +1,24 @@
|
|
|
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-2022 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @module plugins/fix/wrap-nodes
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { HTMLTagNames } from 'jodit/types';
|
|
12
|
+
import { Config } from 'jodit/config';
|
|
13
|
+
|
|
14
|
+
declare module 'jodit/config' {
|
|
15
|
+
interface Config {
|
|
16
|
+
wrapNodes: {
|
|
17
|
+
exclude: HTMLTagNames[];
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Config.prototype.wrapNodes = {
|
|
23
|
+
exclude: ['hr', 'style']
|
|
24
|
+
};
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* [[include:plugins/fix/wrap-nodes/README.md]]
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
* @module plugins/fix/wrap-nodes
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
import type { IJodit, Nullable } from 'jodit/types';
|
|
@@ -14,10 +16,12 @@ import { Dom } from 'jodit/core/dom';
|
|
|
14
16
|
import { isString } from 'jodit/core/helpers/checker';
|
|
15
17
|
import { autobind } from 'jodit/core/decorators';
|
|
16
18
|
|
|
19
|
+
import './config';
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Wrap single text nodes in block wrapper
|
|
19
23
|
*/
|
|
20
|
-
export class
|
|
24
|
+
export class WrapNodes extends Plugin {
|
|
21
25
|
/** @override **/
|
|
22
26
|
protected afterInit(jodit: IJodit): void {
|
|
23
27
|
if (jodit.o.enter.toLowerCase() === 'br') {
|
|
@@ -39,7 +43,7 @@ export class WrapTextNodes extends Plugin {
|
|
|
39
43
|
* Process changed value
|
|
40
44
|
*/
|
|
41
45
|
@autobind
|
|
42
|
-
private postProcessSetEditorValue() {
|
|
46
|
+
private postProcessSetEditorValue(): void {
|
|
43
47
|
const { jodit } = this;
|
|
44
48
|
|
|
45
49
|
if (!jodit.isEditorMode()) {
|
|
@@ -113,5 +117,6 @@ export class WrapTextNodes extends Plugin {
|
|
|
113
117
|
* Some element which need append in block
|
|
114
118
|
*/
|
|
115
119
|
private isNotClosed = (n: Nullable<Node>): n is Element =>
|
|
116
|
-
Dom.isElement(n) &&
|
|
120
|
+
Dom.isElement(n) &&
|
|
121
|
+
!(Dom.isBlock(n) || Dom.isTag(n, this.j.o.wrapNodes.exclude));
|
|
117
122
|
}
|
|
@@ -21,13 +21,13 @@ declare module 'jodit/config' {
|
|
|
21
21
|
* Open WYSIWYG in full screen
|
|
22
22
|
* @example
|
|
23
23
|
* ```javascript
|
|
24
|
-
* var editor =
|
|
24
|
+
* var editor = Jodit.make({
|
|
25
25
|
* fullsize: true // fullsize editor
|
|
26
26
|
* });
|
|
27
27
|
* ```
|
|
28
28
|
* @example
|
|
29
29
|
* ```javascript
|
|
30
|
-
* var editor =
|
|
30
|
+
* var editor = Jodit.make();
|
|
31
31
|
* editor.e.fire('toggleFullSize');
|
|
32
32
|
* editor.e.fire('toggleFullSize', true); // fullsize
|
|
33
33
|
* editor.e.fire('toggleFullSize', false); // usual mode
|
|
@@ -81,7 +81,7 @@ export function fullsize(editor: IViewWithToolbar): void {
|
|
|
81
81
|
oldWidth: number = 0,
|
|
82
82
|
wasToggled = false;
|
|
83
83
|
|
|
84
|
-
const resize = () => {
|
|
84
|
+
const resize = (): void => {
|
|
85
85
|
const { container, events } = editor;
|
|
86
86
|
|
|
87
87
|
if (events) {
|
|
@@ -105,7 +105,7 @@ export function fullsize(editor: IViewWithToolbar): void {
|
|
|
105
105
|
/**
|
|
106
106
|
* Change editor's state between FullSize and normal
|
|
107
107
|
*/
|
|
108
|
-
toggle = (enable?: boolean) => {
|
|
108
|
+
toggle = (enable?: boolean): void => {
|
|
109
109
|
const { container, events } = editor;
|
|
110
110
|
|
|
111
111
|
if (!container) {
|
|
@@ -100,9 +100,9 @@ export function iframe(editor: IJodit): void {
|
|
|
100
100
|
editor
|
|
101
101
|
);
|
|
102
102
|
|
|
103
|
-
const init = () => {
|
|
103
|
+
const init = (): boolean => {
|
|
104
104
|
if (!editor.iframe) {
|
|
105
|
-
return;
|
|
105
|
+
return false;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
const doc = (editor.iframe.contentWindow as Window).document;
|
|
@@ -110,7 +110,7 @@ export function iframe(editor: IJodit): void {
|
|
|
110
110
|
|
|
111
111
|
const docMode = opt.editHTMLDocumentMode;
|
|
112
112
|
|
|
113
|
-
const toggleEditable = () => {
|
|
113
|
+
const toggleEditable = (): void => {
|
|
114
114
|
attr(
|
|
115
115
|
doc.body,
|
|
116
116
|
'contenteditable',
|
|
@@ -327,11 +327,11 @@ export class imageProperties extends Plugin {
|
|
|
327
327
|
lockSize
|
|
328
328
|
} = refs<HTMLInputElement>(this.form);
|
|
329
329
|
|
|
330
|
-
const updateLock = () => {
|
|
330
|
+
const updateLock = (): void => {
|
|
331
331
|
lockMargin.checked = this.state.marginIsLocked;
|
|
332
332
|
lockSize.checked = this.state.sizeIsLocked;
|
|
333
333
|
},
|
|
334
|
-
updateAlign = () => {
|
|
334
|
+
updateAlign = (): void => {
|
|
335
335
|
if (
|
|
336
336
|
image.style.cssFloat &&
|
|
337
337
|
['left', 'right'].indexOf(
|
|
@@ -349,24 +349,24 @@ export class imageProperties extends Plugin {
|
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
351
|
},
|
|
352
|
-
updateBorderRadius = () => {
|
|
352
|
+
updateBorderRadius = (): void => {
|
|
353
353
|
borderRadius.value = (
|
|
354
354
|
parseInt(image.style.borderRadius || '0', 10) || '0'
|
|
355
355
|
).toString();
|
|
356
356
|
},
|
|
357
|
-
updateId = () => {
|
|
357
|
+
updateId = (): void => {
|
|
358
358
|
id.value = attr(image, 'id') || '';
|
|
359
359
|
},
|
|
360
|
-
updateStyle = () => {
|
|
360
|
+
updateStyle = (): void => {
|
|
361
361
|
style.value = attr(image, 'style') || '';
|
|
362
362
|
},
|
|
363
|
-
updateClasses = () => {
|
|
363
|
+
updateClasses = (): void => {
|
|
364
364
|
classes.value = (attr(image, 'class') || '').replace(
|
|
365
365
|
/jodit_focused_image[\s]*/,
|
|
366
366
|
''
|
|
367
367
|
);
|
|
368
368
|
},
|
|
369
|
-
updateMargins = () => {
|
|
369
|
+
updateMargins = (): void => {
|
|
370
370
|
if (!opt.image.editMargins) {
|
|
371
371
|
return;
|
|
372
372
|
}
|
|
@@ -406,7 +406,7 @@ export class imageProperties extends Plugin {
|
|
|
406
406
|
|
|
407
407
|
this.state.marginIsLocked = equal;
|
|
408
408
|
},
|
|
409
|
-
updateSizes = () => {
|
|
409
|
+
updateSizes = (): void => {
|
|
410
410
|
const width =
|
|
411
411
|
attr(image, 'width') ||
|
|
412
412
|
css(image, 'width', true) ||
|
|
@@ -440,7 +440,7 @@ export class imageProperties extends Plugin {
|
|
|
440
440
|
return Math.abs(w - h * this.state.ratio) < 1;
|
|
441
441
|
})();
|
|
442
442
|
},
|
|
443
|
-
updateText = () => {
|
|
443
|
+
updateText = (): void => {
|
|
444
444
|
imageTitle.value = attr(image, 'title') || '';
|
|
445
445
|
|
|
446
446
|
imageAlt.value = attr(image, 'alt') || '';
|
|
@@ -457,7 +457,7 @@ export class imageProperties extends Plugin {
|
|
|
457
457
|
imageLinkOpenInNewTab.checked = false;
|
|
458
458
|
}
|
|
459
459
|
},
|
|
460
|
-
updateSrc = () => {
|
|
460
|
+
updateSrc = (): void => {
|
|
461
461
|
imageSrc.value = attr(image, 'src') || '';
|
|
462
462
|
|
|
463
463
|
if (imageViewSrc) {
|
|
@@ -601,8 +601,7 @@ export class imageProperties extends Plugin {
|
|
|
601
601
|
);
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
this.j.
|
|
605
|
-
|
|
604
|
+
this.j.synchronizeValues();
|
|
606
605
|
this.dialog.close();
|
|
607
606
|
}
|
|
608
607
|
|
|
@@ -613,7 +612,7 @@ export class imageProperties extends Plugin {
|
|
|
613
612
|
private openImageEditor(): void {
|
|
614
613
|
const url: string = attr(this.state.image, 'src') || '',
|
|
615
614
|
a = this.j.c.element('a'),
|
|
616
|
-
loadExternal = () => {
|
|
615
|
+
loadExternal = (): void => {
|
|
617
616
|
if (a.host !== location.host) {
|
|
618
617
|
Confirm(
|
|
619
618
|
this.j.i18n(
|