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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module plugins/print
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { IJodit } from 'jodit/types';
|
|
11
|
+
import type { IJodit, Nullable } from 'jodit/types';
|
|
12
12
|
import { $$, attr, css, isString } from 'jodit/core/helpers';
|
|
13
13
|
import { Dom } from 'jodit/core/dom';
|
|
14
14
|
|
|
@@ -67,7 +67,8 @@ function fixedAssetsSizeAndAbsoluteLinks(
|
|
|
67
67
|
export function previewBox(
|
|
68
68
|
editor: IJodit,
|
|
69
69
|
defaultValue?: string,
|
|
70
|
-
points: 'pt' | 'px' | '' = 'px'
|
|
70
|
+
points: 'pt' | 'px' | '' = 'px',
|
|
71
|
+
container: Nullable<HTMLElement> = null
|
|
71
72
|
): HTMLElement {
|
|
72
73
|
const restoreAttributes = fixedAssetsSizeAndAbsoluteLinks(editor, points);
|
|
73
74
|
|
|
@@ -77,7 +78,11 @@ export function previewBox(
|
|
|
77
78
|
return res;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
let div: HTMLElement = editor.c.div('jodit__preview-box');
|
|
82
|
+
if (container) {
|
|
83
|
+
container.appendChild(div);
|
|
84
|
+
}
|
|
85
|
+
|
|
81
86
|
css(div, {
|
|
82
87
|
position: 'relative',
|
|
83
88
|
padding: 16
|
|
@@ -100,14 +105,16 @@ export function previewBox(
|
|
|
100
105
|
|
|
101
106
|
div.appendChild(iframe);
|
|
102
107
|
|
|
103
|
-
const
|
|
108
|
+
const myWindow = iframe.contentWindow;
|
|
104
109
|
|
|
105
|
-
if (
|
|
110
|
+
if (myWindow) {
|
|
106
111
|
editor.e.fire(
|
|
107
112
|
'generateDocumentStructure.iframe',
|
|
108
|
-
|
|
113
|
+
myWindow.document,
|
|
109
114
|
editor
|
|
110
115
|
);
|
|
116
|
+
|
|
117
|
+
div = myWindow.document.body;
|
|
111
118
|
}
|
|
112
119
|
} else {
|
|
113
120
|
css(div, {
|
|
@@ -127,7 +134,7 @@ export function previewBox(
|
|
|
127
134
|
for (let i = 0; i < dv.children.length; i += 1) {
|
|
128
135
|
const c = dv.children[i];
|
|
129
136
|
|
|
130
|
-
const newNode =
|
|
137
|
+
const newNode = box.ownerDocument.createElement(c.nodeName);
|
|
131
138
|
|
|
132
139
|
for (let j = 0; j < c.attributes.length; j += 1) {
|
|
133
140
|
attr(
|
|
@@ -5,20 +5,21 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @module plugins/print
|
|
8
|
+
* @module plugins/print/preview
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import './preview.less';
|
|
12
12
|
|
|
13
|
-
import type { IControlType,
|
|
13
|
+
import type { IControlType, IJodit } from 'jodit/types';
|
|
14
14
|
import { Config } from 'jodit/config';
|
|
15
|
-
import
|
|
15
|
+
import { MODE_SOURCE, MODE_WYSIWYG } from 'jodit/core/constants';
|
|
16
16
|
import { previewBox } from 'jodit/plugins/print/helpers';
|
|
17
|
+
import { Dialog } from 'jodit/modules/dialog/dialog';
|
|
17
18
|
|
|
18
19
|
Config.prototype.controls.preview = {
|
|
19
20
|
icon: 'eye',
|
|
20
21
|
command: 'preview',
|
|
21
|
-
mode:
|
|
22
|
+
mode: MODE_SOURCE + MODE_WYSIWYG,
|
|
22
23
|
tooltip: 'Preview'
|
|
23
24
|
} as IControlType;
|
|
24
25
|
|
|
@@ -30,17 +31,17 @@ export function preview(editor: IJodit): void {
|
|
|
30
31
|
editor.registerCommand(
|
|
31
32
|
'preview',
|
|
32
33
|
(_: any, _1: any, defaultValue: string) => {
|
|
33
|
-
const dialog =
|
|
34
|
+
const dialog = new Dialog({
|
|
34
35
|
language: editor.o.language,
|
|
35
36
|
theme: editor.o.theme
|
|
36
37
|
});
|
|
37
38
|
|
|
38
|
-
const div = previewBox(editor, defaultValue);
|
|
39
|
-
|
|
40
39
|
dialog
|
|
41
40
|
.setSize(1024, 600)
|
|
42
|
-
.open(
|
|
41
|
+
.open('', editor.i18n('Preview'))
|
|
43
42
|
.setModal(true);
|
|
43
|
+
|
|
44
|
+
previewBox(editor, defaultValue, 'px', dialog.getElm('content'));
|
|
44
45
|
}
|
|
45
46
|
);
|
|
46
47
|
}
|
|
@@ -30,27 +30,27 @@ Config.prototype.controls.print = {
|
|
|
30
30
|
|
|
31
31
|
getContainer(editor, Config).appendChild(iframe);
|
|
32
32
|
|
|
33
|
-
const afterFinishPrint = () => {
|
|
33
|
+
const afterFinishPrint = (): void => {
|
|
34
34
|
editor.e.off(editor.ow, 'mousemove', afterFinishPrint);
|
|
35
35
|
Dom.safeRemove(iframe);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
38
|
+
const myWindow = iframe.contentWindow;
|
|
39
|
+
if (myWindow) {
|
|
40
40
|
editor.e
|
|
41
|
-
.on(
|
|
41
|
+
.on(myWindow, 'onbeforeunload onafterprint', afterFinishPrint)
|
|
42
42
|
.on(editor.ow, 'mousemove', afterFinishPrint);
|
|
43
43
|
|
|
44
44
|
if (editor.o.iframe) {
|
|
45
45
|
editor.e.fire(
|
|
46
46
|
'generateDocumentStructure.iframe',
|
|
47
|
-
|
|
47
|
+
myWindow.document,
|
|
48
48
|
editor
|
|
49
49
|
);
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
myWindow.document.body.innerHTML = editor.value;
|
|
52
52
|
} else {
|
|
53
|
-
|
|
53
|
+
myWindow.document.write(
|
|
54
54
|
'<!doctype html><html lang="' +
|
|
55
55
|
defaultLanguage(editor.o.language) +
|
|
56
56
|
'"><head><title></title></head>' +
|
|
@@ -58,11 +58,20 @@ Config.prototype.controls.print = {
|
|
|
58
58
|
editor.value +
|
|
59
59
|
'</body></html>'
|
|
60
60
|
);
|
|
61
|
-
|
|
61
|
+
myWindow.document.close();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const style = myWindow.document.createElement('style');
|
|
65
|
+
style.innerHTML = `@media print {
|
|
66
|
+
body {
|
|
67
|
+
-webkit-print-color-adjust: exact;
|
|
68
|
+
}
|
|
69
|
+
}`;
|
|
70
|
+
|
|
71
|
+
myWindow.document.head.appendChild(style);
|
|
72
|
+
|
|
73
|
+
myWindow.focus();
|
|
74
|
+
myWindow.print();
|
|
66
75
|
}
|
|
67
76
|
},
|
|
68
77
|
mode: consts.MODE_SOURCE + consts.MODE_WYSIWYG,
|
|
@@ -15,13 +15,13 @@ import { Plugin } from 'jodit/core/plugin';
|
|
|
15
15
|
|
|
16
16
|
Config.prototype.controls.redo = {
|
|
17
17
|
mode: consts.MODE_SPLIT,
|
|
18
|
-
isDisabled: (editor: IJodit): boolean => !editor.
|
|
18
|
+
isDisabled: (editor: IJodit): boolean => !editor.history.canRedo(),
|
|
19
19
|
tooltip: 'Redo'
|
|
20
20
|
} as IControlType;
|
|
21
21
|
|
|
22
22
|
Config.prototype.controls.undo = {
|
|
23
23
|
mode: consts.MODE_SPLIT,
|
|
24
|
-
isDisabled: (editor: IJodit): boolean => !editor.
|
|
24
|
+
isDisabled: (editor: IJodit): boolean => !editor.history.canUndo(),
|
|
25
25
|
tooltip: 'Undo'
|
|
26
26
|
} as IControlType;
|
|
27
27
|
|
|
@@ -47,7 +47,7 @@ export class redoUndo extends Plugin {
|
|
|
47
47
|
|
|
48
48
|
protected override afterInit(editor: IJodit): void {
|
|
49
49
|
const callback = (command: string): void | false => {
|
|
50
|
-
editor.
|
|
50
|
+
editor.history[command as 'redo' | 'undo']();
|
|
51
51
|
|
|
52
52
|
return false;
|
|
53
53
|
};
|
|
@@ -121,7 +121,7 @@ export class resizer extends Plugin {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
private addEventListeners() {
|
|
124
|
+
private addEventListeners(): void {
|
|
125
125
|
const editor = this.j;
|
|
126
126
|
|
|
127
127
|
editor.e
|
|
@@ -197,7 +197,7 @@ export class resizer extends Plugin {
|
|
|
197
197
|
);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
private onResize = (e: MouseEvent) => {
|
|
200
|
+
private onResize = (e: MouseEvent): void => {
|
|
201
201
|
if (this.isResized) {
|
|
202
202
|
if (!this.element) {
|
|
203
203
|
return;
|
|
@@ -283,12 +283,12 @@ export class resizer extends Plugin {
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
private onClickOutside = (e: MouseEvent) => {
|
|
286
|
+
private onClickOutside = (e: MouseEvent): void => {
|
|
287
287
|
if (this.isShown) {
|
|
288
288
|
if (this.isResized) {
|
|
289
289
|
this.j.unlock();
|
|
290
290
|
this.isResized = false;
|
|
291
|
-
this.j.
|
|
291
|
+
this.j.synchronizeValues();
|
|
292
292
|
e.stopImmediatePropagation();
|
|
293
293
|
|
|
294
294
|
this.j.e.off(
|
|
@@ -302,7 +302,7 @@ export class resizer extends Plugin {
|
|
|
302
302
|
}
|
|
303
303
|
};
|
|
304
304
|
|
|
305
|
-
private onDelete(e: KeyboardEvent) {
|
|
305
|
+
private onDelete(e: KeyboardEvent): void {
|
|
306
306
|
if (!this.element) {
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
@@ -317,7 +317,7 @@ export class resizer extends Plugin {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
@debounce()
|
|
320
|
-
private onChangeEditor() {
|
|
320
|
+
private onChangeEditor(): void {
|
|
321
321
|
if (this.isShown) {
|
|
322
322
|
if (!this.element || !this.element.parentNode) {
|
|
323
323
|
this.hide();
|
|
@@ -404,7 +404,7 @@ export class resizer extends Plugin {
|
|
|
404
404
|
}
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
private onClickElement = (element: HTMLElement) => {
|
|
407
|
+
private onClickElement = (element: HTMLElement): void => {
|
|
408
408
|
if (this.isResized) {
|
|
409
409
|
return;
|
|
410
410
|
}
|
|
@@ -420,7 +420,7 @@ export class resizer extends Plugin {
|
|
|
420
420
|
}
|
|
421
421
|
};
|
|
422
422
|
|
|
423
|
-
private updateSize = () => {
|
|
423
|
+
private updateSize = (): void => {
|
|
424
424
|
if (this.isInDestruct || !this.isShown) {
|
|
425
425
|
return;
|
|
426
426
|
}
|
|
@@ -462,7 +462,7 @@ export class resizer extends Plugin {
|
|
|
462
462
|
}
|
|
463
463
|
};
|
|
464
464
|
|
|
465
|
-
private showSizeViewer(w: number, h: number) {
|
|
465
|
+
private showSizeViewer(w: number, h: number): void {
|
|
466
466
|
if (!this.j.o.resizer.showSize) {
|
|
467
467
|
return;
|
|
468
468
|
}
|
|
@@ -487,7 +487,7 @@ export class resizer extends Plugin {
|
|
|
487
487
|
/**
|
|
488
488
|
* Show resizer
|
|
489
489
|
*/
|
|
490
|
-
private show() {
|
|
490
|
+
private show(): void {
|
|
491
491
|
if (this.j.o.readonly || this.isShown) {
|
|
492
492
|
return;
|
|
493
493
|
}
|
|
@@ -519,7 +519,7 @@ export class resizer extends Plugin {
|
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
-
private hideSizeViewer = () => {
|
|
522
|
+
private hideSizeViewer = (): void => {
|
|
523
523
|
this.sizeViewer.style.opacity = '0';
|
|
524
524
|
};
|
|
525
525
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Search plugin. it is used for custom search in text
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
Disable plugin:
|
|
5
|
+
```js
|
|
6
|
+
Jodit.make('#editor', {
|
|
7
|
+
useSearch: false
|
|
8
|
+
});
|
|
9
|
+
```
|
|
10
|
+
or
|
|
11
|
+
```js
|
|
12
|
+
Jodit.make('#editor', {
|
|
13
|
+
disablePlugins: 'search'
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## JS API
|
|
18
|
+
|
|
19
|
+
### Find and select some text
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
const editor = Jodit.make('#editor');
|
|
23
|
+
editor.value = '<p>this text contains some text</p>';
|
|
24
|
+
editor.e.fire('search', 'some text').then(() => {
|
|
25
|
+
console.log('Selected!');
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Find next fragment
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const editor = Jodit.make('#editor');
|
|
33
|
+
editor.value = '<p>this text thow times contains some text and some text</p>';
|
|
34
|
+
editor.e.fire('searchNext', 'some text').then(() => {
|
|
35
|
+
console.log('Selected!');
|
|
36
|
+
editor.e.fire('searchNext', 'some text');
|
|
37
|
+
})
|
|
38
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
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/search
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { FuzzySearch, IControlType, IJodit } from 'jodit/types';
|
|
12
|
+
import { Config } from 'jodit/config';
|
|
13
|
+
|
|
14
|
+
declare module 'jodit/config' {
|
|
15
|
+
interface Config {
|
|
16
|
+
/**
|
|
17
|
+
* Enable custom search plugin
|
|
18
|
+
* 
|
|
19
|
+
*/
|
|
20
|
+
useSearch: boolean;
|
|
21
|
+
|
|
22
|
+
search: {
|
|
23
|
+
lazyIdleTimeout: number;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Function to search for a string within a substring. The default implementation is [[fuzzySearchIndex]]
|
|
27
|
+
* But you can write your own. It must implement the [[FuzzySearch]] interface.
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* Jodit.make('#editor', {
|
|
31
|
+
* search: {
|
|
32
|
+
* fuzzySearch: (needle, haystack, offset) => {
|
|
33
|
+
* return [haystack.indexOf(needle, offset), needle.length];
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
fuzzySearch?: FuzzySearch;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Config.prototype.useSearch = true;
|
|
45
|
+
Config.prototype.search = {
|
|
46
|
+
lazyIdleTimeout: 0
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
Config.prototype.controls.find = {
|
|
50
|
+
tooltip: 'Find',
|
|
51
|
+
icon: 'search',
|
|
52
|
+
|
|
53
|
+
exec(jodit: IJodit, _, { control }) {
|
|
54
|
+
const value = control.args && control.args[0];
|
|
55
|
+
|
|
56
|
+
switch (value) {
|
|
57
|
+
case 'findPrevious':
|
|
58
|
+
jodit.e.fire('searchPrevious');
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'findNext':
|
|
62
|
+
jodit.e.fire('searchNext');
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
case 'replace':
|
|
66
|
+
jodit.execCommand('openReplaceDialog');
|
|
67
|
+
break;
|
|
68
|
+
|
|
69
|
+
default:
|
|
70
|
+
jodit.execCommand('openSearchDialog');
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
list: {
|
|
75
|
+
search: 'Find',
|
|
76
|
+
findNext: 'Find Next',
|
|
77
|
+
findPrevious: 'Find Previous',
|
|
78
|
+
replace: 'Replace'
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
childTemplate: (_, k, v) => v
|
|
82
|
+
} as IControlType;
|
|
@@ -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/search
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export * from './sentence-finder';
|
|
12
|
+
export * from './wrap-ranges-texts-in-tmp-span';
|
|
@@ -0,0 +1,103 @@
|
|
|
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/search
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
CanUndef,
|
|
13
|
+
FuzzySearch,
|
|
14
|
+
ISelectionRange,
|
|
15
|
+
Nullable
|
|
16
|
+
} from 'jodit/types';
|
|
17
|
+
import { fuzzySearchIndex } from 'jodit/src/core/helpers/string/fuzzy-search-index';
|
|
18
|
+
|
|
19
|
+
export interface State {
|
|
20
|
+
query: string;
|
|
21
|
+
sentence: SentenceFinder;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface QueueItem {
|
|
25
|
+
startIndex: number;
|
|
26
|
+
endIndex: number;
|
|
27
|
+
node: Text;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class SentenceFinder {
|
|
31
|
+
private queue: QueueItem[] = [];
|
|
32
|
+
private value: string = '';
|
|
33
|
+
|
|
34
|
+
constructor(private readonly searchIndex: FuzzySearch = fuzzySearchIndex) {}
|
|
35
|
+
|
|
36
|
+
add(node: Text): void {
|
|
37
|
+
const value = (node.nodeValue ?? '').toLowerCase();
|
|
38
|
+
|
|
39
|
+
if (!value.length) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const index = this.value.length;
|
|
44
|
+
|
|
45
|
+
this.queue.push({
|
|
46
|
+
startIndex: index,
|
|
47
|
+
endIndex: index + value.length,
|
|
48
|
+
node
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
this.value += value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ranges(needle: string, position: number = 0): Nullable<ISelectionRange[]> {
|
|
55
|
+
const results: ISelectionRange[] = [];
|
|
56
|
+
|
|
57
|
+
let index = position,
|
|
58
|
+
len = 0,
|
|
59
|
+
startQueueIndex = 0;
|
|
60
|
+
|
|
61
|
+
// Find all ranges in substring
|
|
62
|
+
do {
|
|
63
|
+
[index, len] = this.searchIndex(needle, this.value, index);
|
|
64
|
+
|
|
65
|
+
if (index !== -1) {
|
|
66
|
+
let startContainer: CanUndef<Text>,
|
|
67
|
+
startOffset: number = 0,
|
|
68
|
+
endContainer: CanUndef<Text>,
|
|
69
|
+
endOffset: number = 0;
|
|
70
|
+
|
|
71
|
+
for (let i = startQueueIndex; i < this.queue.length; i += 1) {
|
|
72
|
+
if (!startContainer && this.queue[i].endIndex > index) {
|
|
73
|
+
startContainer = this.queue[i].node;
|
|
74
|
+
startOffset = index - this.queue[i].startIndex;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
startContainer &&
|
|
79
|
+
this.queue[i].endIndex >= index + len
|
|
80
|
+
) {
|
|
81
|
+
endContainer = this.queue[i].node;
|
|
82
|
+
endOffset = index + len - this.queue[i].startIndex;
|
|
83
|
+
startQueueIndex = i;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (startContainer && endContainer) {
|
|
89
|
+
results.push({
|
|
90
|
+
startContainer,
|
|
91
|
+
startOffset,
|
|
92
|
+
endContainer,
|
|
93
|
+
endOffset
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
index += len;
|
|
98
|
+
}
|
|
99
|
+
} while (index !== -1);
|
|
100
|
+
|
|
101
|
+
return results.length === 0 ? null : results;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
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/search
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { CanUndef, ICreate, ISelectionRange, Nullable } from 'jodit/types';
|
|
12
|
+
import { Dom } from 'jodit/core/dom';
|
|
13
|
+
import { $$ } from 'jodit/src/core/helpers/utils/selector';
|
|
14
|
+
|
|
15
|
+
const TMP_ATTR = 'jd-tmp-selection';
|
|
16
|
+
|
|
17
|
+
export function wrapRangesTextsInTmpSpan(
|
|
18
|
+
rng: ISelectionRange,
|
|
19
|
+
restRanges: ISelectionRange[],
|
|
20
|
+
ci: ICreate,
|
|
21
|
+
root: HTMLElement
|
|
22
|
+
): void {
|
|
23
|
+
if (
|
|
24
|
+
rng.startContainer.nodeValue == null ||
|
|
25
|
+
rng.endContainer.nodeValue == null
|
|
26
|
+
) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const span = ci.element('span', {
|
|
31
|
+
[TMP_ATTR]: true
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const startText = rng.startContainer.nodeValue;
|
|
35
|
+
|
|
36
|
+
let diff = 0;
|
|
37
|
+
if (rng.startOffset !== 0) {
|
|
38
|
+
const text = ci.text(startText.substring(0, rng.startOffset));
|
|
39
|
+
rng.startContainer.nodeValue = startText.substring(rng.startOffset);
|
|
40
|
+
Dom.before(rng.startContainer, text);
|
|
41
|
+
|
|
42
|
+
if (rng.startContainer === rng.endContainer) {
|
|
43
|
+
diff = rng.startOffset;
|
|
44
|
+
rng.endOffset -= diff;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
rng.startOffset = 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const endText = rng.endContainer.nodeValue;
|
|
51
|
+
|
|
52
|
+
if (rng.endOffset !== endText.length) {
|
|
53
|
+
const text = ci.text(endText.substring(rng.endOffset));
|
|
54
|
+
rng.endContainer.nodeValue = endText.substring(0, rng.endOffset);
|
|
55
|
+
Dom.after(rng.endContainer, text);
|
|
56
|
+
|
|
57
|
+
for (const range of restRanges) {
|
|
58
|
+
if (range.startContainer === rng.endContainer) {
|
|
59
|
+
range.startContainer = text;
|
|
60
|
+
range.startOffset = range.startOffset - rng.endOffset - diff;
|
|
61
|
+
|
|
62
|
+
if (range.endContainer === rng.endContainer) {
|
|
63
|
+
range.endContainer = text;
|
|
64
|
+
range.endOffset = range.endOffset - rng.endOffset - diff;
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
rng.endOffset = rng.endContainer.nodeValue.length;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let next: CanUndef<Nullable<Node>> = rng.startContainer;
|
|
75
|
+
|
|
76
|
+
do {
|
|
77
|
+
if (!next) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (Dom.isText(next) && !isSelectionWrapper(next.parentNode)) {
|
|
82
|
+
Dom.wrap(next, span.cloneNode() as HTMLElement, ci);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (next === rng.endContainer) {
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let step: Nullable<Node> = next.firstChild || next.nextSibling;
|
|
90
|
+
|
|
91
|
+
if (!step) {
|
|
92
|
+
while (next && !next.nextSibling && next !== root) {
|
|
93
|
+
next = next.parentNode;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
step = next?.nextSibling as Nullable<Node>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
next = step;
|
|
100
|
+
} while (next && next !== root);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function getSelectionWrappers(root: HTMLElement): HTMLElement[] {
|
|
104
|
+
return $$(`[${TMP_ATTR}]`, root);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function clearSelectionWrappers(root: HTMLElement): void {
|
|
108
|
+
getSelectionWrappers(root).forEach(span => Dom.unwrap(span));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function clearSelectionWrappersFromHTML(root: string): string {
|
|
112
|
+
return root.replace(
|
|
113
|
+
RegExp(`<span[^>]+${TMP_ATTR}[^>]+>(.*?)</span>`, 'g'),
|
|
114
|
+
'$1'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function isSelectionWrapper(node: unknown): boolean {
|
|
119
|
+
return Dom.isElement(node) && node.hasAttribute(TMP_ATTR);
|
|
120
|
+
}
|