jodit 4.1.16 → 4.2.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 +22 -5
- package/es2015/jodit.css +82 -31
- package/es2015/jodit.fat.min.css +1 -1
- package/es2015/jodit.fat.min.js +2 -2
- package/es2015/jodit.js +1378 -546
- package/es2015/jodit.min.css +1 -1
- package/es2015/jodit.min.js +2 -2
- 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.css +82 -31
- package/es2018/jodit.fat.min.css +1 -1
- package/es2018/jodit.fat.min.js +2 -2
- package/es2018/jodit.js +1364 -546
- package/es2018/jodit.min.css +1 -1
- package/es2018/jodit.min.js +2 -2
- package/es2018/plugins/debug/debug.js +1 -1
- package/es2018/plugins/debug/debug.min.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021/jodit.css +82 -31
- package/es2021/jodit.fat.min.css +1 -1
- package/es2021/jodit.fat.min.js +2 -2
- package/es2021/jodit.js +1361 -546
- package/es2021/jodit.min.css +1 -1
- package/es2021/jodit.min.js +2 -2
- 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 +82 -31
- package/es2021.en/jodit.fat.min.css +1 -1
- package/es2021.en/jodit.fat.min.js +2 -2
- package/es2021.en/jodit.js +1361 -546
- package/es2021.en/jodit.min.css +1 -1
- package/es2021.en/jodit.min.js +2 -2
- 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 +131 -35
- package/es5/jodit.fat.min.css +1 -1
- package/es5/jodit.fat.min.js +2 -2
- package/es5/jodit.js +1402 -482
- package/es5/jodit.min.css +3 -3
- package/es5/jodit.min.js +2 -2
- 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/esm/config.d.ts +22 -0
- package/esm/config.js +22 -0
- package/esm/core/async/async.js +7 -1
- package/esm/core/constants.js +1 -1
- package/esm/core/helpers/size/position.js +2 -2
- package/esm/core/helpers/utils/selector.d.ts +3 -1
- package/esm/core/helpers/utils/selector.js +3 -3
- package/esm/core/ui/button/tooltip/tooltip.js +2 -1
- package/esm/core/ui/popup/popup.js +1 -1
- package/esm/modules/dialog/dialog.js +1 -0
- package/esm/modules/file-browser/data-provider.js +4 -1
- package/esm/modules/file-browser/file-browser.js +9 -2
- package/esm/modules/image-editor/templates/form.js +6 -5
- package/esm/modules/toolbar/button/button.d.ts +1 -1
- package/esm/modules/widget/tabs/tabs.d.ts +4 -4
- package/esm/modules/widget/tabs/tabs.js +9 -7
- package/esm/plugins/ai-assistant/ai-assistant.d.ts +1 -1
- package/esm/plugins/ai-assistant/ai-assistant.js +3 -3
- package/esm/plugins/image-properties/config.d.ts +5 -83
- package/esm/plugins/image-properties/config.js +0 -3
- package/esm/plugins/image-properties/image-properties.d.ts +22 -32
- package/esm/plugins/image-properties/image-properties.js +133 -402
- package/{types/plugins/image-properties/templates/form.d.ts → esm/plugins/image-properties/readers/align.d.ts} +3 -5
- package/esm/plugins/image-properties/readers/align.js +24 -0
- package/esm/plugins/image-properties/readers/index.d.ts +12 -0
- package/esm/plugins/image-properties/readers/index.js +38 -0
- package/esm/plugins/image-properties/readers/link.d.ts +9 -0
- package/esm/plugins/image-properties/readers/link.js +19 -0
- package/esm/plugins/image-properties/readers/margin.d.ts +8 -0
- package/esm/plugins/image-properties/readers/margin.js +28 -0
- package/esm/plugins/image-properties/readers/size.d.ts +8 -0
- package/esm/plugins/image-properties/readers/size.js +36 -0
- package/esm/plugins/image-properties/ui/ui-image-form.d.ts +29 -0
- package/esm/plugins/image-properties/ui/ui-image-form.js +171 -0
- package/esm/plugins/image-properties/ui/ui-image-main-tab.d.ts +36 -0
- package/esm/plugins/image-properties/ui/ui-image-main-tab.js +179 -0
- package/esm/plugins/image-properties/ui/ui-image-position-tab.d.ts +36 -0
- package/esm/plugins/image-properties/ui/ui-image-position-tab.js +261 -0
- package/esm/plugins/image-properties/{templates/main-tab.d.ts → utils/open-image-editor.d.ts} +5 -3
- package/esm/plugins/image-properties/utils/open-image-editor.js +52 -0
- package/esm/plugins/image-properties/utils/open-image-popup.d.ts +9 -0
- package/esm/plugins/image-properties/utils/open-image-popup.js +34 -0
- package/esm/plugins/image-properties/utils/utils.d.ts +9 -0
- package/esm/plugins/image-properties/utils/utils.js +21 -0
- package/esm/plugins/image-properties/writers/index.d.ts +12 -0
- package/esm/plugins/image-properties/writers/index.js +53 -0
- package/esm/plugins/image-properties/{templates/form.d.ts → writers/link.d.ts} +2 -4
- package/esm/plugins/image-properties/writers/link.js +24 -0
- package/esm/plugins/image-properties/writers/margin.d.ts +8 -0
- package/esm/plugins/image-properties/writers/margin.js +33 -0
- package/esm/plugins/image-properties/writers/size.d.ts +7 -0
- package/esm/plugins/image-properties/writers/size.js +28 -0
- package/esm/plugins/select/config.d.ts +7 -0
- package/esm/plugins/select/config.js +2 -1
- package/esm/plugins/select/select.d.ts +7 -3
- package/esm/plugins/select/select.js +21 -4
- package/esm/types/ui.d.ts +1 -1
- package/package.json +1 -1
- package/types/config.d.ts +22 -0
- package/types/core/helpers/utils/selector.d.ts +3 -1
- package/types/modules/toolbar/button/button.d.ts +1 -1
- package/types/modules/widget/tabs/tabs.d.ts +4 -4
- package/types/plugins/ai-assistant/ai-assistant.d.ts +1 -1
- package/types/plugins/image-properties/config.d.ts +5 -83
- package/types/plugins/image-properties/image-properties.d.ts +22 -32
- package/types/plugins/image-properties/{templates/main-tab.d.ts → readers/align.d.ts} +3 -5
- package/types/plugins/image-properties/readers/index.d.ts +12 -0
- package/types/plugins/image-properties/readers/link.d.ts +9 -0
- package/types/plugins/image-properties/readers/margin.d.ts +8 -0
- package/types/plugins/image-properties/readers/size.d.ts +8 -0
- package/types/plugins/image-properties/ui/ui-image-form.d.ts +29 -0
- package/types/plugins/image-properties/ui/ui-image-main-tab.d.ts +36 -0
- package/types/plugins/image-properties/ui/ui-image-position-tab.d.ts +36 -0
- package/types/plugins/image-properties/utils/open-image-editor.d.ts +12 -0
- package/types/plugins/image-properties/utils/open-image-popup.d.ts +9 -0
- package/types/plugins/image-properties/utils/utils.d.ts +9 -0
- package/types/plugins/image-properties/writers/index.d.ts +12 -0
- package/{esm/plugins/image-properties/templates/position-tab.d.ts → types/plugins/image-properties/writers/link.d.ts} +2 -4
- package/types/plugins/image-properties/writers/margin.d.ts +8 -0
- package/types/plugins/image-properties/writers/size.d.ts +7 -0
- package/types/plugins/select/config.d.ts +7 -0
- package/types/plugins/select/select.d.ts +7 -3
- package/types/types/ui.d.ts +1 -1
- package/esm/plugins/image-properties/templates/form.js +0 -26
- package/esm/plugins/image-properties/templates/main-tab.js +0 -47
- package/esm/plugins/image-properties/templates/position-tab.js +0 -66
- package/types/plugins/image-properties/templates/position-tab.d.ts +0 -10
|
@@ -13,17 +13,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
13
13
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
14
14
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
15
|
};
|
|
16
|
-
import {
|
|
16
|
+
import { cache, cached, watch } from "jodit/esm/core/decorators/index.js";
|
|
17
|
+
import { Dom } from "jodit/esm/core/dom/dom.js";
|
|
17
18
|
import { pluginSystem } from "jodit/esm/core/global.js";
|
|
18
|
-
import {
|
|
19
|
+
import { isAbortError, isNumeric, markOwner } from "jodit/esm/core/helpers/index.js";
|
|
20
|
+
import { Plugin } from "jodit/esm/core/plugin/plugin.js";
|
|
19
21
|
import { Button } from "jodit/esm/core/ui/button/index.js";
|
|
20
|
-
import { Dom, Icon, Plugin, Popup } from "jodit/esm/modules/index.js";
|
|
21
|
-
import { openImageEditor } from "jodit/esm/modules/image-editor/image-editor.js";
|
|
22
|
-
import { FileSelectorWidget, TabsWidget } from "jodit/esm/modules/widget/index.js";
|
|
23
22
|
import "./config";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
23
|
+
import { UIImagePropertiesForm } from "./ui/ui-image-form";
|
|
24
|
+
import { openImageEditorDialog } from "./utils/open-image-editor";
|
|
25
|
+
import { openImagePopup } from "./utils/open-image-popup";
|
|
26
|
+
import { readValuesFromImage } from "./readers";
|
|
27
|
+
import { applyValuesToImage } from "./writers";
|
|
27
28
|
/**
|
|
28
29
|
* Plug-in for image editing window
|
|
29
30
|
*
|
|
@@ -37,15 +38,6 @@ import { positionTab } from "./templates/position-tab";
|
|
|
37
38
|
* });
|
|
38
39
|
* ```
|
|
39
40
|
*/
|
|
40
|
-
const normalSizeToString = (value) => {
|
|
41
|
-
value = trim(value);
|
|
42
|
-
return /^[0-9]+$/.test(value) ? value + 'px' : value;
|
|
43
|
-
};
|
|
44
|
-
const normalSizeFromString = (value) => {
|
|
45
|
-
return /^[-+]?[0-9.]+px$/.test(value.toString())
|
|
46
|
-
? parseFloat(value.toString())
|
|
47
|
-
: value;
|
|
48
|
-
};
|
|
49
41
|
/**
|
|
50
42
|
* Show dialog with image's options
|
|
51
43
|
*/
|
|
@@ -54,406 +46,123 @@ export class imageProperties extends Plugin {
|
|
|
54
46
|
super(...arguments);
|
|
55
47
|
this.state = {
|
|
56
48
|
image: new Image(),
|
|
49
|
+
sourceImage: new Image(),
|
|
57
50
|
get ratio() {
|
|
58
|
-
|
|
51
|
+
const { naturalWidth, naturalHeight } = this.image;
|
|
52
|
+
return naturalWidth / naturalHeight || 1;
|
|
59
53
|
},
|
|
60
54
|
sizeIsLocked: true,
|
|
61
|
-
marginIsLocked: true
|
|
55
|
+
marginIsLocked: true,
|
|
56
|
+
values: {
|
|
57
|
+
style: '',
|
|
58
|
+
imageSrc: '',
|
|
59
|
+
borderRadius: 0,
|
|
60
|
+
imageTitle: '',
|
|
61
|
+
imageAlt: '',
|
|
62
|
+
imageLink: '',
|
|
63
|
+
imageLinkOpenInNewTab: false,
|
|
64
|
+
imageWidth: 0,
|
|
65
|
+
imageHeight: 0,
|
|
66
|
+
marginTop: 0,
|
|
67
|
+
marginRight: 0,
|
|
68
|
+
marginBottom: 0,
|
|
69
|
+
marginLeft: 0,
|
|
70
|
+
classes: '',
|
|
71
|
+
id: '',
|
|
72
|
+
align: ''
|
|
73
|
+
}
|
|
62
74
|
};
|
|
63
75
|
this.activeTabState = {
|
|
64
|
-
|
|
76
|
+
activeTab: 'Image'
|
|
65
77
|
};
|
|
66
78
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const { marginRight, marginBottom, marginLeft, lockMargin } = refs(this.form);
|
|
72
|
-
[marginRight, marginBottom, marginLeft].forEach(elm => {
|
|
73
|
-
attr(elm, 'disabled', this.state.marginIsLocked || null);
|
|
79
|
+
get form() {
|
|
80
|
+
return new UIImagePropertiesForm(this.j, this.state, this.activeTabState, {
|
|
81
|
+
openImageEditor: () => openImageEditorDialog(this.j, this.state),
|
|
82
|
+
openImagePopup: target => openImagePopup(this.j, this.dialog, this.state, target)
|
|
74
83
|
});
|
|
75
|
-
lockMargin.innerHTML = Icon.get(this.state.marginIsLocked ? 'lock' : 'unlock');
|
|
76
|
-
}
|
|
77
|
-
onChangeSizeIsLocked() {
|
|
78
|
-
if (!this.form) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const { lockSize, imageWidth } = refs(this.form);
|
|
82
|
-
lockSize.innerHTML = Icon.get(this.state.sizeIsLocked ? 'lock' : 'unlock');
|
|
83
|
-
lockSize.classList.remove('jodit-properties__lock');
|
|
84
|
-
lockSize.classList.remove('jodit-properties__unlock');
|
|
85
|
-
lockSize.classList.add(this.state.sizeIsLocked
|
|
86
|
-
? 'jodit-properties__lock'
|
|
87
|
-
: 'jodit-properties__unlock');
|
|
88
|
-
this.j.e.fire(imageWidth, 'change');
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Open dialog editing image properties
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```javascript
|
|
95
|
-
* const editor = Jodit.makeJodit('#editor');
|
|
96
|
-
* img = editor.createInside.element('img');
|
|
97
|
-
*
|
|
98
|
-
* img.setAttribute('src', 'images/some-image.png');
|
|
99
|
-
* editor.s.insertImage(img);
|
|
100
|
-
* // open the properties of the editing window
|
|
101
|
-
* editor.events.fire('openImageProperties', img);
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
open() {
|
|
105
|
-
this.makeForm();
|
|
106
|
-
this.activeTabState.__activeTab = 'Image';
|
|
107
|
-
this.j.e.fire('hidePopup');
|
|
108
|
-
markOwner(this.j, this.dialog.container);
|
|
109
|
-
this.state.marginIsLocked = true;
|
|
110
|
-
this.state.sizeIsLocked = true;
|
|
111
|
-
this.onChangeMarginIsLocked();
|
|
112
|
-
this.onChangeSizeIsLocked();
|
|
113
|
-
this.updateValues();
|
|
114
|
-
this.dialog.open().setModal(true).setPosition();
|
|
115
|
-
return false;
|
|
116
84
|
}
|
|
117
85
|
/**
|
|
118
|
-
*
|
|
86
|
+
* Dialog for form
|
|
119
87
|
*/
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
this.dialog = this.j.dlg({
|
|
88
|
+
get dialog() {
|
|
89
|
+
const { j } = this;
|
|
90
|
+
const dialog = j.dlg({
|
|
125
91
|
minWidth: Math.min(400, screen.width),
|
|
126
92
|
minHeight: 590,
|
|
127
93
|
buttons: ['fullsize', 'dialog.close']
|
|
128
94
|
});
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (this.state.image.parentNode &&
|
|
135
|
-
opt.image.selectImageAfterClose) {
|
|
136
|
-
editor.s.select(this.state.image);
|
|
137
|
-
}
|
|
95
|
+
const buttons = this.__buttons;
|
|
96
|
+
buttons.check.onAction(() => {
|
|
97
|
+
applyValuesToImage(j, this.state, this.state.sourceImage);
|
|
98
|
+
j.synchronizeValues();
|
|
99
|
+
dialog.close();
|
|
138
100
|
});
|
|
139
101
|
buttons.remove.onAction(() => {
|
|
140
|
-
|
|
141
|
-
|
|
102
|
+
j.s.removeNode(this.state.sourceImage);
|
|
103
|
+
dialog.close();
|
|
142
104
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const mainForm = form(editor);
|
|
146
|
-
this.form = mainForm;
|
|
147
|
-
dialog.setContent(mainForm);
|
|
148
|
-
const { tabsBox } = refs(this.form);
|
|
149
|
-
if (tabsBox) {
|
|
150
|
-
tabsBox.appendChild(TabsWidget(editor, [
|
|
151
|
-
{ name: 'Image', content: mainTab(editor) },
|
|
152
|
-
{ name: 'Advanced', content: positionTab(editor) }
|
|
153
|
-
], this.activeTabState));
|
|
154
|
-
}
|
|
155
|
-
buttons.check.onAction(this.onApply);
|
|
156
|
-
const { changeImage, editImage } = refs(this.form);
|
|
157
|
-
editor.e.on(changeImage, 'click', this.openImagePopup);
|
|
158
|
-
if (opt.image.useImageEditor) {
|
|
159
|
-
editor.e.on(editImage, 'click', this.openImageEditor);
|
|
160
|
-
}
|
|
161
|
-
const { lockSize, lockMargin, imageWidth, imageHeight } = refs(mainForm);
|
|
162
|
-
if (lockSize) {
|
|
163
|
-
editor.e.on(lockSize, 'click', () => {
|
|
164
|
-
this.state.sizeIsLocked = !this.state.sizeIsLocked;
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
editor.e.on(lockMargin, 'click', (e) => {
|
|
168
|
-
this.state.marginIsLocked = !this.state.marginIsLocked;
|
|
169
|
-
e.preventDefault();
|
|
105
|
+
buttons.cancel.onAction(() => {
|
|
106
|
+
dialog.close();
|
|
170
107
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
imageWidth.value = Math.round(h * this.state.ratio).toString();
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
editor.e.on([imageWidth, imageHeight], 'change keydown mousedown paste', (event) => {
|
|
184
|
-
if (!this.state.sizeIsLocked) {
|
|
185
|
-
return;
|
|
108
|
+
dialog.setHeader(j.i18n('Image properties'));
|
|
109
|
+
dialog.setContent(this.form);
|
|
110
|
+
dialog.setFooter([[buttons.cancel, buttons.remove], buttons.check]);
|
|
111
|
+
j.e.on(dialog, 'afterClose', () => {
|
|
112
|
+
if (this.state.image.parentNode &&
|
|
113
|
+
j.o.image.selectImageAfterClose) {
|
|
114
|
+
j.s.select(this.state.sourceImage);
|
|
186
115
|
}
|
|
187
|
-
editor.async.setTimeout(changeSizes.bind(this, event), {
|
|
188
|
-
timeout: editor.defaultTimeout,
|
|
189
|
-
label: 'image-properties-changeSize'
|
|
190
|
-
});
|
|
191
116
|
});
|
|
192
|
-
dialog.
|
|
193
|
-
|
|
117
|
+
dialog.setSize(j.o.image.dialogWidth);
|
|
118
|
+
markOwner(j, dialog.container);
|
|
119
|
+
return dialog;
|
|
194
120
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const { marginTop, marginRight, marginBottom, marginLeft, lockMargin, imageSrc, id, classes, align, style, imageTitle, imageAlt, borderRadius, imageLink, imageWidth, imageHeight, imageLinkOpenInNewTab, imageViewSrc, lockSize } = refs(this.form);
|
|
202
|
-
const updateLock = () => {
|
|
203
|
-
lockMargin.checked = this.state.marginIsLocked;
|
|
204
|
-
lockSize.checked = this.state.sizeIsLocked;
|
|
205
|
-
}, updateAlign = () => {
|
|
206
|
-
if (image.style.cssFloat &&
|
|
207
|
-
['left', 'right'].indexOf(image.style.cssFloat.toLowerCase()) !== -1) {
|
|
208
|
-
align.value = css(image, 'float');
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
if (css(image, 'display') === 'block' &&
|
|
212
|
-
image.style.marginLeft === 'auto' &&
|
|
213
|
-
image.style.marginRight === 'auto') {
|
|
214
|
-
align.value = 'center';
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}, updateBorderRadius = () => {
|
|
218
|
-
borderRadius.value = (parseInt(image.style.borderRadius || '0', 10) || '0').toString();
|
|
219
|
-
}, updateId = () => {
|
|
220
|
-
id.value = attr(image, 'id') || '';
|
|
221
|
-
}, updateStyle = () => {
|
|
222
|
-
style.value = attr(image, 'style') || '';
|
|
223
|
-
}, updateClasses = () => {
|
|
224
|
-
classes.value = (attr(image, 'class') || '').replace(/jodit_focused_image[\s]*/, '');
|
|
225
|
-
}, updateMargins = () => {
|
|
226
|
-
if (!opt.image.editMargins) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
let equal = true, wasEmptyField = false;
|
|
230
|
-
[marginTop, marginRight, marginBottom, marginLeft].forEach(elm => {
|
|
231
|
-
const id = attr(elm, 'data-ref') || '';
|
|
232
|
-
let value = image.style.getPropertyValue(kebabCase(id));
|
|
233
|
-
if (!value) {
|
|
234
|
-
wasEmptyField = true;
|
|
235
|
-
elm.value = '';
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
if (/^[0-9]+(px)?$/.test(value)) {
|
|
239
|
-
value = parseInt(value, 10);
|
|
240
|
-
}
|
|
241
|
-
elm.value = value.toString() || '';
|
|
242
|
-
if ((wasEmptyField && elm.value) ||
|
|
243
|
-
(equal &&
|
|
244
|
-
id !== 'marginTop' &&
|
|
245
|
-
elm.value !== marginTop.value)) {
|
|
246
|
-
equal = false;
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
this.state.marginIsLocked = equal;
|
|
250
|
-
}, updateSizes = () => {
|
|
251
|
-
const width = attr(image, 'width') ||
|
|
252
|
-
css(image, 'width', true) ||
|
|
253
|
-
false, height = attr(image, 'height') ||
|
|
254
|
-
css(image, 'height', true) ||
|
|
255
|
-
false;
|
|
256
|
-
imageWidth.value =
|
|
257
|
-
width !== false
|
|
258
|
-
? normalSizeFromString(width).toString()
|
|
259
|
-
: image.offsetWidth.toString();
|
|
260
|
-
imageHeight.value =
|
|
261
|
-
height !== false
|
|
262
|
-
? normalSizeFromString(height).toString()
|
|
263
|
-
: image.offsetHeight.toString();
|
|
264
|
-
this.state.sizeIsLocked = (() => {
|
|
265
|
-
if (!isNumeric(imageWidth.value) ||
|
|
266
|
-
!isNumeric(imageHeight.value)) {
|
|
267
|
-
return false;
|
|
268
|
-
}
|
|
269
|
-
const w = parseFloat(imageWidth.value), h = parseFloat(imageHeight.value);
|
|
270
|
-
return Math.abs(w - h * this.state.ratio) < 1;
|
|
271
|
-
})();
|
|
272
|
-
}, updateText = () => {
|
|
273
|
-
imageTitle.value = attr(image, 'title') || '';
|
|
274
|
-
imageAlt.value = attr(image, 'alt') || '';
|
|
275
|
-
const a = Dom.closest(image, 'a', this.j.editor);
|
|
276
|
-
if (a) {
|
|
277
|
-
imageLink.value = attr(a, 'href') || '';
|
|
278
|
-
imageLinkOpenInNewTab.checked =
|
|
279
|
-
attr(a, 'target') === '_blank';
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
imageLink.value = '';
|
|
283
|
-
imageLinkOpenInNewTab.checked = false;
|
|
284
|
-
}
|
|
285
|
-
}, updateSrc = () => {
|
|
286
|
-
imageSrc.value = attr(image, 'src') || '';
|
|
287
|
-
if (imageViewSrc) {
|
|
288
|
-
attr(imageViewSrc, 'src', attr(image, 'src') || '');
|
|
289
|
-
}
|
|
121
|
+
get __buttons() {
|
|
122
|
+
const { j } = this;
|
|
123
|
+
return {
|
|
124
|
+
check: Button(j, 'ok', 'Apply', 'primary'),
|
|
125
|
+
remove: Button(j, 'bin', 'Delete'),
|
|
126
|
+
cancel: Button(j, 'cancel', 'Cancel')
|
|
290
127
|
};
|
|
291
|
-
updateLock();
|
|
292
|
-
updateSrc();
|
|
293
|
-
updateText();
|
|
294
|
-
updateSizes();
|
|
295
|
-
updateMargins();
|
|
296
|
-
updateClasses();
|
|
297
|
-
updateId();
|
|
298
|
-
updateBorderRadius();
|
|
299
|
-
updateAlign();
|
|
300
|
-
updateStyle();
|
|
301
128
|
}
|
|
302
129
|
/**
|
|
303
|
-
*
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
attr(image, 'src', imageSrc.value);
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
Dom.safeRemove(image);
|
|
319
|
-
this.dialog.close();
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
// Border radius
|
|
323
|
-
if (borderRadius.value !== '0' && /^[0-9]+$/.test(borderRadius.value)) {
|
|
324
|
-
image.style.borderRadius = borderRadius.value + 'px';
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
image.style.borderRadius = '';
|
|
328
|
-
}
|
|
329
|
-
// Title
|
|
330
|
-
attr(image, 'title', imageTitle.value || null);
|
|
331
|
-
// Alt
|
|
332
|
-
attr(image, 'alt', imageAlt.value || null);
|
|
333
|
-
// Link
|
|
334
|
-
let link = Dom.closest(image, 'a', this.j.editor);
|
|
335
|
-
if (imageLink.value) {
|
|
336
|
-
if (!link) {
|
|
337
|
-
link = Dom.wrap(image, 'a', this.j.createInside);
|
|
338
|
-
}
|
|
339
|
-
attr(link, 'href', imageLink.value);
|
|
340
|
-
attr(link, 'target', imageLinkOpenInNewTab.checked ? '_blank' : null);
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
if (link && link.parentNode) {
|
|
344
|
-
link.parentNode.replaceChild(image, link);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// Size
|
|
348
|
-
if (imageWidth.value !== image.offsetWidth.toString() ||
|
|
349
|
-
imageHeight.value !== image.offsetHeight.toString()) {
|
|
350
|
-
const updatedtWidth = trim(imageWidth.value)
|
|
351
|
-
? normalSizeToString(imageWidth.value)
|
|
352
|
-
: null;
|
|
353
|
-
const updatedHeight = trim(imageHeight.value)
|
|
354
|
-
? normalSizeToString(imageHeight.value)
|
|
355
|
-
: null;
|
|
356
|
-
css(image, {
|
|
357
|
-
width: updatedtWidth,
|
|
358
|
-
height: updatedHeight
|
|
359
|
-
});
|
|
360
|
-
attr(image, 'width', attr(image, 'width') ? updatedtWidth : null);
|
|
361
|
-
attr(image, 'height', attr(image, 'height') ? updatedHeight : null);
|
|
362
|
-
}
|
|
363
|
-
const margins = [marginTop, marginRight, marginBottom, marginLeft];
|
|
364
|
-
if (opt.image.editMargins) {
|
|
365
|
-
if (!this.state.marginIsLocked) {
|
|
366
|
-
margins.forEach((margin) => {
|
|
367
|
-
const side = attr(margin, 'data-ref') || '';
|
|
368
|
-
css(image, side, normalSizeToString(margin.value));
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
css(image, 'margin', normalSizeToString(marginTop.value));
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (opt.image.editClass) {
|
|
376
|
-
attr(image, 'class', classes.value || null);
|
|
377
|
-
}
|
|
378
|
-
if (opt.image.editId) {
|
|
379
|
-
attr(image, 'id', id.value || null);
|
|
380
|
-
}
|
|
381
|
-
if (opt.image.editAlign) {
|
|
382
|
-
hAlignElement(image, align.value);
|
|
383
|
-
}
|
|
384
|
-
this.j.synchronizeValues();
|
|
385
|
-
this.dialog.close();
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Open image editor dialog
|
|
130
|
+
* Open dialog editing image properties
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```javascript
|
|
134
|
+
* const editor = Jodit.makeJodit('#editor');
|
|
135
|
+
* img = editor.createInside.element('img');
|
|
136
|
+
*
|
|
137
|
+
* img.setAttribute('src', 'images/some-image.png');
|
|
138
|
+
* editor.s.insertImage(img);
|
|
139
|
+
* // open the properties of the editing window
|
|
140
|
+
* editor.events.fire('openImageProperties', img);
|
|
141
|
+
* ```
|
|
389
142
|
*/
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
resp.newfilename);
|
|
400
|
-
this.updateValues();
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
}, error => {
|
|
404
|
-
this.j.alert('There was an error loading %s', error.message);
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
|
-
return;
|
|
143
|
+
open() {
|
|
144
|
+
this.activeTabState.activeTab = 'Image';
|
|
145
|
+
this.__lock();
|
|
146
|
+
this.dialog.open().setModal(true).setPosition();
|
|
147
|
+
this.async
|
|
148
|
+
.promise((resolve, reject) => readValuesFromImage(this.j, this.state).then(resolve, reject))
|
|
149
|
+
.catch((e) => {
|
|
150
|
+
if (!isAbortError(e)) {
|
|
151
|
+
this.dialog.message.error(e.message);
|
|
409
152
|
}
|
|
410
|
-
};
|
|
411
|
-
a.href = url;
|
|
412
|
-
this.j.filebrowser.dataProvider
|
|
413
|
-
.getPathByUrl(a.href.toString())
|
|
414
|
-
.then(resp => {
|
|
415
|
-
openImageEditor.call(this.j.filebrowser, a.href, resp.name, resp.path, resp.source, () => {
|
|
416
|
-
const timestamp = new Date().getTime();
|
|
417
|
-
attr(this.state.image, 'src', url +
|
|
418
|
-
(url.indexOf('?') !== -1 ? '' : '?') +
|
|
419
|
-
'&_tmp=' +
|
|
420
|
-
timestamp.toString());
|
|
421
|
-
this.updateValues();
|
|
422
|
-
}, error => {
|
|
423
|
-
this.j.alert(error.message);
|
|
424
|
-
});
|
|
425
153
|
})
|
|
426
|
-
.
|
|
427
|
-
|
|
428
|
-
});
|
|
154
|
+
.finally(() => this.__unlock());
|
|
155
|
+
return false;
|
|
429
156
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (data.files && data.files.length) {
|
|
440
|
-
attr(this.state.image, 'src', data.baseurl + data.files[0]);
|
|
441
|
-
}
|
|
442
|
-
this.updateValues();
|
|
443
|
-
popup.close();
|
|
444
|
-
},
|
|
445
|
-
filebrowser: (data) => {
|
|
446
|
-
if (data &&
|
|
447
|
-
isArray(data.files) &&
|
|
448
|
-
data.files.length) {
|
|
449
|
-
attr(this.state.image, 'src', data.files[0]);
|
|
450
|
-
popup.close();
|
|
451
|
-
this.updateValues();
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}, this.state.image, popup.close))
|
|
455
|
-
.open(() => position(changeImage));
|
|
456
|
-
event.stopPropagation();
|
|
157
|
+
__lock() {
|
|
158
|
+
this.dialog.lock();
|
|
159
|
+
this.form.setMod('lock', true);
|
|
160
|
+
Object.values(this.__buttons).forEach(b => (b.state.disabled = true));
|
|
161
|
+
}
|
|
162
|
+
__unlock() {
|
|
163
|
+
this.dialog.unlock();
|
|
164
|
+
this.form.setMod('lock', false);
|
|
165
|
+
Object.values(this.__buttons).forEach(b => (b.state.disabled = false));
|
|
457
166
|
}
|
|
458
167
|
/** @override **/
|
|
459
168
|
afterInit(editor) {
|
|
@@ -472,7 +181,8 @@ export class imageProperties extends Plugin {
|
|
|
472
181
|
false) {
|
|
473
182
|
return;
|
|
474
183
|
}
|
|
475
|
-
self.state.
|
|
184
|
+
self.state.sourceImage = image;
|
|
185
|
+
self.state.image = image.cloneNode(true);
|
|
476
186
|
if (!editor.o.readonly) {
|
|
477
187
|
e.stopImmediatePropagation();
|
|
478
188
|
e.preventDefault();
|
|
@@ -486,29 +196,50 @@ export class imageProperties extends Plugin {
|
|
|
486
196
|
});
|
|
487
197
|
})
|
|
488
198
|
.on('openImageProperties.imageproperties', (image) => {
|
|
489
|
-
|
|
199
|
+
self.state.sourceImage = image;
|
|
200
|
+
this.state.image = image.cloneNode(true);
|
|
490
201
|
this.open();
|
|
491
202
|
});
|
|
492
203
|
}
|
|
204
|
+
async onStateValuesImageSrcChange() {
|
|
205
|
+
const { image, values } = this.state;
|
|
206
|
+
if (!image.src) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
this.__lock();
|
|
211
|
+
await image.decode();
|
|
212
|
+
if (this.state.sizeIsLocked && isNumeric(values.imageWidth)) {
|
|
213
|
+
const w = parseFloat(values.imageWidth.toString());
|
|
214
|
+
values.imageHeight = Math.round(w / this.state.ratio);
|
|
215
|
+
}
|
|
216
|
+
this.j.e.fire('updateImageProperties.imageproperties', image);
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
this.j.alert(e.message);
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
this.__unlock();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
493
225
|
/** @override */
|
|
494
226
|
beforeDestruct(editor) {
|
|
495
|
-
this.
|
|
227
|
+
Object.values(cached(this, '__buttons') ?? {}).forEach(b => b.destruct());
|
|
228
|
+
cached(this, 'dialog')?.destruct();
|
|
229
|
+
cached(this, 'form')?.destruct();
|
|
496
230
|
editor.e.off(editor.editor, '.imageproperties').off('.imageproperties');
|
|
497
231
|
}
|
|
498
232
|
}
|
|
499
233
|
__decorate([
|
|
500
|
-
|
|
501
|
-
], imageProperties.prototype, "
|
|
502
|
-
__decorate([
|
|
503
|
-
watch('state.sizeIsLocked')
|
|
504
|
-
], imageProperties.prototype, "onChangeSizeIsLocked", null);
|
|
234
|
+
cache
|
|
235
|
+
], imageProperties.prototype, "form", null);
|
|
505
236
|
__decorate([
|
|
506
|
-
|
|
507
|
-
], imageProperties.prototype, "
|
|
237
|
+
cache
|
|
238
|
+
], imageProperties.prototype, "dialog", null);
|
|
508
239
|
__decorate([
|
|
509
|
-
|
|
510
|
-
], imageProperties.prototype, "
|
|
240
|
+
cache
|
|
241
|
+
], imageProperties.prototype, "__buttons", null);
|
|
511
242
|
__decorate([
|
|
512
|
-
|
|
513
|
-
], imageProperties.prototype, "
|
|
243
|
+
watch('state.image')
|
|
244
|
+
], imageProperties.prototype, "onStateValuesImageSrcChange", null);
|
|
514
245
|
pluginSystem.add('imageProperties', imageProperties);
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
4
|
* Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import type { IJodit } from "jodit/esm/types";
|
|
10
|
-
export declare function form(editor: IJodit): HTMLElement;
|
|
6
|
+
import type { EditValues } from "../interface";
|
|
7
|
+
/** @private */
|
|
8
|
+
export declare function readAlign(image: HTMLImageElement, values: EditValues): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
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-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
import { css } from "jodit/esm/core/helpers/utils/css.js";
|
|
7
|
+
/** @private */
|
|
8
|
+
export function readAlign(image, values) {
|
|
9
|
+
// Align
|
|
10
|
+
if (image.style.cssFloat &&
|
|
11
|
+
['left', 'right'].indexOf(image.style.cssFloat.toLowerCase()) !== -1) {
|
|
12
|
+
values.align = css(image, 'float');
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
if (css(image, 'display') === 'block' &&
|
|
16
|
+
image.style.marginLeft === 'auto' &&
|
|
17
|
+
image.style.marginRight === 'auto') {
|
|
18
|
+
values.align = 'center';
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
values.align = '';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Jodit Editor (https://xdsoft.net/jodit/)
|
|
3
|
+
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
|
+
* Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
+
*/
|
|
6
|
+
import type { IJodit } from "jodit/esm/types";
|
|
7
|
+
import type { ImagePropertiesState } from "../interface";
|
|
8
|
+
/**
|
|
9
|
+
* Read values from image and set it to state
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
export declare function readValuesFromImage(j: IJodit, state: ImagePropertiesState): Promise<void>;
|