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.
Files changed (237) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/es2015/jodit.css +72 -34
  3. package/es2015/jodit.fat.min.css +1 -1
  4. package/es2015/jodit.fat.min.js +35 -10
  5. package/es2015/jodit.js +1967 -327
  6. package/es2015/jodit.min.css +1 -1
  7. package/es2015/jodit.min.js +41 -16
  8. package/es2015/plugins/debug/debug.css +1 -1
  9. package/es2015/plugins/debug/debug.js +1 -1
  10. package/es2015/plugins/debug/debug.min.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  12. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  13. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  14. package/es2018/jodit.fat.min.css +1 -1
  15. package/es2018/jodit.fat.min.js +35 -10
  16. package/es2018/jodit.min.css +1 -1
  17. package/es2018/jodit.min.js +35 -10
  18. package/es2018/plugins/debug/debug.min.js +1 -1
  19. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  20. package/es2021/jodit.css +72 -34
  21. package/es2021/jodit.fat.min.css +1 -1
  22. package/es2021/jodit.fat.min.js +42 -17
  23. package/es2021/jodit.js +1949 -323
  24. package/es2021/jodit.min.css +1 -1
  25. package/es2021/jodit.min.js +42 -17
  26. package/es2021/plugins/debug/debug.css +1 -1
  27. package/es2021/plugins/debug/debug.js +1 -1
  28. package/es2021/plugins/debug/debug.min.js +1 -1
  29. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  30. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  31. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  32. package/es2021.en/jodit.css +72 -34
  33. package/es2021.en/jodit.fat.min.css +1 -1
  34. package/es2021.en/jodit.fat.min.js +42 -17
  35. package/es2021.en/jodit.js +1923 -297
  36. package/es2021.en/jodit.min.css +1 -1
  37. package/es2021.en/jodit.min.js +51 -26
  38. package/es2021.en/plugins/debug/debug.css +1 -1
  39. package/es2021.en/plugins/debug/debug.js +1 -1
  40. package/es2021.en/plugins/debug/debug.min.js +1 -1
  41. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  42. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  43. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  44. package/es5/jodit.css +85 -38
  45. package/es5/jodit.fat.min.css +1 -1
  46. package/es5/jodit.fat.min.js +2 -2
  47. package/es5/jodit.js +2225 -379
  48. package/es5/jodit.min.css +3 -3
  49. package/es5/jodit.min.js +2 -2
  50. package/es5/plugins/debug/debug.css +1 -1
  51. package/es5/plugins/debug/debug.js +1 -1
  52. package/es5/plugins/debug/debug.min.js +1 -1
  53. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  54. package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
  55. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  56. package/es5/polyfills.fat.min.js +1 -1
  57. package/es5/polyfills.js +1 -1
  58. package/es5/polyfills.min.js +1 -1
  59. package/esm/config.d.ts +28 -26
  60. package/esm/config.js +19 -21
  61. package/esm/core/constants.js +1 -1
  62. package/esm/core/helpers/html/apply-styles.js +3 -0
  63. package/esm/core/helpers/html/clean-from-word.js +3 -0
  64. package/esm/core/helpers/html/strip-tags.js +24 -6
  65. package/esm/core/helpers/html/word-lists.d.ts +29 -0
  66. package/esm/core/helpers/html/word-lists.js +158 -0
  67. package/esm/core/helpers/utils/align.d.ts +1 -1
  68. package/esm/core/helpers/utils/align.js +2 -3
  69. package/esm/core/selection/helpers/index.d.ts +1 -0
  70. package/esm/core/selection/helpers/index.js +1 -0
  71. package/esm/core/selection/helpers/is-moved.d.ts +15 -0
  72. package/esm/core/selection/helpers/is-moved.js +22 -0
  73. package/esm/core/selection/style/api/list/toggle-ordered-list.js +40 -3
  74. package/esm/core/selection/style/transactions.js +5 -2
  75. package/esm/jodit.js +14 -4
  76. package/esm/langs/ar.d.ts +10 -0
  77. package/esm/langs/ar.js +11 -1
  78. package/esm/langs/az.d.ts +10 -0
  79. package/esm/langs/az.js +11 -1
  80. package/esm/langs/cs_cz.d.ts +10 -0
  81. package/esm/langs/cs_cz.js +12 -1
  82. package/esm/langs/de.d.ts +10 -0
  83. package/esm/langs/de.js +11 -1
  84. package/esm/langs/es.d.ts +10 -0
  85. package/esm/langs/es.js +11 -1
  86. package/esm/langs/fa.d.ts +10 -0
  87. package/esm/langs/fa.js +11 -1
  88. package/esm/langs/fi.d.ts +10 -0
  89. package/esm/langs/fi.js +11 -1
  90. package/esm/langs/fr.d.ts +10 -0
  91. package/esm/langs/fr.js +11 -1
  92. package/esm/langs/he.d.ts +10 -0
  93. package/esm/langs/he.js +11 -1
  94. package/esm/langs/hu.d.ts +10 -0
  95. package/esm/langs/hu.js +11 -1
  96. package/esm/langs/id.d.ts +10 -0
  97. package/esm/langs/id.js +11 -1
  98. package/esm/langs/it.d.ts +10 -0
  99. package/esm/langs/it.js +11 -1
  100. package/esm/langs/ja.d.ts +10 -0
  101. package/esm/langs/ja.js +11 -1
  102. package/esm/langs/ko.d.ts +10 -0
  103. package/esm/langs/ko.js +11 -1
  104. package/esm/langs/mn.d.ts +10 -0
  105. package/esm/langs/mn.js +11 -1
  106. package/esm/langs/nl.d.ts +10 -0
  107. package/esm/langs/nl.js +11 -1
  108. package/esm/langs/no.d.ts +10 -0
  109. package/esm/langs/no.js +11 -1
  110. package/esm/langs/pl.d.ts +10 -0
  111. package/esm/langs/pl.js +11 -1
  112. package/esm/langs/pt_br.d.ts +10 -0
  113. package/esm/langs/pt_br.js +11 -1
  114. package/esm/langs/ru.d.ts +10 -0
  115. package/esm/langs/ru.js +11 -1
  116. package/esm/langs/sk.d.ts +10 -0
  117. package/esm/langs/sk.js +11 -1
  118. package/esm/langs/sv.d.ts +10 -0
  119. package/esm/langs/sv.js +11 -1
  120. package/esm/langs/tr.d.ts +10 -0
  121. package/esm/langs/tr.js +11 -1
  122. package/esm/langs/ua.d.ts +10 -0
  123. package/esm/langs/ua.js +11 -1
  124. package/esm/langs/zh_cn.d.ts +10 -0
  125. package/esm/langs/zh_cn.js +11 -1
  126. package/esm/langs/zh_tw.d.ts +10 -0
  127. package/esm/langs/zh_tw.js +11 -1
  128. package/esm/modules/dialog/dialog.d.ts +7 -0
  129. package/esm/modules/dialog/dialog.js +24 -6
  130. package/esm/modules/table/table.d.ts +6 -0
  131. package/esm/modules/table/table.js +18 -26
  132. package/esm/plugins/all.d.ts +1 -0
  133. package/esm/plugins/all.js +1 -0
  134. package/esm/plugins/backspace/cases/check-join-neighbors.js +90 -3
  135. package/esm/plugins/clean-html/clean-html.d.ts +8 -0
  136. package/esm/plugins/clean-html/clean-html.js +21 -1
  137. package/esm/plugins/clean-html/helpers/index.d.ts +1 -0
  138. package/esm/plugins/clean-html/helpers/index.js +1 -0
  139. package/esm/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
  140. package/esm/plugins/clean-html/helpers/remove-placeholder-br.js +51 -0
  141. package/esm/plugins/delete/delete.d.ts +11 -1
  142. package/esm/plugins/delete/delete.js +92 -16
  143. package/esm/plugins/focus/focus.js +12 -1
  144. package/esm/plugins/iframe/config.d.ts +3 -0
  145. package/esm/plugins/iframe/config.js +0 -27
  146. package/esm/plugins/iframe/iframe.js +8 -1
  147. package/esm/plugins/image-processor/image-processor.d.ts +4 -1
  148. package/esm/plugins/image-processor/image-processor.js +15 -4
  149. package/esm/plugins/image-properties/readers/align.d.ts +2 -2
  150. package/esm/plugins/index.d.ts +1 -0
  151. package/esm/plugins/inline-popup/config/items/iframe.d.ts +9 -1
  152. package/esm/plugins/inline-popup/config/items/iframe.js +15 -0
  153. package/esm/plugins/inline-popup/inline-popup.d.ts +19 -0
  154. package/esm/plugins/inline-popup/inline-popup.js +70 -1
  155. package/esm/plugins/media/media.js +16 -7
  156. package/esm/plugins/ordered-list/config.js +13 -2
  157. package/esm/plugins/ordered-list/start-dialog.d.ts +19 -0
  158. package/esm/plugins/ordered-list/start-dialog.js +58 -0
  159. package/esm/plugins/placeholder/placeholder.js +7 -1
  160. package/esm/plugins/resizer/config.d.ts +5 -3
  161. package/esm/plugins/resizer/config.js +8 -2
  162. package/esm/plugins/resizer/resizer.d.ts +20 -0
  163. package/esm/plugins/resizer/resizer.js +140 -17
  164. package/esm/plugins/select-cells/select-cells.d.ts +23 -0
  165. package/esm/plugins/select-cells/select-cells.js +75 -1
  166. package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +3 -2
  167. package/esm/plugins/video/config.d.ts +6 -0
  168. package/esm/plugins/video/config.js +77 -65
  169. package/esm/plugins/video-properties/interface.d.ts +31 -0
  170. package/esm/plugins/video-properties/interface.js +6 -0
  171. package/esm/plugins/video-properties/readers.d.ts +26 -0
  172. package/esm/plugins/video-properties/readers.js +65 -0
  173. package/esm/plugins/video-properties/replace.d.ts +15 -0
  174. package/esm/plugins/video-properties/replace.js +97 -0
  175. package/esm/plugins/video-properties/ui/ui-video-form.d.ts +41 -0
  176. package/esm/plugins/video-properties/ui/ui-video-form.js +228 -0
  177. package/esm/plugins/video-properties/video-properties.d.ts +37 -0
  178. package/esm/plugins/video-properties/video-properties.js +175 -0
  179. package/esm/plugins/video-properties/writers.d.ts +15 -0
  180. package/esm/plugins/video-properties/writers.js +73 -0
  181. package/esm/types/types.d.ts +1 -1
  182. package/package.json +1 -1
  183. package/types/config.d.ts +28 -26
  184. package/types/core/helpers/html/word-lists.d.ts +29 -0
  185. package/types/core/helpers/utils/align.d.ts +1 -1
  186. package/types/core/selection/helpers/index.d.ts +1 -0
  187. package/types/core/selection/helpers/is-moved.d.ts +15 -0
  188. package/types/langs/ar.d.ts +10 -0
  189. package/types/langs/az.d.ts +10 -0
  190. package/types/langs/cs_cz.d.ts +10 -0
  191. package/types/langs/de.d.ts +10 -0
  192. package/types/langs/es.d.ts +10 -0
  193. package/types/langs/fa.d.ts +10 -0
  194. package/types/langs/fi.d.ts +10 -0
  195. package/types/langs/fr.d.ts +10 -0
  196. package/types/langs/he.d.ts +10 -0
  197. package/types/langs/hu.d.ts +10 -0
  198. package/types/langs/id.d.ts +10 -0
  199. package/types/langs/it.d.ts +10 -0
  200. package/types/langs/ja.d.ts +10 -0
  201. package/types/langs/ko.d.ts +10 -0
  202. package/types/langs/mn.d.ts +10 -0
  203. package/types/langs/nl.d.ts +10 -0
  204. package/types/langs/no.d.ts +10 -0
  205. package/types/langs/pl.d.ts +10 -0
  206. package/types/langs/pt_br.d.ts +10 -0
  207. package/types/langs/ru.d.ts +10 -0
  208. package/types/langs/sk.d.ts +10 -0
  209. package/types/langs/sv.d.ts +10 -0
  210. package/types/langs/tr.d.ts +10 -0
  211. package/types/langs/ua.d.ts +10 -0
  212. package/types/langs/zh_cn.d.ts +10 -0
  213. package/types/langs/zh_tw.d.ts +10 -0
  214. package/types/modules/dialog/dialog.d.ts +7 -0
  215. package/types/modules/table/table.d.ts +6 -0
  216. package/types/plugins/clean-html/clean-html.d.ts +8 -0
  217. package/types/plugins/clean-html/helpers/index.d.ts +1 -0
  218. package/types/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
  219. package/types/plugins/delete/delete.d.ts +11 -1
  220. package/types/plugins/iframe/config.d.ts +3 -0
  221. package/types/plugins/image-processor/image-processor.d.ts +4 -1
  222. package/types/plugins/image-properties/readers/align.d.ts +2 -2
  223. package/types/plugins/index.d.ts +1 -0
  224. package/types/plugins/inline-popup/config/items/iframe.d.ts +9 -1
  225. package/types/plugins/inline-popup/inline-popup.d.ts +19 -0
  226. package/types/plugins/ordered-list/start-dialog.d.ts +19 -0
  227. package/types/plugins/resizer/config.d.ts +5 -3
  228. package/types/plugins/resizer/resizer.d.ts +20 -0
  229. package/types/plugins/select-cells/select-cells.d.ts +23 -0
  230. package/types/plugins/video/config.d.ts +6 -0
  231. package/types/plugins/video-properties/interface.d.ts +31 -0
  232. package/types/plugins/video-properties/readers.d.ts +26 -0
  233. package/types/plugins/video-properties/replace.d.ts +15 -0
  234. package/types/plugins/video-properties/ui/ui-video-form.d.ts +41 -0
  235. package/types/plugins/video-properties/video-properties.d.ts +37 -0
  236. package/types/plugins/video-properties/writers.d.ts +15 -0
  237. package/types/types/types.d.ts +1 -1
