From 4d29be3e834b49ffde8746da834f219e8f038e7b Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Mon, 17 Jul 2023 16:38:29 +0400 Subject: [PATCH] Add `config.canvas.allowExternalDrop` option #5242 --- src/canvas/config/config.ts | 10 ++++++++++ src/utils/Droppable.ts | 13 +++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/canvas/config/config.ts b/src/canvas/config/config.ts index baf78e90f..770d166aa 100644 --- a/src/canvas/config/config.ts +++ b/src/canvas/config/config.ts @@ -61,6 +61,15 @@ export interface CanvasConfig { * This option allows to customize, by a selector, which element should not be considered textable. */ notTextable?: string[]; + + /** + * By default, the editor allows to drop external elements by relying on the native HTML5 + * drag & drop API (eg. like a D&D of an image file from your desktop). + * If you want to customize how external elements are interpreted by the editor, you can rely + * on `canvas:dragdata` event, eg. https://github.com/GrapesJS/grapesjs/discussions/3849 + * @default true + */ + allowExternalDrop?: boolean; } const config: CanvasConfig = { @@ -78,6 +87,7 @@ const config: CanvasConfig = { * ::-webkit-scrollbar { width: 10px } `, notTextable: ['button', 'a', 'input[type=checkbox]', 'input[type=radio]'], + allowExternalDrop: true, }; export default config; diff --git a/src/utils/Droppable.ts b/src/utils/Droppable.ts index d3654a13e..07824d28b 100644 --- a/src/utils/Droppable.ts +++ b/src/utils/Droppable.ts @@ -83,10 +83,13 @@ export default class Droppable { this.over ? this.endDrop(cancel) : this.__customTglEff(false); } + /** + * This function is expected to be always executed at the end of d&d. + */ endDrop(cancel?: boolean, ev?: Event) { const { em, dragStop } = this; this.counter = 0; - dragStop && dragStop(cancel); + dragStop && dragStop(cancel || !this.over); this.__customTglEff(false); em.trigger('canvas:dragend', ev); } @@ -103,6 +106,12 @@ export default class Droppable { handleDragEnter(ev: DragEvent | Event) { const { em, canvas } = this; const dt = (ev as DragEvent).dataTransfer; + const dragContentOrigin = em.get('dragContent'); + + if (!dragContentOrigin && !canvas.getConfig().allowExternalDrop) { + return; + } + this.updateCounter(1, ev); if (this.over) return; this.over = true; @@ -110,7 +119,7 @@ export default class Droppable { // For security reason I can't read the drag data on dragenter, but // as I need it for the Sorter context I will use `dragContent` or just // any not empty element - let content = em.get('dragContent') || '
'; + let content = dragContentOrigin || '
'; let dragStop: DragStop; let dragContent; em.stopDefault();