jodit 4.18.2 → 4.18.4
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 +41 -0
- package/es2015/jodit.css +66 -6
- package/es2015/jodit.fat.min.css +1 -1
- package/es2015/jodit.fat.min.js +36 -11
- package/es2015/jodit.js +1435 -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 +36 -11
- package/es2018/jodit.min.css +1 -1
- package/es2018/jodit.min.js +36 -11
- package/es2018/plugins/debug/debug.min.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021/jodit.css +66 -6
- package/es2021/jodit.fat.min.css +1 -1
- package/es2021/jodit.fat.min.js +45 -20
- package/es2021/jodit.js +1365 -271
- package/es2021/jodit.min.css +1 -1
- package/es2021/jodit.min.js +45 -20
- 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 +66 -6
- package/es2021.en/jodit.fat.min.css +1 -1
- package/es2021.en/jodit.fat.min.js +51 -26
- package/es2021.en/jodit.js +1339 -245
- 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 +82 -7
- package/es5/jodit.fat.min.css +1 -1
- package/es5/jodit.fat.min.js +2 -2
- package/es5/jodit.js +1629 -354
- 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 +29 -28
- package/esm/config.js +19 -21
- package/esm/core/constants.js +1 -1
- package/esm/core/helpers/utils/align.d.ts +1 -1
- package/esm/core/helpers/utils/align.js +2 -3
- package/esm/core/helpers/utils/index.d.ts +1 -0
- package/esm/core/helpers/utils/index.js +1 -0
- package/esm/core/helpers/utils/prepare-media.d.ts +19 -0
- package/esm/core/helpers/utils/prepare-media.js +31 -0
- package/esm/core/selection/style/api/wrap-unwrapped-text.js +3 -2
- package/esm/jodit.js +14 -4
- package/esm/langs/ar.d.ts +7 -0
- package/esm/langs/ar.js +8 -1
- package/esm/langs/az.d.ts +7 -0
- package/esm/langs/az.js +8 -1
- package/esm/langs/cs_cz.d.ts +7 -0
- package/esm/langs/cs_cz.js +9 -1
- package/esm/langs/de.d.ts +7 -0
- package/esm/langs/de.js +8 -1
- package/esm/langs/es.d.ts +7 -0
- package/esm/langs/es.js +8 -1
- package/esm/langs/fa.d.ts +7 -0
- package/esm/langs/fa.js +8 -1
- package/esm/langs/fi.d.ts +7 -0
- package/esm/langs/fi.js +8 -1
- package/esm/langs/fr.d.ts +7 -0
- package/esm/langs/fr.js +8 -1
- package/esm/langs/he.d.ts +7 -0
- package/esm/langs/he.js +8 -1
- package/esm/langs/hu.d.ts +7 -0
- package/esm/langs/hu.js +8 -1
- package/esm/langs/id.d.ts +7 -0
- package/esm/langs/id.js +8 -1
- package/esm/langs/it.d.ts +7 -0
- package/esm/langs/it.js +8 -1
- package/esm/langs/ja.d.ts +7 -0
- package/esm/langs/ja.js +8 -1
- package/esm/langs/ko.d.ts +7 -0
- package/esm/langs/ko.js +8 -1
- package/esm/langs/mn.d.ts +7 -0
- package/esm/langs/mn.js +8 -1
- package/esm/langs/nl.d.ts +7 -0
- package/esm/langs/nl.js +8 -1
- package/esm/langs/no.d.ts +7 -0
- package/esm/langs/no.js +8 -1
- package/esm/langs/pl.d.ts +7 -0
- package/esm/langs/pl.js +8 -1
- package/esm/langs/pt_br.d.ts +7 -0
- package/esm/langs/pt_br.js +8 -1
- package/esm/langs/ru.d.ts +7 -0
- package/esm/langs/ru.js +8 -1
- package/esm/langs/sk.d.ts +7 -0
- package/esm/langs/sk.js +8 -1
- package/esm/langs/sv.d.ts +7 -0
- package/esm/langs/sv.js +8 -1
- package/esm/langs/tr.d.ts +7 -0
- package/esm/langs/tr.js +8 -1
- package/esm/langs/ua.d.ts +7 -0
- package/esm/langs/ua.js +8 -1
- package/esm/langs/zh_cn.d.ts +7 -0
- package/esm/langs/zh_cn.js +8 -1
- package/esm/langs/zh_tw.d.ts +7 -0
- package/esm/langs/zh_tw.js +8 -1
- package/esm/modules/history/history.d.ts +17 -2
- package/esm/modules/history/history.js +41 -19
- package/esm/modules/table/table.js +7 -2
- package/esm/modules/widget/file-selector/file-selector.js +2 -2
- package/esm/plugins/all.d.ts +1 -0
- package/esm/plugins/all.js +1 -0
- package/esm/plugins/backspace/backspace.js +4 -0
- package/esm/plugins/clean-html/clean-html.d.ts +7 -0
- package/esm/plugins/clean-html/clean-html.js +17 -0
- package/esm/plugins/clean-html/helpers/visitor/filters/replace-old-tags.js +26 -1
- package/esm/plugins/dtd/before-insert/check-block-nesting.d.ts +2 -1
- package/esm/plugins/dtd/before-insert/check-block-nesting.js +26 -5
- package/esm/plugins/enter/helpers/move-cursor-out-from-specal-tags.js +8 -0
- package/esm/plugins/focus/focus.js +3 -0
- package/esm/plugins/hr/hr.js +21 -5
- package/esm/plugins/iframe/config.js +8 -3
- package/esm/plugins/image-processor/image-processor.d.ts +4 -1
- package/esm/plugins/image-processor/image-processor.js +9 -3
- 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 +5 -0
- package/esm/plugins/inline-popup/inline-popup.js +26 -2
- package/esm/plugins/link/link.js +5 -2
- package/esm/plugins/media/config.d.ts +2 -1
- package/esm/plugins/media/media.js +37 -9
- package/esm/plugins/paste/helpers.d.ts +8 -0
- package/esm/plugins/paste/helpers.js +18 -1
- package/esm/plugins/paste/paste.js +2 -2
- package/esm/plugins/resizer/config.d.ts +5 -3
- package/esm/plugins/resizer/config.js +8 -2
- package/esm/plugins/resizer/resizer.d.ts +10 -0
- package/esm/plugins/resizer/resizer.js +72 -18
- package/esm/plugins/select-cells/select-cells.d.ts +10 -0
- package/esm/plugins/select-cells/select-cells.js +54 -6
- package/esm/plugins/table/config.js +51 -1
- package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +1 -1
- package/esm/plugins/video/config.d.ts +6 -0
- package/esm/plugins/video/config.js +78 -82
- 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 +29 -28
- package/types/core/helpers/utils/align.d.ts +1 -1
- package/types/core/helpers/utils/index.d.ts +1 -0
- package/types/core/helpers/utils/prepare-media.d.ts +19 -0
- package/types/langs/ar.d.ts +7 -0
- package/types/langs/az.d.ts +7 -0
- package/types/langs/cs_cz.d.ts +7 -0
- package/types/langs/de.d.ts +7 -0
- package/types/langs/es.d.ts +7 -0
- package/types/langs/fa.d.ts +7 -0
- package/types/langs/fi.d.ts +7 -0
- package/types/langs/fr.d.ts +7 -0
- package/types/langs/he.d.ts +7 -0
- package/types/langs/hu.d.ts +7 -0
- package/types/langs/id.d.ts +7 -0
- package/types/langs/it.d.ts +7 -0
- package/types/langs/ja.d.ts +7 -0
- package/types/langs/ko.d.ts +7 -0
- package/types/langs/mn.d.ts +7 -0
- package/types/langs/nl.d.ts +7 -0
- package/types/langs/no.d.ts +7 -0
- package/types/langs/pl.d.ts +7 -0
- package/types/langs/pt_br.d.ts +7 -0
- package/types/langs/ru.d.ts +7 -0
- package/types/langs/sk.d.ts +7 -0
- package/types/langs/sv.d.ts +7 -0
- package/types/langs/tr.d.ts +7 -0
- package/types/langs/ua.d.ts +7 -0
- package/types/langs/zh_cn.d.ts +7 -0
- package/types/langs/zh_tw.d.ts +7 -0
- package/types/modules/history/history.d.ts +17 -2
- package/types/plugins/clean-html/clean-html.d.ts +7 -0
- package/types/plugins/dtd/before-insert/check-block-nesting.d.ts +2 -1
- 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 +5 -0
- package/types/plugins/media/config.d.ts +2 -1
- package/types/plugins/paste/helpers.d.ts +8 -0
- package/types/plugins/resizer/config.d.ts +5 -3
- package/types/plugins/resizer/resizer.d.ts +10 -0
- package/types/plugins/select-cells/select-cells.d.ts +10 -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
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
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 { cache, cached, watch } from "../../core/decorators/index.js";
|
|
17
|
+
import { Dom } from "../../core/dom/dom.js";
|
|
18
|
+
import { pluginSystem } from "../../core/global.js";
|
|
19
|
+
import { isArray } from "../../core/helpers/checker/is-array.js";
|
|
20
|
+
import { position } from "../../core/helpers/size/position.js";
|
|
21
|
+
import { markOwner } from "../../core/helpers/utils/utils.js";
|
|
22
|
+
import { Plugin } from "../../core/plugin/plugin.js";
|
|
23
|
+
import { Button } from "../../core/ui/button/index.js";
|
|
24
|
+
import { Popup } from "../../core/ui/popup/popup.js";
|
|
25
|
+
import { FileSelectorWidget } from "../../modules/widget/file-selector/file-selector.js";
|
|
26
|
+
import { UIVideoPropertiesForm } from "./ui/ui-video-form.js";
|
|
27
|
+
import { editedMedia, readValues } from "./readers.js";
|
|
28
|
+
import { replaceMedia } from "./replace.js";
|
|
29
|
+
import { applyValues } from "./writers.js";
|
|
30
|
+
import { videoTabs } from "../video/config.js";
|
|
31
|
+
/**
|
|
32
|
+
* Show a dialog with the size, poster and playback settings of a video, an
|
|
33
|
+
* embed or audio. The media popup's Edit button opens it:
|
|
34
|
+
*
|
|
35
|
+
* ```javascript
|
|
36
|
+
* editor.events.fire('openVideoProperties', video);
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class videoProperties extends Plugin {
|
|
40
|
+
constructor() {
|
|
41
|
+
super(...arguments);
|
|
42
|
+
this.state = {
|
|
43
|
+
target: this.j.c.element('video'),
|
|
44
|
+
media: this.j.c.element('video'),
|
|
45
|
+
ratio: 1,
|
|
46
|
+
sizeIsLocked: true,
|
|
47
|
+
values: {
|
|
48
|
+
width: '',
|
|
49
|
+
height: '',
|
|
50
|
+
poster: '',
|
|
51
|
+
autoplay: false,
|
|
52
|
+
loop: false,
|
|
53
|
+
muted: false,
|
|
54
|
+
controls: true
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// The size as it was read, so an unchanged one isn't written
|
|
58
|
+
this.__readSize = '';
|
|
59
|
+
}
|
|
60
|
+
get __size() {
|
|
61
|
+
const { width, height } = this.state.values;
|
|
62
|
+
return `${width}x${height}`;
|
|
63
|
+
}
|
|
64
|
+
get form() {
|
|
65
|
+
return new UIVideoPropertiesForm(this.j, this.state, {
|
|
66
|
+
openPosterPopup: target => this.__openPosterPopup(target)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
get dialog() {
|
|
70
|
+
const { j } = this;
|
|
71
|
+
const dialog = j.dlg({
|
|
72
|
+
minWidth: Math.min(400, screen.width),
|
|
73
|
+
buttons: ['dialog.close']
|
|
74
|
+
});
|
|
75
|
+
const buttons = this.__buttons;
|
|
76
|
+
buttons.check.onAction(() => {
|
|
77
|
+
applyValues(j, this.state, this.__size !== this.__readSize);
|
|
78
|
+
j.synchronizeValues();
|
|
79
|
+
dialog.close();
|
|
80
|
+
});
|
|
81
|
+
buttons.remove.onAction(() => {
|
|
82
|
+
j.s.removeNode(this.state.target);
|
|
83
|
+
dialog.close();
|
|
84
|
+
});
|
|
85
|
+
buttons.cancel.onAction(() => {
|
|
86
|
+
dialog.close();
|
|
87
|
+
});
|
|
88
|
+
dialog.setContent(this.form);
|
|
89
|
+
dialog.setFooter([[buttons.cancel, buttons.remove], buttons.check]);
|
|
90
|
+
markOwner(j, dialog.container);
|
|
91
|
+
return dialog;
|
|
92
|
+
}
|
|
93
|
+
get __buttons() {
|
|
94
|
+
const { j } = this;
|
|
95
|
+
return {
|
|
96
|
+
check: Button(j, 'ok', 'Apply', 'primary'),
|
|
97
|
+
remove: Button(j, 'bin', 'Delete'),
|
|
98
|
+
cancel: Button(j, 'cancel', 'Cancel')
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Open the dialog for the media `target` is, or is the wrapper of
|
|
103
|
+
*/
|
|
104
|
+
open(target) {
|
|
105
|
+
const media = editedMedia(target);
|
|
106
|
+
if (!media) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.state.target = target;
|
|
110
|
+
this.state.media = media;
|
|
111
|
+
readValues(this.state);
|
|
112
|
+
this.__readSize = this.__size;
|
|
113
|
+
this.dialog.setHeader(this.j.i18n(Dom.isTag(media, 'audio')
|
|
114
|
+
? 'Audio properties'
|
|
115
|
+
: 'Video properties'));
|
|
116
|
+
this.dialog.open().setModal(true).setPosition();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The video popup's tabs for the media popup's Replace: what they insert
|
|
120
|
+
* takes the place of the media `target` is, or is the wrapper of
|
|
121
|
+
*/
|
|
122
|
+
onGenerateReplaceVideoTabs(target, close) {
|
|
123
|
+
return videoTabs(this.j, close, insert => replaceMedia(this.j, target, insert));
|
|
124
|
+
}
|
|
125
|
+
__openPosterPopup(button) {
|
|
126
|
+
const { j, state } = this;
|
|
127
|
+
const popup = new Popup(this.dialog);
|
|
128
|
+
const close = () => {
|
|
129
|
+
popup.close();
|
|
130
|
+
popup.destruct();
|
|
131
|
+
};
|
|
132
|
+
popup
|
|
133
|
+
.setContent(FileSelectorWidget(j, {
|
|
134
|
+
upload: (data) => {
|
|
135
|
+
if (data.files && data.files.length) {
|
|
136
|
+
state.values.poster =
|
|
137
|
+
data.baseurl + data.files[0];
|
|
138
|
+
}
|
|
139
|
+
close();
|
|
140
|
+
},
|
|
141
|
+
filebrowser: (data) => {
|
|
142
|
+
if (isArray(data.files) && data.files.length) {
|
|
143
|
+
state.values.poster = data.files[0];
|
|
144
|
+
close();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}, null, close))
|
|
148
|
+
.open(() => position(button));
|
|
149
|
+
}
|
|
150
|
+
/** @override */
|
|
151
|
+
afterInit() { }
|
|
152
|
+
/** @override */
|
|
153
|
+
beforeDestruct() {
|
|
154
|
+
var _a, _b, _c;
|
|
155
|
+
Object.values((_a = cached(this, '__buttons')) !== null && _a !== void 0 ? _a : {}).forEach(b => b.destruct());
|
|
156
|
+
(_b = cached(this, 'dialog')) === null || _b === void 0 ? void 0 : _b.destruct();
|
|
157
|
+
(_c = cached(this, 'form')) === null || _c === void 0 ? void 0 : _c.destruct();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
__decorate([
|
|
161
|
+
cache
|
|
162
|
+
], videoProperties.prototype, "form", null);
|
|
163
|
+
__decorate([
|
|
164
|
+
cache
|
|
165
|
+
], videoProperties.prototype, "dialog", null);
|
|
166
|
+
__decorate([
|
|
167
|
+
cache
|
|
168
|
+
], videoProperties.prototype, "__buttons", null);
|
|
169
|
+
__decorate([
|
|
170
|
+
watch(':openVideoProperties')
|
|
171
|
+
], videoProperties.prototype, "open", null);
|
|
172
|
+
__decorate([
|
|
173
|
+
watch(':generateReplaceVideoTabs')
|
|
174
|
+
], videoProperties.prototype, "onGenerateReplaceVideoTabs", null);
|
|
175
|
+
pluginSystem.add('videoProperties', videoProperties);
|
|
@@ -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
|
+
import type { VideoPropertiesState } from "./interface";
|
|
11
|
+
/**
|
|
12
|
+
* Apply the dialog's values to the media
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyValues(j: IJodit, state: VideoPropertiesState, sizeChanged: boolean): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
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, cssInline } from "../../core/helpers/utils/css.js";
|
|
9
|
+
import { ownSize } from "./readers.js";
|
|
10
|
+
import { normalSizeToString } from "../image-properties/utils/utils.js";
|
|
11
|
+
const cssSize = (value) => value === '' ? null : normalSizeToString(value);
|
|
12
|
+
// Sizes go on as the resizer writes them: an embed takes them as attributes,
|
|
13
|
+
// and a video as CSS, without a height while its ratio is kept, if it had none
|
|
14
|
+
function applySize(j, state) {
|
|
15
|
+
var _a;
|
|
16
|
+
const { media, values } = state;
|
|
17
|
+
if (Dom.isTag(media, 'iframe')) {
|
|
18
|
+
['width', 'height'].forEach(key => {
|
|
19
|
+
attr(media, key, values[key] === '' ? null : values[key]);
|
|
20
|
+
if (cssInline(media, key)) {
|
|
21
|
+
css(media, key, cssSize(values[key]));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
// The resizer's frame for an embed
|
|
25
|
+
const wrapper = media.parentElement;
|
|
26
|
+
if (wrapper && attr(wrapper, 'data-jodit_iframe_wrapper')) {
|
|
27
|
+
css(wrapper, {
|
|
28
|
+
width: media.offsetWidth,
|
|
29
|
+
height: media.offsetHeight
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const heightFollowsWidth = state.sizeIsLocked && !ownSize(media, 'height');
|
|
35
|
+
css(media, {
|
|
36
|
+
width: cssSize(values.width),
|
|
37
|
+
height: heightFollowsWidth ? null : cssSize(values.height)
|
|
38
|
+
});
|
|
39
|
+
if (!((_a = attr(media, 'style')) === null || _a === void 0 ? void 0 : _a.trim())) {
|
|
40
|
+
attr(media, 'style', null);
|
|
41
|
+
}
|
|
42
|
+
j.e.fire(media, 'changesize');
|
|
43
|
+
}
|
|
44
|
+
function setFlag(media, name, on) {
|
|
45
|
+
if (media.hasAttribute(name) !== on) {
|
|
46
|
+
attr(media, name, on ? '' : null);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Apply the dialog's values to the media
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
export function applyValues(j, state, sizeChanged) {
|
|
54
|
+
const { media, values } = state;
|
|
55
|
+
if (sizeChanged && !Dom.isTag(media, 'audio')) {
|
|
56
|
+
applySize(j, state);
|
|
57
|
+
}
|
|
58
|
+
if (Dom.isTag(media, 'iframe')) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (Dom.isTag(media, 'video')) {
|
|
62
|
+
attr(media, 'poster', values.poster || null);
|
|
63
|
+
}
|
|
64
|
+
// Browsers only autoplay muted media, and playsinline keeps an iPhone from
|
|
65
|
+
// playing it full screen
|
|
66
|
+
setFlag(media, 'autoplay', values.autoplay);
|
|
67
|
+
setFlag(media, 'muted', values.autoplay || values.muted);
|
|
68
|
+
setFlag(media, 'loop', values.loop);
|
|
69
|
+
setFlag(media, 'controls', values.controls || !values.autoplay);
|
|
70
|
+
if (values.autoplay && Dom.isTag(media, 'video')) {
|
|
71
|
+
setFlag(media, 'playsinline', true);
|
|
72
|
+
}
|
|
73
|
+
}
|
package/esm/types/types.d.ts
CHANGED
|
@@ -193,7 +193,7 @@ export type ImageHAlign = 'normal' | 'left' | 'right' | 'center' | '';
|
|
|
193
193
|
*/
|
|
194
194
|
export type HAlignClasses = Partial<Record<Exclude<ImageHAlign, ''>, string | string[]>>;
|
|
195
195
|
/**
|
|
196
|
-
*
|
|
196
|
+
* @deprecated Use `HAlignClasses`
|
|
197
197
|
*/
|
|
198
198
|
export type ImageAlignClasses = HAlignClasses;
|
|
199
199
|
/**
|
package/package.json
CHANGED
package/types/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
|
*/
|
|
@@ -989,7 +986,8 @@ interface Config {
|
|
|
989
986
|
*/
|
|
990
987
|
maxHistoryLength: number;
|
|
991
988
|
/**
|
|
992
|
-
*
|
|
989
|
+
* How long a step stays open after its first change, in
|
|
990
|
+
* milliseconds. The changes made in that time are undone together.
|
|
993
991
|
*/
|
|
994
992
|
timeout: number;
|
|
995
993
|
};
|
|
@@ -1597,7 +1595,8 @@ interface Config {
|
|
|
1597
1595
|
* - is wrapped in it instead of the editor-only `mediaFakeTag` when its tag
|
|
1598
1596
|
* is one of `mediaBlocks`, or left in it when it's already in one
|
|
1599
1597
|
* - goes in inside it when the video popup inserts it, as an upload, a
|
|
1600
|
-
* link's embed or embed code that is one element
|
|
1598
|
+
* link's embed or embed code that is one element, and when a pasted
|
|
1599
|
+
* video link is turned into its embed
|
|
1601
1600
|
* - opens the media popup for its wrapper when clicked, whose Align and
|
|
1602
1601
|
* Delete act on the wrapper
|
|
1603
1602
|
*
|
|
@@ -1757,7 +1756,7 @@ interface Config {
|
|
|
1757
1756
|
}
|
|
1758
1757
|
interface Config {
|
|
1759
1758
|
/**
|
|
1760
|
-
* Set of HTML tag names whose elements can be resized by the user via drag handles (e.g. images, iframes, tables)
|
|
1759
|
+
* Set of HTML tag names whose elements can be resized by the user via drag handles (e.g. images, iframes, tables, videos)
|
|
1761
1760
|
*/
|
|
1762
1761
|
allowResizeTags: Set<HTMLTagNames>;
|
|
1763
1762
|
resizer: {
|
|
@@ -1770,14 +1769,16 @@ interface Config {
|
|
|
1770
1769
|
* Save width and height proportions when resizing
|
|
1771
1770
|
* ```js
|
|
1772
1771
|
* Jodit.make('#editor', {
|
|
1773
|
-
* allowResizeTags: ['img', 'iframe', 'table', 'jodit'],
|
|
1772
|
+
* allowResizeTags: new Set(['img', 'iframe', 'table', 'jodit', 'video']),
|
|
1774
1773
|
* resizer: {
|
|
1775
1774
|
* useAspectRatio: false, // don't save,
|
|
1776
|
-
* useAspectRatio: ['img'], // save only for images
|
|
1775
|
+
* useAspectRatio: new Set(['img']), // save only for images
|
|
1777
1776
|
* useAspectRatio: true // save for all
|
|
1778
1777
|
* }
|
|
1779
1778
|
* });
|
|
1780
1779
|
* ```
|
|
1780
|
+
* Images and videos keep it by default. A video with no height of its
|
|
1781
|
+
* own keeps it by being given only a width.
|
|
1781
1782
|
*/
|
|
1782
1783
|
useAspectRatio: boolean | Set<HTMLTagNames>;
|
|
1783
1784
|
/**
|
|
@@ -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
|
/**
|