jodit 4.18.3 → 4.18.6
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/CHANGELOG.md +52 -0
- package/es2015/jodit.css +72 -34
- package/es2015/jodit.fat.min.css +1 -1
- package/es2015/jodit.fat.min.js +35 -10
- package/es2015/jodit.js +1967 -327
- package/es2015/jodit.min.css +1 -1
- package/es2015/jodit.min.js +41 -16
- package/es2015/plugins/debug/debug.css +1 -1
- package/es2015/plugins/debug/debug.js +1 -1
- package/es2015/plugins/debug/debug.min.js +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2018/jodit.fat.min.css +1 -1
- package/es2018/jodit.fat.min.js +35 -10
- package/es2018/jodit.min.css +1 -1
- package/es2018/jodit.min.js +35 -10
- package/es2018/plugins/debug/debug.min.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021/jodit.css +72 -34
- package/es2021/jodit.fat.min.css +1 -1
- package/es2021/jodit.fat.min.js +42 -17
- package/es2021/jodit.js +1949 -323
- package/es2021/jodit.min.css +1 -1
- package/es2021/jodit.min.js +42 -17
- package/es2021/plugins/debug/debug.css +1 -1
- package/es2021/plugins/debug/debug.js +1 -1
- package/es2021/plugins/debug/debug.min.js +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021.en/jodit.css +72 -34
- package/es2021.en/jodit.fat.min.css +1 -1
- package/es2021.en/jodit.fat.min.js +42 -17
- package/es2021.en/jodit.js +1923 -297
- package/es2021.en/jodit.min.css +1 -1
- package/es2021.en/jodit.min.js +51 -26
- package/es2021.en/plugins/debug/debug.css +1 -1
- package/es2021.en/plugins/debug/debug.js +1 -1
- package/es2021.en/plugins/debug/debug.min.js +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es5/jodit.css +85 -38
- package/es5/jodit.fat.min.css +1 -1
- package/es5/jodit.fat.min.js +2 -2
- package/es5/jodit.js +2225 -379
- package/es5/jodit.min.css +3 -3
- package/es5/jodit.min.js +2 -2
- package/es5/plugins/debug/debug.css +1 -1
- package/es5/plugins/debug/debug.js +1 -1
- package/es5/plugins/debug/debug.min.js +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es5/polyfills.fat.min.js +1 -1
- package/es5/polyfills.js +1 -1
- package/es5/polyfills.min.js +1 -1
- package/esm/config.d.ts +28 -26
- package/esm/config.js +19 -21
- package/esm/core/constants.js +1 -1
- package/esm/core/helpers/html/apply-styles.js +3 -0
- package/esm/core/helpers/html/clean-from-word.js +3 -0
- package/esm/core/helpers/html/strip-tags.js +24 -6
- package/esm/core/helpers/html/word-lists.d.ts +29 -0
- package/esm/core/helpers/html/word-lists.js +158 -0
- package/esm/core/helpers/utils/align.d.ts +1 -1
- package/esm/core/helpers/utils/align.js +2 -3
- package/esm/core/selection/helpers/index.d.ts +1 -0
- package/esm/core/selection/helpers/index.js +1 -0
- package/esm/core/selection/helpers/is-moved.d.ts +15 -0
- package/esm/core/selection/helpers/is-moved.js +22 -0
- package/esm/core/selection/style/api/list/toggle-ordered-list.js +40 -3
- package/esm/core/selection/style/transactions.js +5 -2
- package/esm/jodit.js +14 -4
- package/esm/langs/ar.d.ts +10 -0
- package/esm/langs/ar.js +11 -1
- package/esm/langs/az.d.ts +10 -0
- package/esm/langs/az.js +11 -1
- package/esm/langs/cs_cz.d.ts +10 -0
- package/esm/langs/cs_cz.js +12 -1
- package/esm/langs/de.d.ts +10 -0
- package/esm/langs/de.js +11 -1
- package/esm/langs/es.d.ts +10 -0
- package/esm/langs/es.js +11 -1
- package/esm/langs/fa.d.ts +10 -0
- package/esm/langs/fa.js +11 -1
- package/esm/langs/fi.d.ts +10 -0
- package/esm/langs/fi.js +11 -1
- package/esm/langs/fr.d.ts +10 -0
- package/esm/langs/fr.js +11 -1
- package/esm/langs/he.d.ts +10 -0
- package/esm/langs/he.js +11 -1
- package/esm/langs/hu.d.ts +10 -0
- package/esm/langs/hu.js +11 -1
- package/esm/langs/id.d.ts +10 -0
- package/esm/langs/id.js +11 -1
- package/esm/langs/it.d.ts +10 -0
- package/esm/langs/it.js +11 -1
- package/esm/langs/ja.d.ts +10 -0
- package/esm/langs/ja.js +11 -1
- package/esm/langs/ko.d.ts +10 -0
- package/esm/langs/ko.js +11 -1
- package/esm/langs/mn.d.ts +10 -0
- package/esm/langs/mn.js +11 -1
- package/esm/langs/nl.d.ts +10 -0
- package/esm/langs/nl.js +11 -1
- package/esm/langs/no.d.ts +10 -0
- package/esm/langs/no.js +11 -1
- package/esm/langs/pl.d.ts +10 -0
- package/esm/langs/pl.js +11 -1
- package/esm/langs/pt_br.d.ts +10 -0
- package/esm/langs/pt_br.js +11 -1
- package/esm/langs/ru.d.ts +10 -0
- package/esm/langs/ru.js +11 -1
- package/esm/langs/sk.d.ts +10 -0
- package/esm/langs/sk.js +11 -1
- package/esm/langs/sv.d.ts +10 -0
- package/esm/langs/sv.js +11 -1
- package/esm/langs/tr.d.ts +10 -0
- package/esm/langs/tr.js +11 -1
- package/esm/langs/ua.d.ts +10 -0
- package/esm/langs/ua.js +11 -1
- package/esm/langs/zh_cn.d.ts +10 -0
- package/esm/langs/zh_cn.js +11 -1
- package/esm/langs/zh_tw.d.ts +10 -0
- package/esm/langs/zh_tw.js +11 -1
- package/esm/modules/dialog/dialog.d.ts +7 -0
- package/esm/modules/dialog/dialog.js +24 -6
- package/esm/modules/table/table.d.ts +6 -0
- package/esm/modules/table/table.js +18 -26
- package/esm/plugins/all.d.ts +1 -0
- package/esm/plugins/all.js +1 -0
- package/esm/plugins/backspace/cases/check-join-neighbors.js +90 -3
- package/esm/plugins/clean-html/clean-html.d.ts +8 -0
- package/esm/plugins/clean-html/clean-html.js +21 -1
- package/esm/plugins/clean-html/helpers/index.d.ts +1 -0
- package/esm/plugins/clean-html/helpers/index.js +1 -0
- package/esm/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
- package/esm/plugins/clean-html/helpers/remove-placeholder-br.js +51 -0
- package/esm/plugins/delete/delete.d.ts +11 -1
- package/esm/plugins/delete/delete.js +92 -16
- package/esm/plugins/focus/focus.js +12 -1
- package/esm/plugins/iframe/config.d.ts +3 -0
- package/esm/plugins/iframe/config.js +0 -27
- package/esm/plugins/iframe/iframe.js +8 -1
- package/esm/plugins/image-processor/image-processor.d.ts +4 -1
- package/esm/plugins/image-processor/image-processor.js +15 -4
- package/esm/plugins/image-properties/readers/align.d.ts +2 -2
- package/esm/plugins/index.d.ts +1 -0
- package/esm/plugins/inline-popup/config/items/iframe.d.ts +9 -1
- package/esm/plugins/inline-popup/config/items/iframe.js +15 -0
- package/esm/plugins/inline-popup/inline-popup.d.ts +19 -0
- package/esm/plugins/inline-popup/inline-popup.js +70 -1
- package/esm/plugins/media/media.js +16 -7
- package/esm/plugins/ordered-list/config.js +13 -2
- package/esm/plugins/ordered-list/start-dialog.d.ts +19 -0
- package/esm/plugins/ordered-list/start-dialog.js +58 -0
- package/esm/plugins/placeholder/placeholder.js +7 -1
- package/esm/plugins/resizer/config.d.ts +5 -3
- package/esm/plugins/resizer/config.js +8 -2
- package/esm/plugins/resizer/resizer.d.ts +20 -0
- package/esm/plugins/resizer/resizer.js +140 -17
- package/esm/plugins/select-cells/select-cells.d.ts +23 -0
- package/esm/plugins/select-cells/select-cells.js +75 -1
- package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +3 -2
- package/esm/plugins/video/config.d.ts +6 -0
- package/esm/plugins/video/config.js +77 -65
- package/esm/plugins/video-properties/interface.d.ts +31 -0
- package/esm/plugins/video-properties/interface.js +6 -0
- package/esm/plugins/video-properties/readers.d.ts +26 -0
- package/esm/plugins/video-properties/readers.js +65 -0
- package/esm/plugins/video-properties/replace.d.ts +15 -0
- package/esm/plugins/video-properties/replace.js +97 -0
- package/esm/plugins/video-properties/ui/ui-video-form.d.ts +41 -0
- package/esm/plugins/video-properties/ui/ui-video-form.js +228 -0
- package/esm/plugins/video-properties/video-properties.d.ts +37 -0
- package/esm/plugins/video-properties/video-properties.js +175 -0
- package/esm/plugins/video-properties/writers.d.ts +15 -0
- package/esm/plugins/video-properties/writers.js +73 -0
- package/esm/types/types.d.ts +1 -1
- package/package.json +1 -1
- package/types/config.d.ts +28 -26
- package/types/core/helpers/html/word-lists.d.ts +29 -0
- package/types/core/helpers/utils/align.d.ts +1 -1
- package/types/core/selection/helpers/index.d.ts +1 -0
- package/types/core/selection/helpers/is-moved.d.ts +15 -0
- package/types/langs/ar.d.ts +10 -0
- package/types/langs/az.d.ts +10 -0
- package/types/langs/cs_cz.d.ts +10 -0
- package/types/langs/de.d.ts +10 -0
- package/types/langs/es.d.ts +10 -0
- package/types/langs/fa.d.ts +10 -0
- package/types/langs/fi.d.ts +10 -0
- package/types/langs/fr.d.ts +10 -0
- package/types/langs/he.d.ts +10 -0
- package/types/langs/hu.d.ts +10 -0
- package/types/langs/id.d.ts +10 -0
- package/types/langs/it.d.ts +10 -0
- package/types/langs/ja.d.ts +10 -0
- package/types/langs/ko.d.ts +10 -0
- package/types/langs/mn.d.ts +10 -0
- package/types/langs/nl.d.ts +10 -0
- package/types/langs/no.d.ts +10 -0
- package/types/langs/pl.d.ts +10 -0
- package/types/langs/pt_br.d.ts +10 -0
- package/types/langs/ru.d.ts +10 -0
- package/types/langs/sk.d.ts +10 -0
- package/types/langs/sv.d.ts +10 -0
- package/types/langs/tr.d.ts +10 -0
- package/types/langs/ua.d.ts +10 -0
- package/types/langs/zh_cn.d.ts +10 -0
- package/types/langs/zh_tw.d.ts +10 -0
- package/types/modules/dialog/dialog.d.ts +7 -0
- package/types/modules/table/table.d.ts +6 -0
- package/types/plugins/clean-html/clean-html.d.ts +8 -0
- package/types/plugins/clean-html/helpers/index.d.ts +1 -0
- package/types/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
- package/types/plugins/delete/delete.d.ts +11 -1
- package/types/plugins/iframe/config.d.ts +3 -0
- package/types/plugins/image-processor/image-processor.d.ts +4 -1
- package/types/plugins/image-properties/readers/align.d.ts +2 -2
- package/types/plugins/index.d.ts +1 -0
- package/types/plugins/inline-popup/config/items/iframe.d.ts +9 -1
- package/types/plugins/inline-popup/inline-popup.d.ts +19 -0
- package/types/plugins/ordered-list/start-dialog.d.ts +19 -0
- package/types/plugins/resizer/config.d.ts +5 -3
- package/types/plugins/resizer/resizer.d.ts +20 -0
- package/types/plugins/select-cells/select-cells.d.ts +23 -0
- package/types/plugins/video/config.d.ts +6 -0
- package/types/plugins/video-properties/interface.d.ts +31 -0
- package/types/plugins/video-properties/readers.d.ts +26 -0
- package/types/plugins/video-properties/replace.d.ts +15 -0
- package/types/plugins/video-properties/ui/ui-video-form.d.ts +41 -0
- package/types/plugins/video-properties/video-properties.d.ts +37 -0
- package/types/plugins/video-properties/writers.d.ts +15 -0
- package/types/types/types.d.ts +1 -1
package/es5/polyfills.fat.min.js
CHANGED
package/es5/polyfills.js
CHANGED
package/es5/polyfills.min.js
CHANGED
package/esm/config.d.ts
CHANGED
|
@@ -26,7 +26,6 @@ import type { Controls } from "./types/index";
|
|
|
26
26
|
import type { HAlignClasses } from "./types/index";
|
|
27
27
|
import type { IAsyncStorageOptions } from "./types/index";
|
|
28
28
|
import type { IExtraPlugin } from "./types/index";
|
|
29
|
-
import type { ImageAlignClasses } from "./types/index";
|
|
30
29
|
import type { ImageHAlign } from "./types/index";
|
|
31
30
|
import type { IUIButtonState } from "./types/index";
|
|
32
31
|
import type { IViewOptions } from "./types/index";
|
|
@@ -642,29 +641,19 @@ declare class Config implements IViewOptions {
|
|
|
642
641
|
*/
|
|
643
642
|
imageDefaultAlign: ImageHAlign;
|
|
644
643
|
/**
|
|
645
|
-
*
|
|
646
|
-
* `
|
|
647
|
-
* chosen alignment's, which can be several separated by spaces. An
|
|
648
|
-
* alignment can also list several such sets, to recognise each of them;
|
|
649
|
-
* aligning writes the first. `alignClasses.img` takes its place when set.
|
|
650
|
-
*
|
|
651
|
-
* ```javascript
|
|
652
|
-
* Jodit.make('#editor', {
|
|
653
|
-
* imageAlignClasses: {
|
|
654
|
-
* left: 'align-left',
|
|
655
|
-
* right: 'align-right',
|
|
656
|
-
* center: ['align-center', 'centered']
|
|
657
|
-
* }
|
|
658
|
-
* });
|
|
659
|
-
* ```
|
|
644
|
+
* @deprecated Use `alignClasses.img`, which takes the same value. When
|
|
645
|
+
* `alignClasses.img` isn't set, the editor copies this into it.
|
|
660
646
|
*/
|
|
661
|
-
imageAlignClasses: Nullable<
|
|
647
|
+
imageAlignClasses: Nullable<HAlignClasses>;
|
|
662
648
|
/**
|
|
663
|
-
* Class names to align elements with, by tag name,
|
|
664
|
-
*
|
|
665
|
-
* popup.
|
|
666
|
-
*
|
|
667
|
-
*
|
|
649
|
+
* Class names to align elements with, by tag name, instead of an inline
|
|
650
|
+
* `float` or `margin`: `img`, and `video`, `audio` and `iframe` in the
|
|
651
|
+
* media popup. Aligning an element removes every class listed for its tag
|
|
652
|
+
* and adds the chosen alignment's, which can be several separated by
|
|
653
|
+
* spaces. An alignment can also list several such sets, to recognise each
|
|
654
|
+
* of them; aligning writes the first. A media wrapper (see
|
|
655
|
+
* `mediaWrappers`), and Jodit's own `jodit` and `jodit-media` wrappers,
|
|
656
|
+
* are aligned with the classes for the media in them.
|
|
668
657
|
*
|
|
669
658
|
* ```javascript
|
|
670
659
|
* const media = {
|
|
@@ -674,7 +663,15 @@ declare class Config implements IViewOptions {
|
|
|
674
663
|
* };
|
|
675
664
|
*
|
|
676
665
|
* Jodit.make('#editor', {
|
|
677
|
-
* alignClasses: {
|
|
666
|
+
* alignClasses: {
|
|
667
|
+
* img: {
|
|
668
|
+
* left: 'align-left',
|
|
669
|
+
* right: 'align-right',
|
|
670
|
+
* center: ['align-center', 'centered']
|
|
671
|
+
* },
|
|
672
|
+
* video: media,
|
|
673
|
+
* iframe: media
|
|
674
|
+
* }
|
|
678
675
|
* });
|
|
679
676
|
* ```
|
|
680
677
|
*/
|
|
@@ -1407,6 +1404,9 @@ interface Config {
|
|
|
1407
1404
|
iframeDoctype: string;
|
|
1408
1405
|
/**
|
|
1409
1406
|
* Custom style to be used inside the iframe to display content.
|
|
1407
|
+
* It goes in after `iframeCSSLinks`. The rules Jodit's own plugins need
|
|
1408
|
+
* in the editing document are added apart from it, so a value of your
|
|
1409
|
+
* own doesn't have to repeat them.
|
|
1410
1410
|
*
|
|
1411
1411
|
* ```javascript
|
|
1412
1412
|
* Jodit.make('#editor', {
|
|
@@ -1759,7 +1759,7 @@ interface Config {
|
|
|
1759
1759
|
}
|
|
1760
1760
|
interface Config {
|
|
1761
1761
|
/**
|
|
1762
|
-
* Set of HTML tag names whose elements can be resized by the user via drag handles (e.g. images, iframes, tables)
|
|
1762
|
+
* Set of HTML tag names whose elements can be resized by the user via drag handles (e.g. images, iframes, tables, videos)
|
|
1763
1763
|
*/
|
|
1764
1764
|
allowResizeTags: Set<HTMLTagNames>;
|
|
1765
1765
|
resizer: {
|
|
@@ -1772,14 +1772,16 @@ interface Config {
|
|
|
1772
1772
|
* Save width and height proportions when resizing
|
|
1773
1773
|
* ```js
|
|
1774
1774
|
* Jodit.make('#editor', {
|
|
1775
|
-
* allowResizeTags: ['img', 'iframe', 'table', 'jodit'],
|
|
1775
|
+
* allowResizeTags: new Set(['img', 'iframe', 'table', 'jodit', 'video']),
|
|
1776
1776
|
* resizer: {
|
|
1777
1777
|
* useAspectRatio: false, // don't save,
|
|
1778
|
-
* useAspectRatio: ['img'], // save only for images
|
|
1778
|
+
* useAspectRatio: new Set(['img']), // save only for images
|
|
1779
1779
|
* useAspectRatio: true // save for all
|
|
1780
1780
|
* }
|
|
1781
1781
|
* });
|
|
1782
1782
|
* ```
|
|
1783
|
+
* Images and videos keep it by default. A video with no height of its
|
|
1784
|
+
* own keeps it by being given only a width.
|
|
1783
1785
|
*/
|
|
1784
1786
|
useAspectRatio: boolean | Set<HTMLTagNames>;
|
|
1785
1787
|
/**
|
package/esm/config.js
CHANGED
|
@@ -746,29 +746,19 @@ class Config {
|
|
|
746
746
|
*/
|
|
747
747
|
this.imageDefaultAlign = 'normal';
|
|
748
748
|
/**
|
|
749
|
-
*
|
|
750
|
-
* `
|
|
751
|
-
* chosen alignment's, which can be several separated by spaces. An
|
|
752
|
-
* alignment can also list several such sets, to recognise each of them;
|
|
753
|
-
* aligning writes the first. `alignClasses.img` takes its place when set.
|
|
754
|
-
*
|
|
755
|
-
* ```javascript
|
|
756
|
-
* Jodit.make('#editor', {
|
|
757
|
-
* imageAlignClasses: {
|
|
758
|
-
* left: 'align-left',
|
|
759
|
-
* right: 'align-right',
|
|
760
|
-
* center: ['align-center', 'centered']
|
|
761
|
-
* }
|
|
762
|
-
* });
|
|
763
|
-
* ```
|
|
749
|
+
* @deprecated Use `alignClasses.img`, which takes the same value. When
|
|
750
|
+
* `alignClasses.img` isn't set, the editor copies this into it.
|
|
764
751
|
*/
|
|
765
752
|
this.imageAlignClasses = null;
|
|
766
753
|
/**
|
|
767
|
-
* Class names to align elements with, by tag name,
|
|
768
|
-
*
|
|
769
|
-
* popup.
|
|
770
|
-
*
|
|
771
|
-
*
|
|
754
|
+
* Class names to align elements with, by tag name, instead of an inline
|
|
755
|
+
* `float` or `margin`: `img`, and `video`, `audio` and `iframe` in the
|
|
756
|
+
* media popup. Aligning an element removes every class listed for its tag
|
|
757
|
+
* and adds the chosen alignment's, which can be several separated by
|
|
758
|
+
* spaces. An alignment can also list several such sets, to recognise each
|
|
759
|
+
* of them; aligning writes the first. A media wrapper (see
|
|
760
|
+
* `mediaWrappers`), and Jodit's own `jodit` and `jodit-media` wrappers,
|
|
761
|
+
* are aligned with the classes for the media in them.
|
|
772
762
|
*
|
|
773
763
|
* ```javascript
|
|
774
764
|
* const media = {
|
|
@@ -778,7 +768,15 @@ class Config {
|
|
|
778
768
|
* };
|
|
779
769
|
*
|
|
780
770
|
* Jodit.make('#editor', {
|
|
781
|
-
* alignClasses: {
|
|
771
|
+
* alignClasses: {
|
|
772
|
+
* img: {
|
|
773
|
+
* left: 'align-left',
|
|
774
|
+
* right: 'align-right',
|
|
775
|
+
* center: ['align-center', 'centered']
|
|
776
|
+
* },
|
|
777
|
+
* video: media,
|
|
778
|
+
* iframe: media
|
|
779
|
+
* }
|
|
782
780
|
* });
|
|
783
781
|
* ```
|
|
784
782
|
*/
|
package/esm/core/constants.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
4
|
* Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
|
-
export const APP_VERSION = "4.18.
|
|
6
|
+
export const APP_VERSION = "4.18.6";
|
|
7
7
|
// prettier-ignore
|
|
8
8
|
export const ES = "es2020";
|
|
9
9
|
export const IS_ES_MODERN = true;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { globalDocument, IS_PROD } from "../../constants.js";
|
|
10
10
|
import { Dom } from "../../dom/dom.js";
|
|
11
|
+
import { readWordListItems, wrapWordListItems } from "./word-lists.js";
|
|
11
12
|
import { trim } from "../string/trim.js";
|
|
12
13
|
import { attr } from "../utils/attr.js";
|
|
13
14
|
import { css } from "../utils/css.js";
|
|
@@ -60,6 +61,7 @@ export function applyStyles(html) {
|
|
|
60
61
|
iframeDoc.open();
|
|
61
62
|
iframeDoc.write(html);
|
|
62
63
|
iframeDoc.close();
|
|
64
|
+
const listItems = readWordListItems(iframeDoc.body);
|
|
63
65
|
// Word marks its auto-generated list markers (the literal
|
|
64
66
|
// bullet/number, e.g. `1.` or `·`) with `mso-list:Ignore`.
|
|
65
67
|
// They are display-only and must not be imported, otherwise
|
|
@@ -95,6 +97,7 @@ export function applyStyles(html) {
|
|
|
95
97
|
throw e;
|
|
96
98
|
}
|
|
97
99
|
}
|
|
100
|
+
wrapWordListItems(listItems);
|
|
98
101
|
Dom.each(iframeDoc.body, node => {
|
|
99
102
|
if (Dom.isElement(node)) {
|
|
100
103
|
const cssText = attr(node, 'style');
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { globalDocument } from "../../constants.js";
|
|
10
10
|
import { Dom } from "../../dom/dom.js";
|
|
11
11
|
import { toArray } from "../array/to-array.js";
|
|
12
|
+
import { readWordListItems, wrapWordListItems } from "./word-lists.js";
|
|
12
13
|
import { trim } from "../string/trim.js";
|
|
13
14
|
import { attr, attrRaw } from "../utils/attr.js";
|
|
14
15
|
/**
|
|
@@ -25,6 +26,7 @@ export function cleanFromWord(html) {
|
|
|
25
26
|
const div = globalDocument.createElement('div');
|
|
26
27
|
div.innerHTML = html;
|
|
27
28
|
const marks = [];
|
|
29
|
+
const listItems = readWordListItems(div);
|
|
28
30
|
if (div.firstChild) {
|
|
29
31
|
Dom.each(div, node => {
|
|
30
32
|
if (!node) {
|
|
@@ -76,6 +78,7 @@ export function cleanFromWord(html) {
|
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
Dom.safeRemove.apply(null, marks);
|
|
81
|
+
wrapWordListItems(listItems);
|
|
79
82
|
convertedString = div.innerHTML;
|
|
80
83
|
}
|
|
81
84
|
catch (e) { }
|
|
@@ -16,8 +16,12 @@ const NEW_LINE_TAGS = new Set([
|
|
|
16
16
|
'h4',
|
|
17
17
|
'h5',
|
|
18
18
|
'h6',
|
|
19
|
-
'hr'
|
|
19
|
+
'hr',
|
|
20
|
+
'ul',
|
|
21
|
+
'ol',
|
|
22
|
+
'li'
|
|
20
23
|
]);
|
|
24
|
+
const LIST_TAGS = new Set(['ul', 'ol']);
|
|
21
25
|
const INVISIBLE_TAGS = new Set(['script', 'style']);
|
|
22
26
|
const ALONE_TAGS = new Set(['br', 'hr', 'input']);
|
|
23
27
|
/**
|
|
@@ -37,6 +41,16 @@ export function stripTags(html, doc = document, exclude = null, blockBr = false)
|
|
|
37
41
|
Dom.each(tmp, node => {
|
|
38
42
|
Dom.isElement(node) && all.push(node);
|
|
39
43
|
});
|
|
44
|
+
// By default blocks are joined with a single space (single-line
|
|
45
|
+
// plain text). When `blockBr` is set, separate them with a line
|
|
46
|
+
// break instead, so paragraph structure survives — e.g. the
|
|
47
|
+
// "Insert only Text" paste option. See #1232
|
|
48
|
+
const separators = new Set();
|
|
49
|
+
const separator = () => {
|
|
50
|
+
const text = doc.createTextNode(blockBr ? '%%%jodit-single-br%%%' : ' ');
|
|
51
|
+
separators.add(text);
|
|
52
|
+
return text;
|
|
53
|
+
};
|
|
40
54
|
all.forEach(p => {
|
|
41
55
|
const pr = p.parentNode;
|
|
42
56
|
if (!pr) {
|
|
@@ -58,16 +72,20 @@ export function stripTags(html, doc = document, exclude = null, blockBr = false)
|
|
|
58
72
|
if (!Dom.isTag(p, NEW_LINE_TAGS)) {
|
|
59
73
|
return;
|
|
60
74
|
}
|
|
75
|
+
const pv = p.previousSibling;
|
|
76
|
+
// A nested list starts on a new line after its item's own text
|
|
77
|
+
if (Dom.isTag(p, LIST_TAGS) &&
|
|
78
|
+
pv &&
|
|
79
|
+
!separators.has(pv) &&
|
|
80
|
+
!(Dom.isText(pv) && /\s$/.test(pv.nodeValue || ''))) {
|
|
81
|
+
Dom.before(p, separator());
|
|
82
|
+
}
|
|
61
83
|
const nx = p.nextSibling;
|
|
62
84
|
if (Dom.isText(nx) && /^\s/.test(nx.nodeValue || '')) {
|
|
63
85
|
return;
|
|
64
86
|
}
|
|
65
87
|
if (nx) {
|
|
66
|
-
|
|
67
|
-
// plain text). When `blockBr` is set, separate them with a line
|
|
68
|
-
// break instead, so paragraph structure survives — e.g. the
|
|
69
|
-
// "Insert only Text" paste option. See #1232
|
|
70
|
-
Dom.before(nx, doc.createTextNode(blockBr ? '%%%jodit-single-br%%%' : ' '));
|
|
88
|
+
Dom.before(nx, separator());
|
|
71
89
|
}
|
|
72
90
|
});
|
|
73
91
|
return restoreTags(trim(tmp.innerText));
|
|
@@ -0,0 +1,29 @@
|
|
|
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-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A Word list paragraph, read before its `mso-list` style is lost
|
|
8
|
+
*/
|
|
9
|
+
export interface WordListItem {
|
|
10
|
+
paragraph: HTMLElement;
|
|
11
|
+
list: string;
|
|
12
|
+
level: number;
|
|
13
|
+
tag: 'ul' | 'ol';
|
|
14
|
+
listStyleType: string | null;
|
|
15
|
+
start: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Finds Word's list paragraphs (`<p style="mso-list:l0 level1 lfo1">`), reads
|
|
19
|
+
* their list, level and type from the `mso-list:Ignore` marker, and removes the
|
|
20
|
+
* marker. Call it before anything strips the `mso-list` styles, then pass the
|
|
21
|
+
* result to {@link wrapWordListItems}
|
|
22
|
+
*/
|
|
23
|
+
export declare function readWordListItems(root: HTMLElement): WordListItem[];
|
|
24
|
+
/**
|
|
25
|
+
* Turns the paragraphs found by {@link readWordListItems} into `<ul>`/`<ol>`
|
|
26
|
+
* lists, nesting them by level. Each paragraph becomes an `<li>` without Word's
|
|
27
|
+
* hanging indent
|
|
28
|
+
*/
|
|
29
|
+
export declare function wrapWordListItems(items: WordListItem[]): void;
|
|
@@ -0,0 +1,158 @@
|
|
|
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-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @module helpers/html
|
|
8
|
+
*/
|
|
9
|
+
import { Dom } from "../../dom/dom.js";
|
|
10
|
+
import { toArray } from "../array/to-array.js";
|
|
11
|
+
import { attr } from "../utils/attr.js";
|
|
12
|
+
const ROMAN = {
|
|
13
|
+
i: 1,
|
|
14
|
+
v: 5,
|
|
15
|
+
x: 10,
|
|
16
|
+
l: 50,
|
|
17
|
+
c: 100,
|
|
18
|
+
d: 500,
|
|
19
|
+
m: 1000
|
|
20
|
+
};
|
|
21
|
+
function romanValue(roman) {
|
|
22
|
+
let value = 0;
|
|
23
|
+
for (let i = 0; i < roman.length; i += 1) {
|
|
24
|
+
const current = ROMAN[roman[i]], next = ROMAN[roman[i + 1]] || 0;
|
|
25
|
+
value += current < next ? -current : current;
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Word's marker text (`1.`, `b)`, `iv.`, `·`, `o`, `§`) decides the list type
|
|
31
|
+
*/
|
|
32
|
+
function parseMarker(marker) {
|
|
33
|
+
const text = marker.replace(/\s+/g, '');
|
|
34
|
+
const decimal = /^\(?(?:\d+\.)*(\d+)[.)]?$/.exec(text);
|
|
35
|
+
if (decimal) {
|
|
36
|
+
return { tag: 'ol', listStyleType: null, start: Number(decimal[1]) };
|
|
37
|
+
}
|
|
38
|
+
const letters = /^\(?([a-z]+|[A-Z]+)[.)]$/.exec(text);
|
|
39
|
+
if (letters) {
|
|
40
|
+
const value = letters[1], lower = value.toLowerCase(), upper = value !== lower;
|
|
41
|
+
if (/^[ivxlcdm]+$/.test(lower) && (lower.length > 1 || lower === 'i')) {
|
|
42
|
+
return {
|
|
43
|
+
tag: 'ol',
|
|
44
|
+
listStyleType: upper ? 'upper-roman' : 'lower-roman',
|
|
45
|
+
start: romanValue(lower)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Word continues a lettered list with aa, bb, ...
|
|
49
|
+
if (/^([a-z])\1*$/.test(lower)) {
|
|
50
|
+
return {
|
|
51
|
+
tag: 'ol',
|
|
52
|
+
listStyleType: upper ? 'upper-alpha' : 'lower-alpha',
|
|
53
|
+
start: (lower.length - 1) * 26 + lower.charCodeAt(0) - 96
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { tag: 'ul', listStyleType: null, start: 1 };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Removes the marker and the wrappers it leaves empty
|
|
61
|
+
*/
|
|
62
|
+
function removeMarker(marker, paragraph) {
|
|
63
|
+
let parent = marker.parentNode;
|
|
64
|
+
Dom.safeRemove(marker);
|
|
65
|
+
while (parent &&
|
|
66
|
+
parent !== paragraph &&
|
|
67
|
+
Dom.isElement(parent) &&
|
|
68
|
+
Dom.isEmpty(parent)) {
|
|
69
|
+
const next = parent.parentNode;
|
|
70
|
+
Dom.safeRemove(parent);
|
|
71
|
+
parent = next;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Finds Word's list paragraphs (`<p style="mso-list:l0 level1 lfo1">`), reads
|
|
76
|
+
* their list, level and type from the `mso-list:Ignore` marker, and removes the
|
|
77
|
+
* marker. Call it before anything strips the `mso-list` styles, then pass the
|
|
78
|
+
* result to {@link wrapWordListItems}
|
|
79
|
+
*/
|
|
80
|
+
export function readWordListItems(root) {
|
|
81
|
+
const items = [];
|
|
82
|
+
toArray(root.querySelectorAll('p')).forEach(paragraph => {
|
|
83
|
+
const match = /mso-list:\s*l(\d+)\s+level(\d+)(?:\s+lfo(\d+))?/i.exec(attr(paragraph, 'style') || '');
|
|
84
|
+
if (!match) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const marker = toArray(paragraph.querySelectorAll('[style]')).find(elm => /mso-list:\s*ignore/i.test(attr(elm, 'style') || ''));
|
|
88
|
+
items.push({
|
|
89
|
+
paragraph,
|
|
90
|
+
list: `${match[1]}:${match[3] || ''}`,
|
|
91
|
+
level: Number(match[2]),
|
|
92
|
+
...parseMarker((marker === null || marker === void 0 ? void 0 : marker.textContent) || '')
|
|
93
|
+
});
|
|
94
|
+
if (marker) {
|
|
95
|
+
removeMarker(marker, paragraph);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return items;
|
|
99
|
+
}
|
|
100
|
+
function isAdjacent(prev, item) {
|
|
101
|
+
return (Dom.findSibling(item.paragraph, true, n => !Dom.isEmptyTextNode(n) && !Dom.isComment(n)) === prev.paragraph);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Turns the paragraphs found by {@link readWordListItems} into `<ul>`/`<ol>`
|
|
105
|
+
* lists, nesting them by level. Each paragraph becomes an `<li>` without Word's
|
|
106
|
+
* hanging indent
|
|
107
|
+
*/
|
|
108
|
+
export function wrapWordListItems(items) {
|
|
109
|
+
let stack = [];
|
|
110
|
+
const continues = items.map((item, index) => index > 0 && isAdjacent(items[index - 1], item));
|
|
111
|
+
items.forEach((item, index) => {
|
|
112
|
+
const { paragraph } = item;
|
|
113
|
+
if (!continues[index]) {
|
|
114
|
+
stack = [];
|
|
115
|
+
}
|
|
116
|
+
while (stack.length && stack[stack.length - 1].level > item.level) {
|
|
117
|
+
stack.pop();
|
|
118
|
+
}
|
|
119
|
+
let top = stack[stack.length - 1];
|
|
120
|
+
if (top && top.level === item.level && top.list !== item.list) {
|
|
121
|
+
stack.pop();
|
|
122
|
+
top = stack[stack.length - 1];
|
|
123
|
+
}
|
|
124
|
+
const doc = paragraph.ownerDocument;
|
|
125
|
+
if (!top || top.level < item.level) {
|
|
126
|
+
const element = doc.createElement(item.tag);
|
|
127
|
+
if (item.listStyleType) {
|
|
128
|
+
element.style.listStyleType = item.listStyleType;
|
|
129
|
+
}
|
|
130
|
+
if (item.tag === 'ol' && item.start !== 1) {
|
|
131
|
+
attr(element, 'start', item.start);
|
|
132
|
+
}
|
|
133
|
+
if (top && top.li) {
|
|
134
|
+
top.li.appendChild(element);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
Dom.before(paragraph, element);
|
|
138
|
+
}
|
|
139
|
+
top = { level: item.level, list: item.list, element };
|
|
140
|
+
stack.push(top);
|
|
141
|
+
}
|
|
142
|
+
const li = doc.createElement('li');
|
|
143
|
+
toArray(paragraph.attributes).forEach(attribute => {
|
|
144
|
+
if (attribute.name !== 'class') {
|
|
145
|
+
li.setAttribute(attribute.name, attribute.value);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
li.style.removeProperty('margin-left');
|
|
149
|
+
li.style.removeProperty('text-indent');
|
|
150
|
+
if (!attr(li, 'style')) {
|
|
151
|
+
attr(li, 'style', null);
|
|
152
|
+
}
|
|
153
|
+
Dom.moveContent(paragraph, li);
|
|
154
|
+
Dom.safeRemove(paragraph);
|
|
155
|
+
top.element.appendChild(li);
|
|
156
|
+
top.li = li;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
@@ -10,7 +10,7 @@ import type { HAlignClasses, IJodit, ImageHAlign, Nullable } from "../../../type
|
|
|
10
10
|
/**
|
|
11
11
|
* The class names to align `elm` with: `alignClasses` for its tag, or for the
|
|
12
12
|
* media in it when it wraps media (a `mediaWrappers` wrapper, `jodit` or
|
|
13
|
-
* `jodit-media`)
|
|
13
|
+
* `jodit-media`)
|
|
14
14
|
*/
|
|
15
15
|
export declare function getAlignClasses(jodit: IJodit, elm: Nullable<HTMLElement>): Nullable<HAlignClasses>;
|
|
16
16
|
/**
|
|
@@ -15,7 +15,7 @@ const classSets = (value) => (isArray(value) ? value : [value !== null && value
|
|
|
15
15
|
/**
|
|
16
16
|
* The class names to align `elm` with: `alignClasses` for its tag, or for the
|
|
17
17
|
* media in it when it wraps media (a `mediaWrappers` wrapper, `jodit` or
|
|
18
|
-
* `jodit-media`)
|
|
18
|
+
* `jodit-media`)
|
|
19
19
|
*/
|
|
20
20
|
export function getAlignClasses(jodit, elm) {
|
|
21
21
|
var _a, _b;
|
|
@@ -25,8 +25,7 @@ export function getAlignClasses(jodit, elm) {
|
|
|
25
25
|
const media = Dom.isTag(elm, new Set(['jodit', 'jodit-media']))
|
|
26
26
|
? elm.firstElementChild
|
|
27
27
|
: getWrappedMedia(jodit, elm);
|
|
28
|
-
|
|
29
|
-
return ((_b = (_a = jodit.o.alignClasses) === null || _a === void 0 ? void 0 : _a[tag]) !== null && _b !== void 0 ? _b : (tag === 'img' ? jodit.o.imageAlignClasses : null));
|
|
28
|
+
return ((_b = (_a = jodit.o.alignClasses) === null || _a === void 0 ? void 0 : _a[(media !== null && media !== void 0 ? media : elm).nodeName.toLowerCase()]) !== null && _b !== void 0 ? _b : null);
|
|
30
29
|
}
|
|
31
30
|
/**
|
|
32
31
|
* Align image, with `classes` (see `alignClasses`) instead of inline styles
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { INVISIBLE_SPACE_REG_EXP_END as INV_END, INVISIBLE_SPACE_REG_EXP_START as INV_START } from "../../constants.js";
|
|
10
10
|
import { Dom } from "../../dom/dom.js";
|
|
11
11
|
export * from "./composed-ranges.js";
|
|
12
|
+
export * from "./is-moved.js";
|
|
12
13
|
export * from "./move-node-inside-start.js";
|
|
13
14
|
export * from "./move-the-node-along-the-edge-outward.js";
|
|
14
15
|
/**
|
|
@@ -0,0 +1,15 @@
|
|
|
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-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @module selection
|
|
8
|
+
*/
|
|
9
|
+
import type { IJodit, Nullable } from "../../../types/index";
|
|
10
|
+
/**
|
|
11
|
+
* Whether the selection, `before` as it was when a key went down, has since
|
|
12
|
+
* moved to somewhere else in the editor
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
export declare function isMoved(jodit: IJodit, before: Nullable<Range>): boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
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-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Whether the selection, `before` as it was when a key went down, has since
|
|
8
|
+
* moved to somewhere else in the editor
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
export function isMoved(jodit, before) {
|
|
12
|
+
const { s } = jodit;
|
|
13
|
+
// Selecting table cells, for one, removes the selection altogether
|
|
14
|
+
if (!before || !s.isInsideArea) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const { range } = s;
|
|
18
|
+
return (range.startContainer !== before.startContainer ||
|
|
19
|
+
range.startOffset !== before.startOffset ||
|
|
20
|
+
range.endContainer !== before.endContainer ||
|
|
21
|
+
range.endOffset !== before.endOffset);
|
|
22
|
+
}
|