jodit 3.19.4 → 3.20.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/build/jodit.css +45 -42
- package/build/jodit.es2018.css +38 -36
- package/build/jodit.es2018.en.css +38 -36
- package/build/jodit.es2018.en.js +22562 -25637
- package/build/jodit.es2018.en.min.css +1 -1
- package/build/jodit.es2018.en.min.js +1 -1
- package/build/jodit.es2018.js +23105 -26181
- package/build/jodit.es2018.min.css +1 -1
- package/build/jodit.es2018.min.js +1 -1
- package/build/jodit.js +797 -386
- package/build/jodit.min.css +2 -2
- package/build/jodit.min.js +1 -1
- package/build/plugins/debug/debug.es2018.en.js +97 -0
- package/build/plugins/debug/debug.es2018.en.min.js +1 -0
- package/build/plugins/debug/debug.es2018.js +97 -0
- package/build/plugins/debug/debug.es2018.min.js +1 -0
- package/build/plugins/debug/debug.js +96 -0
- package/build/plugins/debug/debug.min.js +1 -0
- package/build/plugins/speech-recognize/speech-recognize.css +1 -1
- package/build/plugins/speech-recognize/speech-recognize.es2018.css +1 -1
- package/build/plugins/speech-recognize/speech-recognize.es2018.en.css +1 -1
- package/build/plugins/speech-recognize/speech-recognize.es2018.en.js +331 -398
- package/build/plugins/speech-recognize/speech-recognize.es2018.en.min.js +1 -1
- package/build/plugins/speech-recognize/speech-recognize.es2018.js +331 -398
- package/build/plugins/speech-recognize/speech-recognize.es2018.min.js +1 -1
- package/build/plugins/speech-recognize/speech-recognize.js +1 -1
- package/build/vdom.css +1 -1
- package/build/vdom.js +1 -1
- package/index.html +2 -2
- package/package.json +9 -4
- package/src/config.ts +4 -2
- package/src/core/constants.ts +7 -7
- package/src/core/decorators/derive/README.md +71 -0
- package/src/core/decorators/derive/derive.ts +48 -0
- package/src/core/decorators/index.ts +1 -0
- package/src/core/decorators/spy/spy.ts +5 -0
- package/src/core/dom/dom.test.js +0 -1
- package/src/core/dom/dom.ts +28 -13
- package/src/core/event-emitter/observable.ts +3 -3
- package/src/core/helpers/helpers.test.js +0 -170
- package/src/core/plugin/plugin-system.ts +20 -0
- package/src/core/selection/select.ts +27 -9
- package/src/core/selection/style/api/toggle/toggle-ordered-list.ts +5 -1
- package/src/core/selection/style/api/wrap-ordered-list.ts +5 -1
- package/src/core/selection/style/api/wrap-unwrapped-text.ts +1 -1
- package/src/core/selection/style/style.test.js +1 -1
- package/src/core/{view/panel.ts → traits/dlgs.ts} +17 -9
- package/src/core/traits/elms.ts +4 -8
- package/src/core/traits/index.ts +1 -0
- package/src/core/traits/mods.ts +17 -10
- package/src/core/ui/button/index.ts +1 -0
- package/src/{plugins → core/ui/button}/tooltip/README.md +0 -0
- package/src/{plugins → core/ui/button}/tooltip/tooltip.less +4 -4
- package/src/{plugins → core/ui/button}/tooltip/tooltip.test.js +3 -2
- package/src/core/ui/button/tooltip/tooltip.ts +132 -0
- package/src/core/ui/element.ts +5 -27
- package/src/core/ui/group/group.test.js +44 -0
- package/src/core/ui/group/group.ts +4 -4
- package/src/core/view/view-with-toolbar.ts +2 -2
- package/src/core/view/view.ts +11 -33
- package/src/jodit.ts +20 -8
- package/src/langs/ar.js +1 -1
- package/src/langs/cs_cz.js +1 -1
- package/src/langs/de.js +1 -1
- package/src/langs/es.js +1 -1
- package/src/langs/fa.js +1 -1
- package/src/langs/fr.js +1 -1
- package/src/langs/he.js +1 -1
- package/src/langs/hu.js +1 -1
- package/src/langs/i18n.test.js +170 -0
- package/src/langs/id.js +1 -1
- package/src/langs/it.js +1 -1
- package/src/langs/ja.js +1 -1
- package/src/langs/ko.js +1 -1
- package/src/langs/nl.js +1 -1
- package/src/langs/pl.js +1 -1
- package/src/langs/pt_br.js +1 -1
- package/src/langs/ru.js +1 -1
- package/src/langs/tr.js +1 -1
- package/src/langs/zh_cn.js +1 -1
- package/src/langs/zh_tw.js +1 -1
- package/src/modules/dialog/dialog.less +2 -0
- package/src/modules/dialog/dialog.ts +27 -50
- package/src/modules/file-browser/README.md +10 -10
- package/src/modules/file-browser/__image_snapshots__/file-browser-test-screenshot-js-filebrowser-screenshot-testing-open-filebrowser-works-1-snap.png +0 -0
- package/src/modules/file-browser/builders/context-menu.ts +1 -1
- package/src/modules/file-browser/file-browser.test.js +26 -13
- package/src/modules/file-browser/file-browser.test.screenshot.js +23 -0
- package/src/modules/file-browser/file-browser.ts +9 -5
- package/src/modules/history/snapshot.ts +12 -3
- package/src/modules/image-editor/__image_snapshots__/image-editor-test-screenshot-js-image-editor-screenshot-testing-open-image-editor-works-1-snap.png +0 -0
- package/src/modules/image-editor/image-editor.test.screenshot.js +25 -0
- package/src/modules/image-editor/image-editor.ts +7 -6
- package/src/modules/status-bar/status-bar.ts +5 -16
- package/src/modules/table/table.test.js +2 -1
- package/src/modules/toolbar/collection/collection.ts +6 -1
- package/src/modules/uploader/README.md +1 -1
- package/src/modules/uploader/config.ts +1 -1
- package/src/modules/uploader/uploader.test.js +96 -46
- package/src/plugins/about/about.ts +1 -1
- package/src/plugins/add-new-line/add-new-line.ts +5 -4
- package/src/plugins/backspace/backspace.test.js +33 -39
- package/src/plugins/backspace/backspace.ts +10 -4
- package/src/plugins/backspace/cases/check-remove-char.ts +36 -14
- package/src/plugins/backspace/cases/check-remove-unbreakable-element.ts +8 -0
- package/src/plugins/backspace/config.ts +1 -1
- package/src/plugins/backspace/interface.d.ts +1 -1
- package/src/plugins/clean-html/clean-html.test.js +240 -164
- package/src/plugins/clean-html/config.ts +10 -2
- package/src/plugins/clean-html/helpers/remove-format/remove-format-for-collapsed-selection.ts +3 -2
- package/src/plugins/clean-html/helpers/remove-format/remove-format-for-selection.ts +2 -2
- package/src/plugins/clean-html/helpers/visitor/filters/index.ts +1 -0
- package/src/plugins/clean-html/helpers/visitor/filters/remove-empty-text-node.ts +35 -0
- package/src/plugins/clean-html/helpers/visitor/filters/remove-inv-text-nodes.ts +2 -6
- package/src/plugins/clean-html/helpers/visitor/visit-node-walker.ts +5 -0
- package/src/plugins/debug/debug.ts +68 -0
- package/src/plugins/drag-and-drop/drag-and-drop.ts +0 -1
- package/src/plugins/drag-and-drop-element/drag-and-drop-element.test.js +37 -34
- package/src/plugins/dtd/README.md +52 -0
- package/{types/plugins/tooltip/tooltip.d.ts → src/plugins/dtd/after-insert/index.ts} +5 -4
- package/src/plugins/dtd/after-insert/remove-extra-br.ts +39 -0
- package/src/plugins/dtd/before-insert/check-block-nesting.ts +40 -0
- package/src/plugins/dtd/before-insert/index.ts +12 -0
- package/src/plugins/dtd/config.ts +67 -0
- package/src/plugins/dtd/dtd.test.js +128 -0
- package/src/plugins/dtd/dtd.ts +48 -0
- package/src/plugins/enter/enter.test.js +89 -193
- package/src/plugins/enter/enter.ts +14 -11
- package/src/plugins/enter/helpers/check-br.ts +11 -1
- package/src/plugins/enter/helpers/index.ts +1 -0
- package/src/plugins/enter/helpers/move-cursor-out-from-specal-tags.ts +32 -0
- package/src/plugins/enter/helpers/split-fragment.ts +1 -0
- package/src/plugins/fullsize/config.ts +1 -1
- package/src/plugins/fullsize/fullsize.test.js +77 -12
- package/src/plugins/fullsize/fullsize.ts +12 -1
- package/src/plugins/iframe/config.ts +1 -1
- package/src/plugins/image-properties/README.md +7 -0
- package/src/plugins/image-properties/image-properties.ts +1 -1
- package/src/plugins/index.ts +1 -1
- package/src/plugins/limit/limit.test.js +27 -0
- package/src/plugins/limit/limit.ts +4 -2
- package/src/plugins/line-height/line-height.svg +1 -1
- package/src/plugins/link/README.md +5 -0
- package/src/plugins/link/link.test.js +11 -12
- package/src/plugins/link/link.ts +1 -1
- package/src/plugins/mobile/mobile.ts +1 -1
- package/src/plugins/ordered-list/ordered-list.test.js +3 -14
- package/src/plugins/paste/config.ts +0 -7
- package/src/plugins/paste/paste.test.js +3 -3
- package/src/plugins/paste-storage/paste-storage.ts +1 -1
- package/src/plugins/preview/preview.ts +1 -1
- package/src/plugins/search/search.ts +1 -1
- package/src/plugins/select/config.ts +1 -1
- package/src/plugins/spellcheck/config.ts +1 -1
- package/src/plugins/symbols/symbols.test.js +5 -4
- package/src/plugins/table/config.ts +4 -17
- package/src/plugins/table/table.test.js +2 -2
- package/src/plugins/wrap-nodes/wrap-nodes.test.js +34 -5
- package/src/plugins/wrap-nodes/wrap-nodes.ts +59 -16
- package/src/styles/variables.less +1 -1
- package/src/types/ajax.d.ts +2 -2
- package/src/types/file-browser.d.ts +4 -2
- package/src/types/jodit.d.ts +3 -2
- package/src/types/plugin.d.ts +1 -0
- package/src/types/toolbar.d.ts +12 -6
- package/src/types/traits.d.ts +30 -1
- package/src/types/types.d.ts +1 -0
- package/src/types/view.d.ts +9 -34
- package/src/typings.d.ts +1 -0
- package/types/config.d.ts +3 -2
- package/types/core/constants.d.ts +7 -7
- package/types/core/decorators/derive/derive.d.ts +6 -0
- package/types/core/decorators/index.d.ts +1 -0
- package/types/core/dom/dom.d.ts +5 -4
- package/types/core/plugin/plugin-system.d.ts +4 -0
- package/types/core/traits/dlgs.d.ts +15 -0
- package/types/core/traits/elms.d.ts +2 -4
- package/types/core/traits/index.d.ts +1 -0
- package/types/core/traits/mods.d.ts +5 -8
- package/types/core/ui/button/index.d.ts +1 -0
- package/types/core/ui/button/tooltip/tooltip.d.ts +29 -0
- package/types/core/ui/element.d.ts +3 -9
- package/types/core/ui/group/group.d.ts +2 -2
- package/types/core/view/view-with-toolbar.d.ts +2 -2
- package/types/core/view/view.d.ts +5 -10
- package/types/jodit.d.ts +7 -4
- package/types/modules/dialog/dialog.d.ts +8 -10
- package/types/modules/file-browser/file-browser.d.ts +5 -2
- package/types/modules/history/snapshot.d.ts +3 -2
- package/types/modules/image-editor/image-editor.d.ts +4 -4
- package/types/modules/status-bar/status-bar.d.ts +3 -4
- package/types/modules/toolbar/collection/collection.d.ts +1 -0
- package/types/plugins/clean-html/config.d.ts +7 -1
- package/types/plugins/clean-html/helpers/visitor/filters/index.d.ts +1 -0
- package/types/plugins/clean-html/helpers/visitor/filters/remove-empty-text-node.d.ts +13 -0
- package/types/plugins/dtd/after-insert/index.d.ts +10 -0
- package/types/plugins/dtd/after-insert/remove-extra-br.d.ts +16 -0
- package/types/plugins/dtd/before-insert/check-block-nesting.d.ts +16 -0
- package/types/plugins/dtd/before-insert/index.d.ts +10 -0
- package/types/plugins/dtd/config.d.ts +27 -0
- package/types/plugins/dtd/dtd.d.ts +6 -0
- package/types/plugins/enter/helpers/index.d.ts +1 -0
- package/types/plugins/enter/helpers/move-cursor-out-from-specal-tags.d.ts +13 -0
- package/types/plugins/iframe/config.d.ts +1 -1
- package/types/plugins/index.d.ts +1 -1
- package/types/plugins/paste/config.d.ts +0 -4
- package/types/plugins/spellcheck/config.d.ts +1 -1
- package/types/types/ajax.d.ts +2 -2
- package/types/types/file-browser.d.ts +4 -2
- package/types/types/jodit.d.ts +3 -2
- package/types/types/plugin.d.ts +1 -0
- package/types/types/toolbar.d.ts +12 -6
- package/types/types/traits.d.ts +30 -1
- package/types/types/types.d.ts +1 -0
- package/types/types/view.d.ts +9 -34
- package/src/plugins/tooltip/tooltip.ts +0 -114
- package/types/core/view/panel.d.ts +0 -13
|
@@ -0,0 +1,32 @@
|
|
|
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/enter
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { IJodit, Nullable, HTMLTagNames } from 'jodit/types';
|
|
12
|
+
import { Dom } from 'jodit/core/dom/dom';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Checks if the cursor is on the edge of a special tag and exits if so
|
|
16
|
+
*/
|
|
17
|
+
export function moveCursorOutFromSpecialTags(
|
|
18
|
+
jodit: IJodit,
|
|
19
|
+
current: Nullable<Node>,
|
|
20
|
+
tags: HTMLTagNames[]
|
|
21
|
+
): void {
|
|
22
|
+
const { s } = jodit;
|
|
23
|
+
|
|
24
|
+
const link = Dom.closest(current, tags, jodit.editor);
|
|
25
|
+
if (link) {
|
|
26
|
+
if (s.cursorOnTheRight(link)) {
|
|
27
|
+
s.setCursorAfter(link);
|
|
28
|
+
} else if (s.cursorOnTheLeft(link)) {
|
|
29
|
+
s.setCursorBefore(link);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -6,29 +6,94 @@
|
|
|
6
6
|
|
|
7
7
|
describe('Fullsize plugin', function () {
|
|
8
8
|
describe('Toggle fullsize', function () {
|
|
9
|
-
it('Should resize all boxes to first state',
|
|
9
|
+
it('Should resize all boxes to first state', () => {
|
|
10
10
|
const editor = getJodit({
|
|
11
11
|
history: {
|
|
12
12
|
timeout: 0
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
|
|
16
|
+
const checkSizes = ['container', 'workplace', 'editor'];
|
|
17
|
+
|
|
18
|
+
const initialSizes = checkSizes.map(
|
|
19
|
+
key => editor[key].offsetHeight
|
|
20
|
+
),
|
|
21
|
+
equal = (a, b) => Math.abs(a - b) <= 2;
|
|
22
22
|
|
|
23
23
|
editor.toggleFullSize(true);
|
|
24
|
-
|
|
25
|
-
expect(equal(editor[key].offsetHeight,
|
|
24
|
+
checkSizes.map((key, index) => {
|
|
25
|
+
expect(equal(editor[key].offsetHeight, initialSizes[index])).is
|
|
26
|
+
.false;
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
editor.toggleFullSize(false);
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
expect(
|
|
31
|
+
checkSizes.map(function (key, index) {
|
|
32
|
+
expect(
|
|
33
|
+
equal(editor[key].offsetHeight, initialSizes[index])
|
|
34
|
+
).is.true;
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function checkAllParents(editor, enabled) {
|
|
39
|
+
let parent = editor.container.parentNode;
|
|
40
|
+
|
|
41
|
+
while (parent && parent.nodeType === Node.ELEMENT_NODE) {
|
|
42
|
+
expect(
|
|
43
|
+
parent.classList.contains('jodit_fullsize-box_true')
|
|
44
|
+
).equals(enabled);
|
|
45
|
+
parent = parent.parentNode;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
describe('globalFullSize', () => {
|
|
50
|
+
describe('set fullsize', () => {
|
|
51
|
+
it('Should set special class for all parents', () => {
|
|
52
|
+
const editor = getJodit();
|
|
53
|
+
editor.toggleFullSize(true);
|
|
54
|
+
checkAllParents(editor, true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('remove fullsize', () => {
|
|
59
|
+
it('Should remove special class for all parents', () => {
|
|
60
|
+
const editor = getJodit();
|
|
61
|
+
editor.toggleFullSize(true);
|
|
62
|
+
editor.toggleFullSize(false);
|
|
63
|
+
checkAllParents(editor, false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('Several fullsize blocks', () => {
|
|
67
|
+
it('Should remove special class for all parents only for latest block', () => {
|
|
68
|
+
const editor = getJodit();
|
|
69
|
+
editor.toggleFullSize(true);
|
|
70
|
+
const dialog = editor.dlg();
|
|
71
|
+
dialog.open('test');
|
|
72
|
+
dialog.toggleFullSize(true);
|
|
73
|
+
|
|
74
|
+
checkAllParents(editor, true);
|
|
75
|
+
|
|
76
|
+
dialog.toggleFullSize(false);
|
|
77
|
+
checkAllParents(editor, true);
|
|
78
|
+
|
|
79
|
+
editor.toggleFullSize(false);
|
|
80
|
+
checkAllParents(editor, false);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('Close dialog', () => {
|
|
85
|
+
it('Should work same way', () => {
|
|
86
|
+
const editor = getJodit();
|
|
87
|
+
const dialog = editor.dlg();
|
|
88
|
+
dialog.open('test');
|
|
89
|
+
dialog.toggleFullSize(true);
|
|
90
|
+
|
|
91
|
+
checkAllParents(dialog, true);
|
|
92
|
+
|
|
93
|
+
dialog.close();
|
|
94
|
+
checkAllParents(dialog, false);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
32
97
|
});
|
|
33
98
|
});
|
|
34
99
|
});
|
|
@@ -19,6 +19,8 @@ import { pluginSystem } from 'jodit/core/global';
|
|
|
19
19
|
|
|
20
20
|
import './config';
|
|
21
21
|
|
|
22
|
+
const fullsizeStack = new Set();
|
|
23
|
+
|
|
22
24
|
/**
|
|
23
25
|
* Process `toggleFullSize` event, and behavior - set/unset fullsize mode
|
|
24
26
|
*/
|
|
@@ -84,7 +86,16 @@ export function fullsize(editor: IViewWithToolbar): void {
|
|
|
84
86
|
css(editor.toolbar.container, 'width', 'auto');
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
enable
|
|
90
|
+
? fullsizeStack.add(container)
|
|
91
|
+
: fullsizeStack.delete(container);
|
|
92
|
+
|
|
93
|
+
const shouldToggleGlobalFullsize =
|
|
94
|
+
editor.o.globalFullSize &&
|
|
95
|
+
((fullsizeStack.size === 1 && enable) ||
|
|
96
|
+
(fullsizeStack.size === 0 && !enable));
|
|
97
|
+
|
|
98
|
+
if (shouldToggleGlobalFullsize) {
|
|
88
99
|
let node = container.parentNode as HTMLElement;
|
|
89
100
|
|
|
90
101
|
while (
|
|
@@ -26,7 +26,7 @@ declare module 'jodit/config' {
|
|
|
26
26
|
iframeDefaultSrc: string;
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Base URL where the root directory for
|
|
29
|
+
* Base URL where the root directory for [[Config.iframe]] mode
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
32
|
* ```javascript
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
# Image properties dialog
|
|
2
2
|
|
|
3
3
|
After double-clicking on a photo in the editor, it opens the photo editing dialog.
|
|
4
|
+
|
|
5
|
+
## Known Issues
|
|
6
|
+
|
|
7
|
+
- When opening an editor in a [mui](https://mui.com/material-ui/api/modal) dialog box and opening the image dialog box in it,
|
|
8
|
+
the mui dialog does not allow focus to be passed out. As a result, no field inside image properties can be focused.
|
|
9
|
+
Just enable the [disableEnforceFocus](https://mui.com/material-ui/api/modal/#props) option.
|
|
10
|
+
[Image properties - Input fields are not clickable ( react + material ui ) #879](https://github.com/xdan/jodit/issues/879)
|
package/src/plugins/index.ts
CHANGED
|
@@ -67,7 +67,7 @@ import 'jodit/plugins/symbols/symbols';
|
|
|
67
67
|
import 'jodit/plugins/tab/tab';
|
|
68
68
|
import 'jodit/plugins/table/table';
|
|
69
69
|
import 'jodit/plugins/table-keyboard-navigation/table-keyboard-navigation';
|
|
70
|
-
import 'jodit/plugins/tooltip/tooltip';
|
|
71
70
|
import 'jodit/plugins/video/video';
|
|
72
71
|
import 'jodit/plugins/wrap-nodes/wrap-nodes';
|
|
72
|
+
import 'jodit/plugins/dtd/dtd';
|
|
73
73
|
import 'jodit/plugins/xpath/xpath';
|
|
@@ -23,6 +23,33 @@ describe('Limit plugin', function () {
|
|
|
23
23
|
}, 200);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
describe('For special keys (ctrl + c etc.)', function () {
|
|
27
|
+
it('should allow press them', done => {
|
|
28
|
+
const editor = getJodit({
|
|
29
|
+
limitChars: 5
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
editor.value = '<p>11111</p>';
|
|
33
|
+
setCursorToChar(editor);
|
|
34
|
+
|
|
35
|
+
editor.e.on('keyup.limit', e => {
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
try {
|
|
38
|
+
expect(e.ctrlKey).is.true;
|
|
39
|
+
expect(e.defaultPrevented).is.false;
|
|
40
|
+
done();
|
|
41
|
+
} catch (e) {
|
|
42
|
+
done(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
simulateEvent('keyup', 'c', editor, opts => {
|
|
48
|
+
opts.ctrlKey = true;
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
26
53
|
describe('Stat plugin', function () {
|
|
27
54
|
it('should show chars count', function (done) {
|
|
28
55
|
const editor = getJodit({
|
|
@@ -33,7 +33,6 @@ export class limit extends Plugin {
|
|
|
33
33
|
|
|
34
34
|
if (jodit && (limitWords || limitChars)) {
|
|
35
35
|
let snapshot: SnapshotType | null = null;
|
|
36
|
-
|
|
37
36
|
jodit.e
|
|
38
37
|
.off('.limit')
|
|
39
38
|
.on('beforePaste.limit', () => {
|
|
@@ -60,7 +59,10 @@ export class limit extends Plugin {
|
|
|
60
59
|
event: KeyboardEvent | null = null,
|
|
61
60
|
inputText: string = ''
|
|
62
61
|
): boolean {
|
|
63
|
-
if (
|
|
62
|
+
if (
|
|
63
|
+
event &&
|
|
64
|
+
(COMMAND_KEYS.includes(event.key) || event.ctrlKey || event.metaKey)
|
|
65
|
+
) {
|
|
64
66
|
return false;
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
2
2
|
<path
|
|
3
3
|
d="M5.09668 6.99707H7.17358L4.17358 3.99707L1.17358 6.99707H3.09668V17.0031H1.15881L4.15881 20.0031L7.15881 17.0031H5.09668V6.99707Z"/>
|
|
4
4
|
<path d="M22.8412 7H8.84119V5H22.8412V7Z"/>
|
|
@@ -61,4 +61,9 @@ Jodit.make('#editor', {
|
|
|
61
61
|
});
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
## Known Issues
|
|
64
65
|
|
|
66
|
+
- When opening an editor in a [mui](https://mui.com/material-ui/api/modal) dialog box and opening the link popup in it,
|
|
67
|
+
the mui dialog does not allow focus to be passed out. As a result, no field inside form can be focused.
|
|
68
|
+
Just enable the [disableEnforceFocus](https://mui.com/material-ui/api/modal/#props) option.
|
|
69
|
+
[Image properties - Input fields are not clickable ( react + material ui ) #879](https://github.com/xdan/jodit/issues/879)
|
|
@@ -540,7 +540,8 @@ describe('Link plugin', function () {
|
|
|
540
540
|
}
|
|
541
541
|
});
|
|
542
542
|
|
|
543
|
-
editor.value = '';
|
|
543
|
+
editor.value = '<p>|<br></p>';
|
|
544
|
+
setCursorToChar(editor);
|
|
544
545
|
|
|
545
546
|
clickButton('link', editor);
|
|
546
547
|
|
|
@@ -570,13 +571,13 @@ describe('Link plugin', function () {
|
|
|
570
571
|
|
|
571
572
|
url.focus();
|
|
572
573
|
url.value = 'tests/artio.jpg';
|
|
573
|
-
simulateEvent('submit',
|
|
574
|
+
simulateEvent('submit', list.querySelector('form'));
|
|
574
575
|
|
|
575
576
|
expect(sortAttributes(editor.value)).equals(
|
|
576
577
|
'<p><a href="tests/artio.jpg">123</a></p>'
|
|
577
578
|
);
|
|
578
579
|
|
|
579
|
-
simulateEvent('mousedown',
|
|
580
|
+
simulateEvent('mousedown', editor.editor);
|
|
580
581
|
|
|
581
582
|
expect(list.parentNode).is.null;
|
|
582
583
|
});
|
|
@@ -584,22 +585,20 @@ describe('Link plugin', function () {
|
|
|
584
585
|
it('Should fire change event', function () {
|
|
585
586
|
let change = 0;
|
|
586
587
|
|
|
587
|
-
const editor = getJodit(
|
|
588
|
-
events: {
|
|
589
|
-
change: function () {
|
|
590
|
-
change += 1;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
});
|
|
588
|
+
const editor = getJodit();
|
|
594
589
|
|
|
595
|
-
editor.value = '';
|
|
590
|
+
editor.value = '<p>|<br></p>';
|
|
591
|
+
setCursorToChar(editor);
|
|
592
|
+
editor.events.on('change', function () {
|
|
593
|
+
change += 1;
|
|
594
|
+
});
|
|
596
595
|
|
|
597
596
|
clickButton('link', editor);
|
|
598
597
|
|
|
599
598
|
const list = getOpenedPopup(editor);
|
|
600
599
|
const url = list.querySelector('input[ref=url_input]');
|
|
601
600
|
url.value = 'tests/artio.jpg';
|
|
602
|
-
simulateEvent('submit',
|
|
601
|
+
simulateEvent('submit', list.querySelector('form'));
|
|
603
602
|
|
|
604
603
|
expect(sortAttributes(editor.value)).equals(
|
|
605
604
|
'<p><a href="tests/artio.jpg">tests/artio.jpg</a></p>'
|
package/src/plugins/link/link.ts
CHANGED
|
@@ -77,7 +77,7 @@ export function mobile(editor: IJodit): void {
|
|
|
77
77
|
).offsetWidth;
|
|
78
78
|
|
|
79
79
|
const newStore = ((): ReturnType<typeof splitArray> => {
|
|
80
|
-
if (width >= editor.o.sizeLG) {
|
|
80
|
+
if (editor.isFullSize || width >= editor.o.sizeLG) {
|
|
81
81
|
return splitArray(editor.o.buttons);
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -22,26 +22,15 @@ describe('Test orderedList plugin', function () {
|
|
|
22
22
|
|
|
23
23
|
it('If press Enter inside <li> in the end it should create new <li> and cursor must be in it', function () {
|
|
24
24
|
const editor = getJodit();
|
|
25
|
-
editor.value = '<ul><li>test
|
|
26
|
-
|
|
27
|
-
const sel = editor.s.sel,
|
|
28
|
-
range = editor.s.createRange();
|
|
29
|
-
|
|
30
|
-
range.setStart(
|
|
31
|
-
editor.editor.firstChild.firstChild.firstChild,
|
|
32
|
-
4
|
|
33
|
-
);
|
|
34
|
-
range.collapse(true);
|
|
35
|
-
|
|
36
|
-
sel.removeAllRanges();
|
|
37
|
-
sel.addRange(range);
|
|
25
|
+
editor.value = '<ul><li>test|</li></ul>';
|
|
26
|
+
setCursorToChar(editor);
|
|
38
27
|
|
|
39
28
|
simulateEvent('keydown', Jodit.KEY_ENTER, editor.editor);
|
|
40
29
|
|
|
41
30
|
editor.s.insertNode(editor.createInside.text(' a '));
|
|
42
31
|
|
|
43
32
|
expect(editor.value).equals(
|
|
44
|
-
'<ul><li>test</li><li> a
|
|
33
|
+
'<ul><li>test</li><li> a </li></ul>'
|
|
45
34
|
);
|
|
46
35
|
});
|
|
47
36
|
|
|
@@ -43,11 +43,6 @@ declare module 'jodit/config' {
|
|
|
43
43
|
*/
|
|
44
44
|
nl2brInPlainText: boolean;
|
|
45
45
|
|
|
46
|
-
/**
|
|
47
|
-
* Draggable elements
|
|
48
|
-
*/
|
|
49
|
-
draggableTags: string | string[];
|
|
50
|
-
|
|
51
46
|
/**
|
|
52
47
|
* Options when inserting HTML string
|
|
53
48
|
*/
|
|
@@ -68,8 +63,6 @@ Config.prototype.memorizeChoiceWhenPasteFragment = false;
|
|
|
68
63
|
|
|
69
64
|
Config.prototype.nl2brInPlainText = true;
|
|
70
65
|
|
|
71
|
-
Config.prototype.draggableTags = ['img', 'jodit-media', 'jodit'];
|
|
72
|
-
|
|
73
66
|
const psKey = 'pasteStorage';
|
|
74
67
|
|
|
75
68
|
Config.prototype.controls.paste = {
|
|
@@ -1050,7 +1050,7 @@ describe('Test paste plugin', () => {
|
|
|
1050
1050
|
};
|
|
1051
1051
|
};
|
|
1052
1052
|
|
|
1053
|
-
simulateEvent('paste',
|
|
1053
|
+
simulateEvent('paste', editor.editor, emulatePasteEvent);
|
|
1054
1054
|
|
|
1055
1055
|
expect(editor.value).equals('<p>test</p>');
|
|
1056
1056
|
|
|
@@ -1077,7 +1077,7 @@ describe('Test paste plugin', () => {
|
|
|
1077
1077
|
});
|
|
1078
1078
|
|
|
1079
1079
|
expect(editor.value).equals(
|
|
1080
|
-
'<p>test
|
|
1080
|
+
'<p>test<br>test<br>test<br></p>'
|
|
1081
1081
|
);
|
|
1082
1082
|
});
|
|
1083
1083
|
});
|
|
@@ -1255,7 +1255,7 @@ describe('Test paste plugin', () => {
|
|
|
1255
1255
|
simulateEvent('paste', editor.editor, emulatePasteEvent);
|
|
1256
1256
|
|
|
1257
1257
|
expect(editor.value).equals(
|
|
1258
|
-
'<p>test
|
|
1258
|
+
'<p>test<br>test<br>test<br>test<br>test<br><br></p>'
|
|
1259
1259
|
);
|
|
1260
1260
|
});
|
|
1261
1261
|
});
|
|
@@ -144,7 +144,7 @@ export class search extends Plugin {
|
|
|
144
144
|
|
|
145
145
|
const textNode = this.j.createInside.text(this.ui.replace);
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
Dom.safeInsertNode(rng, textNode);
|
|
148
148
|
this.j.s.select(textNode);
|
|
149
149
|
this.tryScrollToElement(textNode);
|
|
150
150
|
this.cache = {};
|
|
@@ -16,7 +16,7 @@ declare module 'jodit/config' {
|
|
|
16
16
|
interface Config {
|
|
17
17
|
/**
|
|
18
18
|
* Options specifies whether the editor is to have its spelling and grammar checked or not
|
|
19
|
-
* @see
|
|
19
|
+
* @see http://www.w3schools.com/tags/att_global_spellcheck.asp
|
|
20
20
|
*/
|
|
21
21
|
spellcheck: boolean;
|
|
22
22
|
}
|
|
@@ -214,7 +214,8 @@ describe('Symbols plugin', function () {
|
|
|
214
214
|
buttons: 'symbols'
|
|
215
215
|
});
|
|
216
216
|
|
|
217
|
-
editor.value = '';
|
|
217
|
+
editor.value = '<p>test|</p>';
|
|
218
|
+
setCursorToChar(editor);
|
|
218
219
|
|
|
219
220
|
const btn = getButton('symbols', editor);
|
|
220
221
|
|
|
@@ -227,7 +228,7 @@ describe('Symbols plugin', function () {
|
|
|
227
228
|
|
|
228
229
|
simulateEvent('keydown', Jodit.KEY_ENTER, currentActive);
|
|
229
230
|
|
|
230
|
-
expect(editor.value).equals('<p
|
|
231
|
+
expect(editor.value).equals('<p>test&</p>');
|
|
231
232
|
|
|
232
233
|
simulateEvent('click', btn); // close previous
|
|
233
234
|
simulateEvent('click', btn);
|
|
@@ -237,9 +238,9 @@ describe('Symbols plugin', function () {
|
|
|
237
238
|
|
|
238
239
|
const currentActive2 = dialog.getElementsByTagName('a')[125];
|
|
239
240
|
|
|
240
|
-
simulateEvent('mousedown',
|
|
241
|
+
simulateEvent('mousedown', currentActive2);
|
|
241
242
|
|
|
242
|
-
expect(editor.value).equals('<p
|
|
243
|
+
expect(editor.value).equals('<p>test&½</p>');
|
|
243
244
|
});
|
|
244
245
|
});
|
|
245
246
|
});
|
|
@@ -180,22 +180,6 @@ Config.prototype.controls.table = {
|
|
|
180
180
|
tbody.appendChild(tr);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
const crnt = editor.s.current();
|
|
184
|
-
|
|
185
|
-
if (crnt && editor.s.isCollapsed()) {
|
|
186
|
-
const block = Dom.closest(crnt, Dom.isBlock, editor.editor);
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
block &&
|
|
190
|
-
block !== editor.editor &&
|
|
191
|
-
!block.nodeName.match(
|
|
192
|
-
/^TD|TH|TBODY|TABLE|THEADER|TFOOTER$/
|
|
193
|
-
)
|
|
194
|
-
) {
|
|
195
|
-
editor.s.setCursorAfter(block);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
183
|
$$('input[type=checkbox]:checked', options).forEach(
|
|
200
184
|
(input: HTMLElement) => {
|
|
201
185
|
(input as HTMLInputElement).value
|
|
@@ -206,7 +190,10 @@ Config.prototype.controls.table = {
|
|
|
206
190
|
}
|
|
207
191
|
);
|
|
208
192
|
|
|
209
|
-
editor.
|
|
193
|
+
if (editor.editor.firstChild) {
|
|
194
|
+
editor.s.insertNode(crt.text('\n'), false, false);
|
|
195
|
+
}
|
|
196
|
+
|
|
210
197
|
editor.s.insertNode(table, false);
|
|
211
198
|
|
|
212
199
|
if (first_td) {
|
|
@@ -15,7 +15,7 @@ describe('Test table plugin', () => {
|
|
|
15
15
|
popup.querySelector('span[data-index="6"]')
|
|
16
16
|
);
|
|
17
17
|
expect(sortAttributes(editor.value)).eq(
|
|
18
|
-
'
|
|
18
|
+
'<table style="border-collapse:collapse;width:100%"><tbody>\n<tr>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td>\n\t<td style="width:14.28%"><br></td></tr></tbody></table>'
|
|
19
19
|
);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
@@ -36,7 +36,7 @@ describe('Test table plugin', () => {
|
|
|
36
36
|
popup.querySelector('span[data-index="2"]')
|
|
37
37
|
);
|
|
38
38
|
expect(sortAttributes(editor.value)).eq(
|
|
39
|
-
'
|
|
39
|
+
'<table style="border-collapse:collapse;width:100%"><tbody>\n<tr>\n\t<td style="color:red;width:33.33%"><br></td>\n\t<td style="color:red;width:33.33%"><br></td>\n\t<td style="color:red;width:33.33%"><br></td></tr></tbody></table>'
|
|
40
40
|
);
|
|
41
41
|
});
|
|
42
42
|
});
|
|
@@ -12,10 +12,39 @@ describe('WrapNodes plugin test', function () {
|
|
|
12
12
|
expect(editor.value).equals('<p>test</p>');
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
describe('Use Japanese keyboard', function () {
|
|
16
|
+
it('Should right wrap text', async function () {
|
|
17
|
+
const editor = getJodit({
|
|
18
|
+
language: 'ja'
|
|
19
|
+
});
|
|
20
|
+
editor.value = '';
|
|
21
|
+
|
|
22
|
+
editor.s.insertNode(editor.createInside.text('た'));
|
|
23
|
+
await editor.async.requestIdlePromise();
|
|
24
|
+
editor.s.insertNode(editor.createInside.text('て'));
|
|
25
|
+
await editor.async.requestIdlePromise();
|
|
26
|
+
editor.s.insertNode(editor.createInside.text('い'));
|
|
27
|
+
await editor.async.requestIdlePromise();
|
|
28
|
+
|
|
29
|
+
expect(editor.value).equals('<p>たてい</p>');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('Wrap leafs', function () {
|
|
34
|
+
it('Should wrap alone LI element', function () {
|
|
35
|
+
const editor = getJodit();
|
|
36
|
+
editor.value = '<li>test</li>';
|
|
37
|
+
expect(editor.value).equals('<ul><li>test</li></ul>');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('Should wrap several LI elements', function () {
|
|
41
|
+
const editor = getJodit();
|
|
42
|
+
editor.value =
|
|
43
|
+
'<li>test</li><li>test</li><p>test</p>test<li>test</li> <li>test</li>s<li>test</li>';
|
|
44
|
+
expect(editor.value).equals(
|
|
45
|
+
'<ul><li>test</li><li>test</li></ul><p>test</p><p>test</p><ul><li>test</li><li>test</li></ul> <p>s</p><ul><li>test</li></ul>'
|
|
46
|
+
);
|
|
47
|
+
});
|
|
19
48
|
});
|
|
20
49
|
|
|
21
50
|
describe('For STYLE/SCRIPT elements', function () {
|
|
@@ -114,7 +143,7 @@ describe('WrapNodes plugin test', function () {
|
|
|
114
143
|
expect(editor.value).equals('<p>test</p>');
|
|
115
144
|
expect(editor.history.length).equals(1);
|
|
116
145
|
editor.history.undo();
|
|
117
|
-
expect(editor.value).equals('');
|
|
146
|
+
expect(editor.value).equals('<p><br></p>');
|
|
118
147
|
});
|
|
119
148
|
});
|
|
120
149
|
|