Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 1x 1x 1x 14x 14x 14x 14x 25x 14x 1x 1x 12x 12x 12x 2x 1x 15x 15x 12x 12x 15x 15x 1x 9x 7x 2x 5x 5x 5x 3x 7x 1x | import { handleDroppedContent } from './utils/handleDroppedContent';
import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
/**
* Options for DragAndDrop plugin
*/
export interface DragAndDropOptions {
/**
* Forbidden elements that cannot be dropped in the editor
* @default ['iframe']
*/
forbiddenElements?: string[];
}
const DefaultOptions = {
forbiddenElements: ['iframe'],
};
/**
* DragAndDrop plugin, handles ContentChanged event when change source is "Drop"
* to sanitize dropped content, similar to how PastePlugin sanitizes pasted content.
*/
export class DragAndDropPlugin implements EditorPlugin {
private editor: IEditor | null = null;
private forbiddenElements: string[] = [];
private isInternalDragging: boolean = false;
private disposer: (() => void) | null = null;
/**
* Construct a new instance of DragAndDropPlugin
*/
constructor(options: DragAndDropOptions = DefaultOptions) {
this.forbiddenElements = options.forbiddenElements ?? [];
}
/**
* Get name of this plugin
*/
getName() {
return 'DragAndDrop';
}
/**
* The first method that editor will call to a plugin when editor is initializing.
* It will pass in the editor instance, plugin should take this chance to save the
* editor reference so that it can call to any editor method or format API later.
* @param editor The editor object
*/
initialize(editor: IEditor) {
this.editor = editor;
this.disposer = editor.attachDomEvent({
dragstart: {
beforeDispatch: _ev => {
this.isInternalDragging = true;
},
},
});
}
/**
* The last method that editor will call to a plugin before it is disposed.
* Plugin can take this chance to clear the reference to editor. After this method is
* called, plugin should not call to any editor method since it will result in error.
*/
dispose() {
this.editor = null;
if (this.disposer) {
this.disposer();
this.disposer = null;
}
this.isInternalDragging = false;
this.forbiddenElements = [];
}
/**
* Core method for a plugin. Once an event happens in editor, editor will call this
* method of each plugin to handle the event as long as the event is not handled
* exclusively by another plugin.
* @param event The event to handle:
*/
onPluginEvent(event: PluginEvent) {
if (this.editor && event.eventType == 'beforeDrop') {
if (this.isInternalDragging) {
this.isInternalDragging = false;
} else {
const dropEvent = event.rawEvent;
const html = dropEvent.dataTransfer?.getData('text/html');
if (html) {
handleDroppedContent(this.editor, dropEvent, html, this.forbiddenElements);
}
}
return;
}
}
}
|