jodit 4.18.6 → 4.18.7
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 +10 -0
- package/es2015/jodit.css +1 -1
- package/es2015/jodit.fat.min.js +8 -8
- package/es2015/jodit.js +103 -22
- package/es2015/jodit.min.js +8 -8
- 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.js +6 -6
- package/es2018/jodit.min.js +6 -6
- package/es2018/plugins/debug/debug.min.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021/jodit.css +1 -1
- package/es2021/jodit.fat.min.js +6 -6
- package/es2021/jodit.js +102 -22
- package/es2021/jodit.min.js +6 -6
- 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 +1 -1
- package/es2021.en/jodit.fat.min.js +10 -10
- package/es2021.en/jodit.js +102 -22
- package/es2021.en/jodit.min.js +6 -6
- 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 +2 -2
- package/es5/jodit.fat.min.js +2 -2
- package/es5/jodit.js +110 -21
- package/es5/jodit.min.css +2 -2
- 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 +2 -0
- package/esm/core/constants.js +1 -1
- package/esm/core/decorators/component/component.js +12 -0
- package/esm/core/ui/popup/popup.js +14 -9
- package/esm/jodit.js +5 -1
- package/esm/modules/file-browser/ui/files/files.js +17 -2
- package/esm/modules/file-browser/ui/tree/tree.js +17 -2
- package/esm/plugins/backspace/cases/check-remove-char.d.ts +2 -1
- package/esm/plugins/backspace/cases/check-remove-char.js +25 -4
- package/esm/plugins/backspace/config.d.ts +2 -0
- package/esm/plugins/backspace/config.js +6 -3
- package/esm/plugins/image-properties/image-properties.d.ts +5 -0
- package/esm/plugins/image-properties/image-properties.js +30 -5
- package/esm/plugins/mobile/mobile.js +7 -4
- package/package.json +1 -1
- package/types/config.d.ts +2 -0
- package/types/plugins/backspace/cases/check-remove-char.d.ts +2 -1
- package/types/plugins/backspace/config.d.ts +2 -0
- package/types/plugins/image-properties/image-properties.d.ts +5 -0
package/es5/polyfills.fat.min.js
CHANGED
package/es5/polyfills.js
CHANGED
package/es5/polyfills.min.js
CHANGED
package/esm/config.d.ts
CHANGED
|
@@ -1034,6 +1034,8 @@ interface Config {
|
|
|
1034
1034
|
interface Config {
|
|
1035
1035
|
/**
|
|
1036
1036
|
* Keyboard hotkey mappings for delete and backspace operations (character, word, sentence).
|
|
1037
|
+
* On macOS the defaults leave out Cmd+Backspace, Ctrl+Backspace, Ctrl+Option+Backspace
|
|
1038
|
+
* and Cmd+Option+Backspace, so the browser applies the system's own bindings to them.
|
|
1037
1039
|
*/
|
|
1038
1040
|
delete: {
|
|
1039
1041
|
hotkeys: {
|
package/esm/core/constants.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
4
|
* Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
|
-
export const APP_VERSION = "4.18.
|
|
6
|
+
export const APP_VERSION = "4.18.7";
|
|
7
7
|
// prettier-ignore
|
|
8
8
|
export const ES = "es2020";
|
|
9
9
|
export const IS_ES_MODERN = true;
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import { IS_PROD } from "../../constants.js";
|
|
7
7
|
import { getClassName } from "../../helpers/utils/get-class-name.js";
|
|
8
8
|
const componentRegistry = new Map();
|
|
9
|
+
const decoratedClasses = new WeakSet();
|
|
10
|
+
const warnedClasses = new WeakSet();
|
|
9
11
|
/**
|
|
10
12
|
* Decorate components and set status isReady after constructor
|
|
11
13
|
* @param constructorFunction - Component constructor class
|
|
@@ -24,8 +26,18 @@ export function component(constructorFunction) {
|
|
|
24
26
|
}
|
|
25
27
|
this.setStatus('ready');
|
|
26
28
|
}
|
|
29
|
+
else if (!IS_PROD &&
|
|
30
|
+
!decoratedClasses.has(this.constructor) &&
|
|
31
|
+
!warnedClasses.has(this.constructor)) {
|
|
32
|
+
// Only the outermost class's decorator sets `ready`, so a subclass
|
|
33
|
+
// without its own decorator stays in `beforeInit`. See #1685
|
|
34
|
+
warnedClasses.add(this.constructor);
|
|
35
|
+
console.warn(`Component "${this.constructor.name || getClassName(this)}" extends a @component class without being decorated itself, so it never becomes ready and its @watch, @debounce, @throttle and @hook handlers never run`);
|
|
36
|
+
}
|
|
27
37
|
}
|
|
28
38
|
}
|
|
39
|
+
decoratedClasses.add(constructorFunction);
|
|
40
|
+
decoratedClasses.add(newConstructorFunction);
|
|
29
41
|
const name = getClassName(constructorFunction.prototype);
|
|
30
42
|
if (componentRegistry.has(name) && !IS_PROD) {
|
|
31
43
|
throw new Error(`Component with name "${name}" is already registered`);
|
|
@@ -13,8 +13,9 @@ 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
|
+
var Popup_1;
|
|
16
17
|
import { Component } from "../../component/component.js";
|
|
17
|
-
import { autobind, throttle } from "../../decorators/index.js";
|
|
18
|
+
import { autobind, component, throttle } from "../../decorators/index.js";
|
|
18
19
|
import { Dom } from "../../dom/dom.js";
|
|
19
20
|
import { eventEmitter, getContainer } from "../../global.js";
|
|
20
21
|
import { attr, css, getFixedPositionOffset, isFunction, isString, kebabCase, markOwner, position, ucfirst } from "../../helpers/index.js";
|
|
@@ -29,7 +30,7 @@ const EVENTS_FOR_AUTOCLOSE = [
|
|
|
29
30
|
'backSpaceAfterDelete',
|
|
30
31
|
'beforeCommandDelete'
|
|
31
32
|
];
|
|
32
|
-
|
|
33
|
+
let Popup = Popup_1 = class Popup extends UIGroup {
|
|
33
34
|
className() {
|
|
34
35
|
return 'Popup';
|
|
35
36
|
}
|
|
@@ -39,7 +40,7 @@ export class Popup extends UIGroup {
|
|
|
39
40
|
Dom.append(content, childContainer);
|
|
40
41
|
}
|
|
41
42
|
updateParentElement(target) {
|
|
42
|
-
if (target !== this && Component.isInstanceOf(target,
|
|
43
|
+
if (target !== this && Component.isInstanceOf(target, Popup_1)) {
|
|
43
44
|
this.__childrenPopups.forEach(popup => {
|
|
44
45
|
if (!target.closest(popup) && popup.isOpened) {
|
|
45
46
|
popup.close();
|
|
@@ -89,7 +90,7 @@ export class Popup extends UIGroup {
|
|
|
89
90
|
Dom.append(parentContainer, this.container);
|
|
90
91
|
}
|
|
91
92
|
else {
|
|
92
|
-
const popupContainer = getContainer(this.jodit,
|
|
93
|
+
const popupContainer = getContainer(this.jodit, Popup_1);
|
|
93
94
|
if (parentContainer !== this.container.parentElement) {
|
|
94
95
|
Dom.append(popupContainer, this.container);
|
|
95
96
|
}
|
|
@@ -207,13 +208,13 @@ export class Popup extends UIGroup {
|
|
|
207
208
|
};
|
|
208
209
|
const getMatchStrategy = (inBox) => {
|
|
209
210
|
let strategy;
|
|
210
|
-
if (
|
|
211
|
+
if (Popup_1.boxInView(getPointByStrategy(defaultStrategy), inBox)) {
|
|
211
212
|
strategy = defaultStrategy;
|
|
212
213
|
}
|
|
213
214
|
else {
|
|
214
215
|
strategy =
|
|
215
216
|
list.find((key) => {
|
|
216
|
-
if (
|
|
217
|
+
if (Popup_1.boxInView(getPointByStrategy(key), inBox)) {
|
|
217
218
|
return key;
|
|
218
219
|
}
|
|
219
220
|
return;
|
|
@@ -224,7 +225,7 @@ export class Popup extends UIGroup {
|
|
|
224
225
|
// Try to find match position inside Jodit.container
|
|
225
226
|
let strategy = getMatchStrategy(position(this.j.container, this.j));
|
|
226
227
|
// If not found or is not inside window view
|
|
227
|
-
if (!strategy || !
|
|
228
|
+
if (!strategy || !Popup_1.boxInView(getPointByStrategy(strategy), view)) {
|
|
228
229
|
// Find match strategy inside window view
|
|
229
230
|
strategy = getMatchStrategy(view) || strategy || defaultStrategy;
|
|
230
231
|
}
|
|
@@ -280,7 +281,7 @@ export class Popup extends UIGroup {
|
|
|
280
281
|
if (!e.target) {
|
|
281
282
|
return false;
|
|
282
283
|
}
|
|
283
|
-
const box = UIElement.closestElement(e.target,
|
|
284
|
+
const box = UIElement.closestElement(e.target, Popup_1);
|
|
284
285
|
return Boolean(box && (this === box || box.closest(this)));
|
|
285
286
|
}
|
|
286
287
|
__addGlobalListeners() {
|
|
@@ -353,7 +354,7 @@ export class Popup extends UIGroup {
|
|
|
353
354
|
this.close();
|
|
354
355
|
return super.destruct();
|
|
355
356
|
}
|
|
356
|
-
}
|
|
357
|
+
};
|
|
357
358
|
__decorate([
|
|
358
359
|
autobind
|
|
359
360
|
], Popup.prototype, "updatePosition", null);
|
|
@@ -367,3 +368,7 @@ __decorate([
|
|
|
367
368
|
__decorate([
|
|
368
369
|
autobind
|
|
369
370
|
], Popup.prototype, "__closeOnOutsideClick", null);
|
|
371
|
+
Popup = Popup_1 = __decorate([
|
|
372
|
+
component
|
|
373
|
+
], Popup);
|
|
374
|
+
export { Popup };
|
package/esm/jodit.js
CHANGED
|
@@ -557,7 +557,7 @@ let Jodit = Jodit_1 = class Jodit extends ViewWithToolbar {
|
|
|
557
557
|
const hotkeys = this.o.commandToHotkeys[commandName] ||
|
|
558
558
|
this.o.commandToHotkeys[commandNameOriginal] ||
|
|
559
559
|
command.hotkeys;
|
|
560
|
-
if (hotkeys) {
|
|
560
|
+
if (hotkeys && hotkeys.length) {
|
|
561
561
|
this.registerHotkeyToCommand(hotkeys, commandName, options === null || options === void 0 ? void 0 : options.stopPropagation);
|
|
562
562
|
}
|
|
563
563
|
}
|
|
@@ -567,6 +567,10 @@ let Jodit = Jodit_1 = class Jodit extends ViewWithToolbar {
|
|
|
567
567
|
* Register hotkey for command
|
|
568
568
|
*/
|
|
569
569
|
registerHotkeyToCommand(hotkeys, commandName, shouldStop = true) {
|
|
570
|
+
// An empty list (e.g. `commandToHotkeys: { cmd: [] }`) turns the key off
|
|
571
|
+
if (!hotkeys || !hotkeys.length) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
570
574
|
const shortcuts = asArray(hotkeys)
|
|
571
575
|
.map(normalizeKeyAliases)
|
|
572
576
|
.map(hotkey => hotkey + '.hotkey')
|
|
@@ -3,9 +3,24 @@
|
|
|
3
3
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
4
|
* Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
|
+
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/index.js";
|
|
6
17
|
import { UIGroup } from "../../../../core/ui/index.js";
|
|
7
|
-
|
|
18
|
+
let FileBrowserFiles = class FileBrowserFiles extends UIGroup {
|
|
8
19
|
className() {
|
|
9
20
|
return 'FileBrowserFiles';
|
|
10
21
|
}
|
|
11
|
-
}
|
|
22
|
+
};
|
|
23
|
+
FileBrowserFiles = __decorate([
|
|
24
|
+
component
|
|
25
|
+
], FileBrowserFiles);
|
|
26
|
+
export { FileBrowserFiles };
|
|
@@ -3,9 +3,24 @@
|
|
|
3
3
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
4
|
* Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
5
|
*/
|
|
6
|
+
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/index.js";
|
|
6
17
|
import { UIGroup } from "../../../../core/ui/index.js";
|
|
7
|
-
|
|
18
|
+
let FileBrowserTree = class FileBrowserTree extends UIGroup {
|
|
8
19
|
className() {
|
|
9
20
|
return 'FileBrowserTree';
|
|
10
21
|
}
|
|
11
|
-
}
|
|
22
|
+
};
|
|
23
|
+
FileBrowserTree = __decorate([
|
|
24
|
+
component
|
|
25
|
+
], FileBrowserTree);
|
|
26
|
+
export { FileBrowserTree };
|
|
@@ -19,6 +19,7 @@ import type { DeleteMode } from "../interface";
|
|
|
19
19
|
* ```html
|
|
20
20
|
* t|st
|
|
21
21
|
* ```
|
|
22
|
+
* With `stopBeforeSpace`, nothing is removed when the next char is a space.
|
|
22
23
|
* @private
|
|
23
24
|
*/
|
|
24
|
-
export declare function checkRemoveChar(jodit: IJodit, fakeNode: Node, backspace: boolean, mode: DeleteMode): boolean;
|
|
25
|
+
export declare function checkRemoveChar(jodit: IJodit, fakeNode: Node, backspace: boolean, mode: DeleteMode, stopBeforeSpace?: boolean): boolean;
|
|
@@ -18,10 +18,11 @@ import { findMostNestedNeighbor } from "../helpers.js";
|
|
|
18
18
|
* ```html
|
|
19
19
|
* t|st
|
|
20
20
|
* ```
|
|
21
|
+
* With `stopBeforeSpace`, nothing is removed when the next char is a space.
|
|
21
22
|
* @private
|
|
22
23
|
*/
|
|
23
24
|
// eslint-disable-next-line complexity
|
|
24
|
-
export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
|
|
25
|
+
export function checkRemoveChar(jodit, fakeNode, backspace, mode, stopBeforeSpace = false) {
|
|
25
26
|
var _a, _b;
|
|
26
27
|
const step = backspace ? -1 : 1;
|
|
27
28
|
const anotherSibling = Dom.sibling(fakeNode, !backspace);
|
|
@@ -40,6 +41,10 @@ export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
|
|
|
40
41
|
break;
|
|
41
42
|
}
|
|
42
43
|
if ((_a = sibling.nodeValue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
44
|
+
if (stopBeforeSpace &&
|
|
45
|
+
isSpace(nextChar(sibling.nodeValue, backspace))) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
43
48
|
removed = tryRemoveChar(sibling, backspace, step, anotherSibling);
|
|
44
49
|
if (!sibling.nodeValue.length &&
|
|
45
50
|
Dom.isInlineBlock(sibling.parentNode)) {
|
|
@@ -160,8 +165,24 @@ function replaceSpaceOnNBSP(anotherSibling, backspace, value) {
|
|
|
160
165
|
}
|
|
161
166
|
function checkRepeatRemoveCharAction(backspace, sibling, fakeNode, mode, removed, jodit) {
|
|
162
167
|
call(backspace ? Dom.after : Dom.before, sibling, fakeNode);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
const wordChar = mode === 'word' && !isSpace(removed);
|
|
169
|
+
// Backspace by word removes the spaces before the caret, then the word, and keeps the space in front of it
|
|
170
|
+
if (mode === 'sentence' || wordChar || (mode === 'word' && backspace)) {
|
|
171
|
+
checkRemoveChar(jodit, fakeNode, backspace, mode, wordChar && backspace);
|
|
166
172
|
}
|
|
167
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* The char tryRemoveChar would remove next
|
|
176
|
+
*/
|
|
177
|
+
function nextChar(value, backspace) {
|
|
178
|
+
const chars = toArray(value);
|
|
179
|
+
const step = backspace ? -1 : 1;
|
|
180
|
+
let index = backspace ? chars.length - 1 : 0;
|
|
181
|
+
while (chars[index] === INVISIBLE_SPACE) {
|
|
182
|
+
index += step;
|
|
183
|
+
}
|
|
184
|
+
return chars[index];
|
|
185
|
+
}
|
|
186
|
+
function isSpace(char) {
|
|
187
|
+
return char === ' ' || char === NBSP_SPACE;
|
|
188
|
+
}
|
|
@@ -7,6 +7,8 @@ declare module 'jodit/config' {
|
|
|
7
7
|
interface Config {
|
|
8
8
|
/**
|
|
9
9
|
* Keyboard hotkey mappings for delete and backspace operations (character, word, sentence).
|
|
10
|
+
* On macOS the defaults leave out Cmd+Backspace, Ctrl+Backspace, Ctrl+Option+Backspace
|
|
11
|
+
* and Cmd+Option+Backspace, so the browser applies the system's own bindings to them.
|
|
10
12
|
*/
|
|
11
13
|
delete: {
|
|
12
14
|
hotkeys: {
|
|
@@ -6,14 +6,17 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* @module plugins/backspace
|
|
8
8
|
*/
|
|
9
|
+
import { IS_MAC } from "../../core/constants.js";
|
|
9
10
|
import { Config } from "../../config.js";
|
|
10
11
|
Config.prototype.delete = {
|
|
11
12
|
hotkeys: {
|
|
12
|
-
delete: ['delete', 'cmd+backspace'],
|
|
13
|
-
deleteWord:
|
|
13
|
+
delete: IS_MAC ? ['delete'] : ['delete', 'cmd+backspace'],
|
|
14
|
+
deleteWord: IS_MAC
|
|
15
|
+
? ['ctrl+delete']
|
|
16
|
+
: ['ctrl+delete', 'cmd+alt+backspace', 'ctrl+alt+backspace'],
|
|
14
17
|
deleteSentence: ['ctrl+shift+delete', 'cmd+shift+delete'],
|
|
15
18
|
backspace: ['backspace'],
|
|
16
|
-
backspaceWord: ['ctrl+backspace'],
|
|
19
|
+
backspaceWord: IS_MAC ? [] : ['ctrl+backspace'],
|
|
17
20
|
backspaceSentence: ['ctrl+shift+backspace', 'cmd+shift+backspace']
|
|
18
21
|
}
|
|
19
22
|
};
|
|
@@ -52,6 +52,11 @@ export declare class imageProperties extends Plugin {
|
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
54
|
protected open(): void | false;
|
|
55
|
+
/**
|
|
56
|
+
* Keys typed while the dialog is open must not reach the editor behind it,
|
|
57
|
+
* so focus the active tab's first field, or else the first field shown
|
|
58
|
+
*/
|
|
59
|
+
private __focusFirstField;
|
|
55
60
|
private __lock;
|
|
56
61
|
private __unlock;
|
|
57
62
|
/** @override **/
|
|
@@ -16,7 +16,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
16
16
|
import { cache, cached, watch } from "../../core/decorators/index.js";
|
|
17
17
|
import { Dom } from "../../core/dom/dom.js";
|
|
18
18
|
import { pluginSystem } from "../../core/global.js";
|
|
19
|
-
import { isAbortError, isNumeric, markOwner } from "../../core/helpers/index.js";
|
|
19
|
+
import { isAbortError, isNumeric, markOwner, toArray } from "../../core/helpers/index.js";
|
|
20
20
|
import { Plugin } from "../../core/plugin/plugin.js";
|
|
21
21
|
import { Button } from "../../core/ui/button/index.js";
|
|
22
22
|
import "./config.js";
|
|
@@ -99,8 +99,12 @@ export class imageProperties extends Plugin {
|
|
|
99
99
|
dialog.close();
|
|
100
100
|
});
|
|
101
101
|
buttons.remove.onAction(() => {
|
|
102
|
+
const caret = j.s.createRange();
|
|
103
|
+
caret.setStartBefore(this.state.sourceImage);
|
|
104
|
+
caret.collapse(true);
|
|
102
105
|
j.s.removeNode(this.state.sourceImage);
|
|
103
106
|
dialog.close();
|
|
107
|
+
j.s.selectRange(caret);
|
|
104
108
|
});
|
|
105
109
|
buttons.cancel.onAction(() => {
|
|
106
110
|
dialog.close();
|
|
@@ -108,11 +112,20 @@ export class imageProperties extends Plugin {
|
|
|
108
112
|
dialog.setHeader(j.i18n('Image properties'));
|
|
109
113
|
dialog.setContent(this.form);
|
|
110
114
|
dialog.setFooter([[buttons.cancel, buttons.remove], buttons.check]);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
// The dialog fires `afterClose` on its own emitter, not the editor's
|
|
116
|
+
dialog.e.on(dialog, 'afterClose', () => {
|
|
117
|
+
const { sourceImage } = this.state;
|
|
118
|
+
if (j.isInDestruct || !Dom.isOrContains(j.editor, sourceImage)) {
|
|
119
|
+
return;
|
|
115
120
|
}
|
|
121
|
+
if (j.o.image.selectImageAfterClose) {
|
|
122
|
+
j.s.select(sourceImage);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const caret = j.s.createRange();
|
|
126
|
+
caret.setStartAfter(sourceImage);
|
|
127
|
+
caret.collapse(true);
|
|
128
|
+
j.s.selectRange(caret);
|
|
116
129
|
});
|
|
117
130
|
dialog.setSize(j.o.image.dialogWidth);
|
|
118
131
|
markOwner(j, dialog.container);
|
|
@@ -144,6 +157,7 @@ export class imageProperties extends Plugin {
|
|
|
144
157
|
this.activeTabState.activeTab = 'Image';
|
|
145
158
|
this.__lock();
|
|
146
159
|
this.dialog.open().setModal(true).setPosition();
|
|
160
|
+
this.__focusFirstField();
|
|
147
161
|
this.async
|
|
148
162
|
.promise((resolve, reject) => readValuesFromImage(this.j, this.state).then(resolve, reject))
|
|
149
163
|
.catch((e) => {
|
|
@@ -154,6 +168,17 @@ export class imageProperties extends Plugin {
|
|
|
154
168
|
.finally(() => this.__unlock());
|
|
155
169
|
return false;
|
|
156
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Keys typed while the dialog is open must not reach the editor behind it,
|
|
173
|
+
* so focus the active tab's first field, or else the first field shown
|
|
174
|
+
*/
|
|
175
|
+
__focusFirstField() {
|
|
176
|
+
var _a;
|
|
177
|
+
const fields = (box) => toArray(box.querySelectorAll('input, select, textarea'));
|
|
178
|
+
(_a = fields(this.form.getElm('tabsBox'))
|
|
179
|
+
.concat(fields(this.form.container))
|
|
180
|
+
.find(field => field.offsetParent != null)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
181
|
+
}
|
|
157
182
|
__lock() {
|
|
158
183
|
this.dialog.lock();
|
|
159
184
|
this.form.setMod('lock', true);
|
|
@@ -78,9 +78,11 @@ function fitToButtons(list, editor) {
|
|
|
78
78
|
return cleaned;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
|
-
* The width that decides which breakpoint set the toolbar uses
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* The width that decides which breakpoint set the toolbar uses: the editor's
|
|
82
|
+
* own width, or its parent's while the editor has none yet (for example
|
|
83
|
+
* while hidden at init). A toolbar rendered into an external container
|
|
84
|
+
* (`toolbar` set to an element or a selector) lays out in that container, so
|
|
85
|
+
* its width is what matters there.
|
|
84
86
|
*/
|
|
85
87
|
function adaptiveWidth(editor) {
|
|
86
88
|
var _a;
|
|
@@ -91,7 +93,8 @@ function adaptiveWidth(editor) {
|
|
|
91
93
|
return width;
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
|
-
return (
|
|
96
|
+
return (editor.container.offsetWidth ||
|
|
97
|
+
((_a = editor.container.parentElement) !== null && _a !== void 0 ? _a : editor.container).offsetWidth);
|
|
95
98
|
}
|
|
96
99
|
/**
|
|
97
100
|
* Rebuild toolbar in depends on editor's width
|
package/package.json
CHANGED
package/types/config.d.ts
CHANGED
|
@@ -1034,6 +1034,8 @@ interface Config {
|
|
|
1034
1034
|
interface Config {
|
|
1035
1035
|
/**
|
|
1036
1036
|
* Keyboard hotkey mappings for delete and backspace operations (character, word, sentence).
|
|
1037
|
+
* On macOS the defaults leave out Cmd+Backspace, Ctrl+Backspace, Ctrl+Option+Backspace
|
|
1038
|
+
* and Cmd+Option+Backspace, so the browser applies the system's own bindings to them.
|
|
1037
1039
|
*/
|
|
1038
1040
|
delete: {
|
|
1039
1041
|
hotkeys: {
|
|
@@ -19,6 +19,7 @@ import type { DeleteMode } from "../interface";
|
|
|
19
19
|
* ```html
|
|
20
20
|
* t|st
|
|
21
21
|
* ```
|
|
22
|
+
* With `stopBeforeSpace`, nothing is removed when the next char is a space.
|
|
22
23
|
* @private
|
|
23
24
|
*/
|
|
24
|
-
export declare function checkRemoveChar(jodit: IJodit, fakeNode: Node, backspace: boolean, mode: DeleteMode): boolean;
|
|
25
|
+
export declare function checkRemoveChar(jodit: IJodit, fakeNode: Node, backspace: boolean, mode: DeleteMode, stopBeforeSpace?: boolean): boolean;
|
|
@@ -7,6 +7,8 @@ declare module 'jodit/config' {
|
|
|
7
7
|
interface Config {
|
|
8
8
|
/**
|
|
9
9
|
* Keyboard hotkey mappings for delete and backspace operations (character, word, sentence).
|
|
10
|
+
* On macOS the defaults leave out Cmd+Backspace, Ctrl+Backspace, Ctrl+Option+Backspace
|
|
11
|
+
* and Cmd+Option+Backspace, so the browser applies the system's own bindings to them.
|
|
10
12
|
*/
|
|
11
13
|
delete: {
|
|
12
14
|
hotkeys: {
|
|
@@ -52,6 +52,11 @@ export declare class imageProperties extends Plugin {
|
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
54
|
protected open(): void | false;
|
|
55
|
+
/**
|
|
56
|
+
* Keys typed while the dialog is open must not reach the editor behind it,
|
|
57
|
+
* so focus the active tab's first field, or else the first field shown
|
|
58
|
+
*/
|
|
59
|
+
private __focusFirstField;
|
|
55
60
|
private __lock;
|
|
56
61
|
private __unlock;
|
|
57
62
|
/** @override **/
|