@@ -0,0 +1,26 @@
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 plugins/video-properties
8
+ */
9
+ import type { Nullable } from "../../types/index";
10
+ import type { EditedMedia, VideoPropertiesState } from "./interface";
11
+ /**
12
+ * The media `target` is, or holds as its wrapper (`jodit-media`, the resizer's
13
+ * `jodit` for an embed, or one from `mediaWrappers`)
14
+ * @private
15
+ */
16
+ export declare function editedMedia(target: HTMLElement): Nullable<EditedMedia>;
17
+ /**
18
+ * The size `media` is given, inline or by its attribute
19
+ * @private
20
+ */
21
+ export declare function ownSize(media: EditedMedia, key: 'width' | 'height'): string;
22
+ /**
23
+ * Read the media's values into the state
24
+ * @private
25
+ */
26
+ export declare function readValues(state: VideoPropertiesState): void;
@@ -0,0 +1,65 @@
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
+ import { Dom } from "../../core/dom/dom.js";
7
+ import { isNumeric } from "../../core/helpers/checker/is-numeric.js";
8
+ import { attr } from "../../core/helpers/utils/attr.js";
9
+ import { cssInline } from "../../core/helpers/utils/css.js";
10
+ import { normalSizeFromString } from "../image-properties/utils/utils.js";
11
+ const mediaSelector = 'video, audio, iframe';
12
+ /**
13
+ * The media `target` is, or holds as its wrapper (`jodit-media`, the resizer's
14
+ * `jodit` for an embed, or one from `mediaWrappers`)
15
+ * @private
16
+ */
17
+ export function editedMedia(target) {
18
+ return (target.matches(mediaSelector)
19
+ ? target
20
+ : target.querySelector(mediaSelector));
21
+ }
22
+ /**
23
+ * The size `media` is given, inline or by its attribute
24
+ * @private
25
+ */
26
+ export function ownSize(media, key) {
27
+ return cssInline(media, key) || attr(media, key) || '';
28
+ }
29
+ const toNumber = (value) => parseFloat(value.toString());
30
+ /**
31
+ * Read the media's values into the state
32
+ * @private
33
+ */
34
+ export function readValues(state) {
35
+ const { media, values } = state;
36
+ const width = ownSize(media, 'width');
37
+ const height = ownSize(media, 'height');
38
+ values.width = width ? normalSizeFromString(width) : media.offsetWidth;
39
+ values.height = height ? normalSizeFromString(height) : '';
40
+ if (Dom.isTag(media, 'video') && media.videoWidth) {
41
+ state.ratio = media.videoWidth / media.videoHeight;
42
+ }
43
+ else if (isNumeric(values.width) && isNumeric(values.height)) {
44
+ state.ratio = toNumber(values.width) / toNumber(values.height);
45
+ }
46
+ else {
47
+ state.ratio = media.offsetWidth / media.offsetHeight || 1;
48
+ }
49
+ // One with no height takes it from its width
50
+ if (!height && isNumeric(values.width)) {
51
+ values.height = Math.round(toNumber(values.width) / state.ratio);
52
+ }
53
+ state.sizeIsLocked =
54
+ isNumeric(values.width) &&
55
+ isNumeric(values.height) &&
56
+ (!height ||
57
+ Math.abs(toNumber(values.width) - toNumber(values.height) * state.ratio) < 1);
58
+ values.poster = attr(media, 'poster') || '';
59
+ values.autoplay = media.hasAttribute('autoplay');
60
+ values.loop = media.hasAttribute('loop');
61
+ // Autoplay's own: turning it off gives the sound back
62
+ values.muted = media.hasAttribute('muted') && !values.autoplay;
63
+ // Without Autoplay it keeps its controls, or it could never be played
64
+ values.controls = media.hasAttribute('controls') || !values.autoplay;
65
+ }
@@ -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 plugins/video-properties
8
+ */
9
+ import type { IJodit } from "../../types/index";
10
+ /**
11
+ * Run `insert`, which inserts media at the cursor, with the cursor after
12
+ * `replaced`, and put what it inserts in place of `replaced`
13
+ * @private
14
+ */
15
+ export declare function replaceMedia(j: IJodit, replaced: HTMLElement, insert: () => void): void;
@@ -0,0 +1,97 @@
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
+ import { Dom } from "../../core/dom/dom.js";
7
+ import { attr } from "../../core/helpers/utils/attr.js";
8
+ import { css } from "../../core/helpers/utils/css.js";
9
+ import { editedMedia, ownSize, readValues } from "./readers.js";
10
+ import { applyValues } from "./writers.js";
11
+ /**
12
+ * Give `media`, in `outer`, the classes, inline styles, size and playback
13
+ * settings of `old`, in `oldOuter`. It keeps its own source and poster.
14
+ */
15
+ function takeOver(j, oldOuter, old, outer, media) {
16
+ var _a;
17
+ const state = {
18
+ target: oldOuter,
19
+ media: old,
20
+ ratio: 1,
21
+ sizeIsLocked: true,
22
+ values: {
23
+ width: '',
24
+ height: '',
25
+ poster: '',
26
+ autoplay: false,
27
+ loop: false,
28
+ muted: false,
29
+ controls: true
30
+ }
31
+ };
32
+ readValues(state);
33
+ const pairs = [[old, media]];
34
+ // A wrapper kept in the content, which holds the alignment
35
+ if (oldOuter !== old &&
36
+ outer !== media &&
37
+ oldOuter.nodeName === outer.nodeName) {
38
+ pairs.push([oldOuter, outer]);
39
+ }
40
+ pairs.forEach(([from, to]) => {
41
+ ['class', 'style'].forEach(name => attr(to, name, attr(from, name)));
42
+ });
43
+ // A video's size is CSS and an embed's its attributes, so the writer sizes
44
+ // one that's a different element
45
+ if (old.nodeName !== media.nodeName) {
46
+ css(media, { width: null, height: null });
47
+ if (!((_a = attr(media, 'style')) === null || _a === void 0 ? void 0 : _a.trim())) {
48
+ attr(media, 'style', null);
49
+ }
50
+ }
51
+ state.media = media;
52
+ state.values.poster = attr(media, 'poster') || '';
53
+ applyValues(j, state, Boolean(ownSize(old, 'width') || ownSize(old, 'height')));
54
+ }
55
+ /**
56
+ * Run `insert`, which inserts media at the cursor, with the cursor after
57
+ * `replaced`, and put what it inserts in place of `replaced`
58
+ * @private
59
+ */
60
+ export function replaceMedia(j, replaced, insert) {
61
+ const inserted = [];
62
+ const collect = (node) => {
63
+ inserted.push(node);
64
+ };
65
+ j.history.snapshot.transaction(() => {
66
+ j.s.focus();
67
+ j.s.setCursorAfter(replaced);
68
+ j.e.on('afterInsertNode', collect);
69
+ try {
70
+ insert();
71
+ }
72
+ finally {
73
+ j.e.off('afterInsertNode', collect);
74
+ }
75
+ const [outer] = inserted;
76
+ if (!Dom.isHTMLElement(outer)) {
77
+ return;
78
+ }
79
+ const old = editedMedia(replaced);
80
+ const media = editedMedia(outer);
81
+ if (old && media) {
82
+ takeOver(j, replaced, old, outer, media);
83
+ }
84
+ // The resizer can have put an embed in its own wrapper already
85
+ const placed = Dom.isHTMLElement(outer.parentElement) &&
86
+ attr(outer.parentElement, 'data-jodit-temp')
87
+ ? outer.parentElement
88
+ : outer;
89
+ // Where the old one was, since media Jodit counts as blocks can be put
90
+ // after the paragraph
91
+ Dom.before(replaced, placed);
92
+ Dom.safeRemove(replaced);
93
+ j.s.setCursorAfter(placed);
94
+ });
95
+ j.synchronizeValues();
96
+ j.e.fire('closeAllPopups');
97
+ }
@@ -0,0 +1,41 @@
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 plugins/video-properties
8
+ */
9
+ import type { IJodit } from "../../../types/index";
10
+ import { UIElement } from "../../../core/ui/element";
11
+ import type { VideoPropertiesAPI, VideoPropertiesState } from "../interface";
12
+ /** @private */
13
+ export declare class UIVideoPropertiesForm extends UIElement<IJodit> {
14
+ private state;
15
+ private handlers;
16
+ className(): string;
17
+ constructor(jodit: IJodit, state: VideoPropertiesState, handlers: VideoPropertiesAPI);
18
+ protected render(): string;
19
+ private input;
20
+ private show;
21
+ /**
22
+ * A video has every field, an embed only its size, and audio only its
23
+ * playback settings
24
+ */
25
+ protected onStateMediaChange(): void;
26
+ private showPreview;
27
+ protected hideChangePoster(): void;
28
+ protected onStatePosterChange(): void;
29
+ protected onPosterChange(): void;
30
+ protected onChangePosterClick(e: MouseEvent): void;
31
+ protected onRemovePosterClick(): void;
32
+ protected onStateSizeIsLockedChange(): void;
33
+ protected onLockSizeClick(): void;
34
+ protected onStateSizeChange(): void;
35
+ protected onSizeInput(e: Event): void;
36
+ /**
37
+ * Autoplay mutes it, and it keeps its controls unless it autoplays
38
+ */
39
+ protected onStateFlagsChange(): void;
40
+ protected onFlagChange(e: Event): void;
41
+ }
@@ -0,0 +1,228 @@
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
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
7
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
9
+ r = Reflect.decorate(decorators, target, key, desc);
10
+ else
11
+ for (var i = decorators.length - 1; i >= 0; i--)
12
+ if (d = decorators[i])
13
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
15
+ };
16
+ import { component } from "../../../core/decorators/component/component.js";
17
+ import { hook } from "../../../core/decorators/hook/hook.js";
18
+ import { watch } from "../../../core/decorators/watch/watch.js";
19
+ import { Dom } from "../../../core/dom/dom.js";
20
+ import { isNumeric } from "../../../core/helpers/checker/is-numeric.js";
21
+ import { attr } from "../../../core/helpers/utils/attr.js";
22
+ import { css } from "../../../core/helpers/utils/css.js";
23
+ import { UIElement } from "../../../core/ui/element.js";
24
+ import { Icon } from "../../../core/ui/icon.js";
25
+ const flags = {
26
+ autoplay: 'Autoplay',
27
+ loop: 'Loop',
28
+ muted: 'Muted',
29
+ controls: 'Controls'
30
+ };
31
+ const checkbox = ([flag, label]) => `<label class="jodit_vertical_middle">
32
+ <input type="checkbox" class="jodit-checkbox &__${flag}"/>
33
+ <span>~${label}~</span>
34
+ </label>`;
35
+ /** @private */
36
+ let UIVideoPropertiesForm = class UIVideoPropertiesForm extends UIElement {
37
+ className() {
38
+ return 'UIVideoPropertiesForm';
39
+ }
40
+ constructor(jodit, state, handlers) {
41
+ super(jodit);
42
+ this.state = state;
43
+ this.handlers = handlers;
44
+ }
45
+ render() {
46
+ return `<form>
47
+ <div class="jodit-form__group &__previewBox">
48
+ <img class="&__preview" alt=""/>
49
+ </div>
50
+ <div class="jodit-form__group &__sizes">
51
+ <input type="text" class="jodit-input &__width" placeholder="~Width~" aria-label="~Width~"/>
52
+ <a class="&__lockSize">*lock*</a>
53
+ <input type="text" class="jodit-input &__height" placeholder="~Height~" aria-label="~Height~"/>
54
+ </div>
55
+ <div class="jodit-form__group &__editPoster">
56
+ <label>~Poster~</label>
57
+ <div class="jodit-input_group">
58
+ <input type="text" class="jodit-input &__poster" placeholder="https://"/>
59
+ <div class="jodit-input_group-buttons">
60
+ <a class="jodit-button &__changePoster" title="~Upload~">*image*</a>
61
+ <a class="jodit-button &__removePoster" title="~Remove~">*bin*</a>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ <div class="jodit-form__group &__playback">
66
+ ${Object.entries(flags).map(checkbox).join('')}
67
+ </div>
68
+ </form>`;
69
+ }
70
+ input(name) {
71
+ return this.getElm(name);
72
+ }
73
+ show(name, shown) {
74
+ css(this.getElm(name), 'display', shown ? null : 'none');
75
+ }
76
+ /**
77
+ * A video has every field, an embed only its size, and audio only its
78
+ * playback settings
79
+ */
80
+ onStateMediaChange() {
81
+ const { media } = this.state;
82
+ this.show('editPoster', Dom.isTag(media, 'video'));
83
+ this.show('sizes', !Dom.isTag(media, 'audio'));
84
+ this.show('playback', !Dom.isTag(media, 'iframe'));
85
+ this.showPreview();
86
+ }
87
+ // A video's poster, when it has one
88
+ showPreview() {
89
+ const { media, values } = this.state;
90
+ const shown = Dom.isTag(media, 'video') && Boolean(values.poster);
91
+ this.show('previewBox', shown);
92
+ attr(this.getElm('preview'), 'src', shown ? values.poster : null);
93
+ }
94
+ hideChangePoster() {
95
+ const { uploader, filebrowser } = this.j.o;
96
+ // What FileSelectorWidget offers
97
+ const canUpload = uploader.showTabInFileSelector !== false &&
98
+ Boolean(uploader.url ||
99
+ uploader.insertImageAsBase64URI ||
100
+ uploader.customUploadFunction);
101
+ const canBrowse = Boolean(filebrowser.ajax.url || filebrowser.items.url);
102
+ this.show('changePoster', canUpload || canBrowse);
103
+ }
104
+ onStatePosterChange() {
105
+ const { poster } = this.state.values;
106
+ this.input('poster').value = poster;
107
+ this.show('removePoster', Boolean(poster));
108
+ this.showPreview();
109
+ }
110
+ onPosterChange() {
111
+ this.state.values.poster = this.input('poster').value;
112
+ }
113
+ onChangePosterClick(e) {
114
+ this.handlers.openPosterPopup(this.getElm('changePoster'));
115
+ e.stopPropagation();
116
+ }
117
+ onRemovePosterClick() {
118
+ this.state.values.poster = '';
119
+ }
120
+ onStateSizeIsLockedChange() {
121
+ this.getElm('lockSize').innerHTML = Icon.get(this.state.sizeIsLocked ? 'lock' : 'unlock');
122
+ }
123
+ onLockSizeClick() {
124
+ const { state } = this;
125
+ const { values } = state;
126
+ state.sizeIsLocked = !state.sizeIsLocked;
127
+ if (state.sizeIsLocked && isNumeric(values.width)) {
128
+ values.height = Math.round(parseFloat(values.width.toString()) / state.ratio);
129
+ }
130
+ }
131
+ onStateSizeChange() {
132
+ const { values } = this.state;
133
+ // Not the field being typed in
134
+ ['width', 'height'].forEach(key => {
135
+ const input = this.input(key);
136
+ if (input !== this.j.od.activeElement) {
137
+ input.value = values[key].toString();
138
+ }
139
+ });
140
+ }
141
+ onSizeInput(e) {
142
+ const { state } = this;
143
+ const { values } = state;
144
+ // Both read first, since setting one rewrites the other's field
145
+ const width = this.input('width').value;
146
+ const height = this.input('height').value;
147
+ if (!state.sizeIsLocked || !isNumeric(width) || !isNumeric(height)) {
148
+ values.width = width;
149
+ values.height = height;
150
+ return;
151
+ }
152
+ const w = parseFloat(width);
153
+ const h = parseFloat(height);
154
+ if (e.target === this.input('width')) {
155
+ values.width = w;
156
+ values.height = Math.round(w / state.ratio);
157
+ }
158
+ else {
159
+ values.width = Math.round(h * state.ratio);
160
+ values.height = h;
161
+ }
162
+ }
163
+ /**
164
+ * Autoplay mutes it, and it keeps its controls unless it autoplays
165
+ */
166
+ onStateFlagsChange() {
167
+ const { values } = this.state;
168
+ this.input('autoplay').checked = values.autoplay;
169
+ this.input('loop').checked = values.loop;
170
+ this.input('muted').checked = values.muted || values.autoplay;
171
+ this.input('muted').disabled = values.autoplay;
172
+ this.input('controls').checked = values.controls || !values.autoplay;
173
+ this.input('controls').disabled = !values.autoplay;
174
+ }
175
+ onFlagChange(e) {
176
+ Object.keys(flags).forEach(flag => {
177
+ const input = this.input(flag);
178
+ if (e.target === input) {
179
+ this.state.values[flag] = input.checked;
180
+ }
181
+ });
182
+ }
183
+ };
184
+ __decorate([
185
+ hook('ready'),
186
+ watch('state.media')
187
+ ], UIVideoPropertiesForm.prototype, "onStateMediaChange", null);
188
+ __decorate([
189
+ hook('ready')
190
+ ], UIVideoPropertiesForm.prototype, "hideChangePoster", null);
191
+ __decorate([
192
+ hook('ready'),
193
+ watch('state.values.poster')
194
+ ], UIVideoPropertiesForm.prototype, "onStatePosterChange", null);
195
+ __decorate([
196
+ watch('poster:change')
197
+ ], UIVideoPropertiesForm.prototype, "onPosterChange", null);
198
+ __decorate([
199
+ watch('changePoster:click')
200
+ ], UIVideoPropertiesForm.prototype, "onChangePosterClick", null);
201
+ __decorate([
202
+ watch('removePoster:click')
203
+ ], UIVideoPropertiesForm.prototype, "onRemovePosterClick", null);
204
+ __decorate([
205
+ hook('ready'),
206
+ watch('state.sizeIsLocked')
207
+ ], UIVideoPropertiesForm.prototype, "onStateSizeIsLockedChange", null);
208
+ __decorate([
209
+ watch('lockSize:click')
210
+ ], UIVideoPropertiesForm.prototype, "onLockSizeClick", null);
211
+ __decorate([
212
+ hook('ready'),
213
+ watch(['state.values.width', 'state.values.height'])
214
+ ], UIVideoPropertiesForm.prototype, "onStateSizeChange", null);
215
+ __decorate([
216
+ watch(['width:input', 'height:input', 'width:change', 'height:change'])
217
+ ], UIVideoPropertiesForm.prototype, "onSizeInput", null);
218
+ __decorate([
219
+ hook('ready'),
220
+ watch(Object.keys(flags).map(flag => `state.values.${flag}`))
221
+ ], UIVideoPropertiesForm.prototype, "onStateFlagsChange", null);
222
+ __decorate([
223
+ watch(Object.keys(flags).map(flag => `${flag}:change`))
224
+ ], UIVideoPropertiesForm.prototype, "onFlagChange", null);
225
+ UIVideoPropertiesForm = __decorate([
226
+ component
227
+ ], UIVideoPropertiesForm);
228
+ export { UIVideoPropertiesForm };
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * Released under MIT see LICENSE.txt in the project root for license information.
4
+ * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ import { Plugin } from "../../core/plugin/plugin";
7
+ import type { VideoPropertiesState } from "./interface";
8
+ /**
9
+ * Show a dialog with the size, poster and playback settings of a video, an
10
+ * embed or audio. The media popup's Edit button opens it:
11
+ *
12
+ * ```javascript
13
+ * editor.events.fire('openVideoProperties', video);
14
+ * ```
15
+ */
16
+ export declare class videoProperties extends Plugin {
17
+ protected state: VideoPropertiesState;
18
+ private __readSize;
19
+ private get __size();
20
+ private get form();
21
+ private get dialog();
22
+ private get __buttons();
23
+ /**
24
+ * Open the dialog for the media `target` is, or is the wrapper of
25
+ */
26
+ protected open(target: HTMLElement): void;
27
+ /**
28
+ * The video popup's tabs for the media popup's Replace: what they insert
29
+ * takes the place of the media `target` is, or is the wrapper of
30
+ */
31
+ protected onGenerateReplaceVideoTabs(target: HTMLElement, close: () => void): HTMLElement;
32
+ private __openPosterPopup;
33
+ /** @override */
34
+ protected afterInit(): void;
35
+ /** @override */
36
+ protected beforeDestruct(): void;
37
+ }