mirror of
https://github.com/codex-team/editor.js
synced 2024-06-08 00:42:31 +02:00
Handle paste on images and blocks w\o inputs (#583)
This commit is contained in:
parent
d00412e1df
commit
e8d43c8fc7
12
dist/codex-editor.js
vendored
12
dist/codex-editor.js
vendored
File diff suppressed because one or more lines are too long
1
dist/codex-editor.js.map
vendored
1
dist/codex-editor.js.map
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,9 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### 2.2.24 changelog
|
||||||
|
|
||||||
|
- `Improvements` *Paste handling — minor paste handling improvements
|
||||||
|
|
||||||
### 2.2.23 changelog
|
### 2.2.23 changelog
|
||||||
|
|
||||||
- `New` *Shortcuts — copy and cut Blocks selected by CMD+A
|
- `New` *Shortcuts — copy and cut Blocks selected by CMD+A
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "codex.editor",
|
"name": "codex.editor",
|
||||||
"version": "2.7.23",
|
"version": "2.7.24",
|
||||||
"description": "CodeX Editor. Native JS, based on API and Open Source",
|
"description": "CodeX Editor. Native JS, based on API and Open Source",
|
||||||
"main": "dist/codex-editor.js",
|
"main": "dist/codex-editor.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./types/index.d.ts",
|
||||||
|
|
|
@ -90,11 +90,7 @@ export default class Block {
|
||||||
* @param {HTMLElement} element
|
* @param {HTMLElement} element
|
||||||
*/
|
*/
|
||||||
set currentInput(element: HTMLElement) {
|
set currentInput(element: HTMLElement) {
|
||||||
const index = this.inputs.findIndex((input) => input === element || input.contains(element));
|
this.inputIndex = this.inputs.findIndex((input) => input === element || input.contains(element));
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
this.inputIndex = index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -468,12 +468,13 @@ export default class Dom {
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
public static containsOnlyInlineElements(data: string | HTMLElement): boolean {
|
public static containsOnlyInlineElements(data: string | HTMLElement): boolean {
|
||||||
const wrapper = document.createElement('template');
|
let wrapper: HTMLElement;
|
||||||
|
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
|
wrapper = document.createElement('div');
|
||||||
wrapper.innerHTML = data;
|
wrapper.innerHTML = data;
|
||||||
} else {
|
} else {
|
||||||
wrapper.appendChild(data);
|
wrapper = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const check = (element: HTMLElement) => {
|
const check = (element: HTMLElement) => {
|
||||||
|
@ -481,6 +482,6 @@ export default class Dom {
|
||||||
&& Array.from(element.children).every(check);
|
&& Array.from(element.children).every(check);
|
||||||
};
|
};
|
||||||
|
|
||||||
return check(wrapper);
|
return Array.from(wrapper.children).every(check);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ export default class Paste extends Module {
|
||||||
private setCallback(): void {
|
private setCallback(): void {
|
||||||
const {Listeners, UI} = this.Editor;
|
const {Listeners, UI} = this.Editor;
|
||||||
|
|
||||||
Listeners.on(UI.nodes.redactor, 'paste', this.handlePasteEvent);
|
Listeners.on(document, 'paste', this.handlePasteEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,15 +328,7 @@ export default class Paste extends Module {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
private isNativeBehaviour(element: EventTarget): boolean {
|
private isNativeBehaviour(element: EventTarget): boolean {
|
||||||
const {Editor: {BlockManager}} = this;
|
return $.isNativeInput(element);
|
||||||
|
|
||||||
if ( $.isNativeInput(element) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const block = BlockManager.getBlock(element as HTMLElement);
|
|
||||||
|
|
||||||
return !block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -345,15 +337,20 @@ export default class Paste extends Module {
|
||||||
* @param {ClipboardEvent} event
|
* @param {ClipboardEvent} event
|
||||||
*/
|
*/
|
||||||
private handlePasteEvent = async (event: ClipboardEvent): Promise<void> => {
|
private handlePasteEvent = async (event: ClipboardEvent): Promise<void> => {
|
||||||
|
const {BlockManager, Toolbar} = this.Editor;
|
||||||
|
|
||||||
/** If target is native input or is not Block, use browser behaviour */
|
/** If target is native input or is not Block, use browser behaviour */
|
||||||
if (
|
if (
|
||||||
this.isNativeBehaviour(event.target) && !event.clipboardData.types.includes('Files')
|
!BlockManager.currentBlock || this.isNativeBehaviour(event.target) && !event.clipboardData.types.includes('Files')
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.processDataTransfer(event.clipboardData);
|
this.processDataTransfer(event.clipboardData);
|
||||||
|
|
||||||
|
BlockManager.clearFocused();
|
||||||
|
Toolbar.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -362,7 +359,7 @@ export default class Paste extends Module {
|
||||||
* @param {FileList} items - pasted or dropped items
|
* @param {FileList} items - pasted or dropped items
|
||||||
*/
|
*/
|
||||||
private async processFiles(items: FileList) {
|
private async processFiles(items: FileList) {
|
||||||
const {BlockManager} = this.Editor;
|
const {BlockManager, Tools} = this.Editor;
|
||||||
|
|
||||||
let dataToInsert: Array<{type: string, event: PasteEvent}>;
|
let dataToInsert: Array<{type: string, event: PasteEvent}>;
|
||||||
|
|
||||||
|
@ -373,14 +370,12 @@ export default class Paste extends Module {
|
||||||
);
|
);
|
||||||
dataToInsert = dataToInsert.filter((data) => !!data);
|
dataToInsert = dataToInsert.filter((data) => !!data);
|
||||||
|
|
||||||
|
const isCurrentBlockInitial = Tools.isInitial(BlockManager.currentBlock.tool);
|
||||||
|
const needToReplaceCurrentBlock = isCurrentBlockInitial && BlockManager.currentBlock.isEmpty;
|
||||||
|
|
||||||
dataToInsert.forEach(
|
dataToInsert.forEach(
|
||||||
(data, i) => {
|
(data, i) => {
|
||||||
if (i === 0 && BlockManager.currentBlock && BlockManager.currentBlock.isEmpty) {
|
BlockManager.paste(data.type, data.event, i === 0 && needToReplaceCurrentBlock);
|
||||||
BlockManager.paste(data.type, data.event, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockManager.paste(data.type, data.event);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -598,7 +593,11 @@ export default class Paste extends Module {
|
||||||
const currentToolSanitizeConfig = Sanitizer.getInlineToolsConfig(BlockManager.currentBlock.name);
|
const currentToolSanitizeConfig = Sanitizer.getInlineToolsConfig(BlockManager.currentBlock.name);
|
||||||
|
|
||||||
/** If there is no pattern substitute - insert string as it is */
|
/** If there is no pattern substitute - insert string as it is */
|
||||||
document.execCommand('insertHTML', false, Sanitizer.clean(content.innerHTML, currentToolSanitizeConfig));
|
if (BlockManager.currentBlock.currentInput) {
|
||||||
|
document.execCommand('insertHTML', false, Sanitizer.clean(content.innerHTML, currentToolSanitizeConfig));
|
||||||
|
} else {
|
||||||
|
this.insertBlock(dataToInsert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -196,22 +196,25 @@ export default class UI extends Module {
|
||||||
*/
|
*/
|
||||||
private defaultBehaviour(event: KeyboardEvent): void {
|
private defaultBehaviour(event: KeyboardEvent): void {
|
||||||
const keyDownOnEditor = (event.target as HTMLElement).closest(`.${this.CSS.editorWrapper}`);
|
const keyDownOnEditor = (event.target as HTMLElement).closest(`.${this.CSS.editorWrapper}`);
|
||||||
|
const {currentBlock} = this.Editor.BlockManager;
|
||||||
|
const isMetaKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore keydowns on document
|
* Ignore keydowns on editor and meta keys
|
||||||
* clear pointer and close toolbar
|
|
||||||
*/
|
*/
|
||||||
if (!keyDownOnEditor) {
|
if (keyDownOnEditor || currentBlock && isMetaKey) {
|
||||||
/**
|
return;
|
||||||
* Remove all highlights and remove caret
|
|
||||||
*/
|
|
||||||
this.Editor.BlockManager.dropPointer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close Toolbar
|
|
||||||
*/
|
|
||||||
this.Editor.Toolbar.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all highlights and remove caret
|
||||||
|
*/
|
||||||
|
this.Editor.BlockManager.dropPointer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Toolbar
|
||||||
|
*/
|
||||||
|
this.Editor.Toolbar.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue