From e2ebd92568eebefaaab12535b548e2621d6a82e1 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Wed, 26 Aug 2020 10:50:00 -0700 Subject: [PATCH] Prepare for BeforeCutCopyEvent --- .../sidePane/eventViewer/EventViewPane.tsx | 9 +++- .../CopyPastePlugin.ts} | 6 +-- .../corePlugins/darkMode/DarkModePlugin.ts | 4 +- .../lib/editor/createEditorCore.ts | 4 +- ...tePluginTest.ts => copyPastePluginTest.ts} | 8 ++-- .../lib/event/BeforeCutCopyEvent.ts | 27 +++++++++++ .../lib/event/PluginEvent.ts | 2 + .../lib/event/PluginEventType.ts | 45 ++++++++++--------- packages/roosterjs-editor-types/lib/index.ts | 1 + .../lib/interface/CorePlugins.ts | 4 +- 10 files changed, 76 insertions(+), 34 deletions(-) rename packages/roosterjs-editor-core/lib/corePlugins/{corePaste/CorePastePlugin.ts => copyPaste/CopyPastePlugin.ts} (94%) rename packages/roosterjs-editor-core/test/corePlugins/{corePastePluginTest.ts => copyPastePluginTest.ts} (94%) create mode 100644 packages/roosterjs-editor-types/lib/event/BeforeCutCopyEvent.ts diff --git a/demo/scripts/controls/sidePane/eventViewer/EventViewPane.tsx b/demo/scripts/controls/sidePane/eventViewer/EventViewPane.tsx index dcbce22bf8e..a04b53f5b4c 100644 --- a/demo/scripts/controls/sidePane/eventViewer/EventViewPane.tsx +++ b/demo/scripts/controls/sidePane/eventViewer/EventViewPane.tsx @@ -33,6 +33,7 @@ const EventTypeMap = { [PluginEventType.PendingFormatStateChanged]: 'PendingFormatStateChanged', [PluginEventType.DarkModeChanged]: 'DarkModeChanged', [PluginEventType.Scroll]: 'Scroll', + [PluginEventType.BeforeCutCopy]: 'BeforeCutCopy', }; export default class EventViewPane extends React.Component< @@ -183,8 +184,14 @@ export default class EventViewPane extends React.Component< Operation={operation} Type={type}; Id={id} ); + + case PluginEventType.BeforeCutCopy: + const { isCut } = event; + return isCut={isCut ? 'true' : 'false'}; + + default: + return null; } - return null; } private clear = () => { diff --git a/packages/roosterjs-editor-core/lib/corePlugins/corePaste/CorePastePlugin.ts b/packages/roosterjs-editor-core/lib/corePlugins/copyPaste/CopyPastePlugin.ts similarity index 94% rename from packages/roosterjs-editor-core/lib/corePlugins/corePaste/CorePastePlugin.ts rename to packages/roosterjs-editor-core/lib/corePlugins/copyPaste/CopyPastePlugin.ts index 5082073751e..f4e5cd909c7 100644 --- a/packages/roosterjs-editor-core/lib/corePlugins/corePaste/CorePastePlugin.ts +++ b/packages/roosterjs-editor-core/lib/corePlugins/copyPaste/CopyPastePlugin.ts @@ -6,9 +6,9 @@ const CONTAINER_HTML = /** * @internal - * Core paste plugin for handling onPaste event and extract the pasted content + * Copy and paste plugin for handling onCopy and onPaste event */ -export default class CorePastePlugin implements EditorPlugin { +export default class CopyPastePlugin implements EditorPlugin { private editor: IEditor; private disposer: () => void; @@ -16,7 +16,7 @@ export default class CorePastePlugin implements EditorPlugin { * Get a friendly name of this plugin */ getName() { - return 'CorePaste'; + return 'CopyPaste'; } /** diff --git a/packages/roosterjs-editor-core/lib/corePlugins/darkMode/DarkModePlugin.ts b/packages/roosterjs-editor-core/lib/corePlugins/darkMode/DarkModePlugin.ts index 0d22f18ce4d..38636d67303 100644 --- a/packages/roosterjs-editor-core/lib/corePlugins/darkMode/DarkModePlugin.ts +++ b/packages/roosterjs-editor-core/lib/corePlugins/darkMode/DarkModePlugin.ts @@ -10,7 +10,7 @@ import { /** * @internal - * Copy plugin, hijacks copy events to normalize the content to the clipboard. + * Dark mode plugin, handles dark mode related color transform events */ export default class DarkModePlugin implements PluginWithState { private editor: IEditor; @@ -32,7 +32,7 @@ export default class DarkModePlugin implements PluginWithState { - let plugin: CorePastePlugin; +describe('CopyPastePlugin', () => { + let plugin: CopyPastePlugin; let handler: (event: Event) => void; let paste: jasmine.Spy; let tempNode: HTMLElement = null; @@ -19,7 +19,7 @@ describe('CorePastePlugin', () => { beforeEach(() => { handler = null; - plugin = new CorePastePlugin(); + plugin = new CopyPastePlugin(); spyOn(addDomEventHandler, 'default').and.callThrough(); paste = jasmine.createSpy('paste'); diff --git a/packages/roosterjs-editor-types/lib/event/BeforeCutCopyEvent.ts b/packages/roosterjs-editor-types/lib/event/BeforeCutCopyEvent.ts new file mode 100644 index 00000000000..41b2409f944 --- /dev/null +++ b/packages/roosterjs-editor-types/lib/event/BeforeCutCopyEvent.ts @@ -0,0 +1,27 @@ +import BasePluginEvent from './BasePluginEvent'; +import { PluginEventType } from './PluginEventType'; + +/** + * Provides a chance for plugin to change the content before it is copied from editor. + */ +export default interface BeforeCutCopyEvent extends BasePluginEvent { + /** + * Raw DOM event + */ + rawEvent: ClipboardEvent; + + /** + * An object contains all related data for pasting + */ + clonedRoot: HTMLDivElement; + + /** + * The selection range under cloned root + */ + range: Range; + + /** + * Whether this is a cut event + */ + isCut: boolean; +} diff --git a/packages/roosterjs-editor-types/lib/event/PluginEvent.ts b/packages/roosterjs-editor-types/lib/event/PluginEvent.ts index f924f38555c..c55d6408470 100644 --- a/packages/roosterjs-editor-types/lib/event/PluginEvent.ts +++ b/packages/roosterjs-editor-types/lib/event/PluginEvent.ts @@ -1,3 +1,4 @@ +import BeforeCutCopyEvent from './BeforeCutCopyEvent'; import BeforeDisposeEvent from './BeforeDisposeEvent'; import BeforePasteEvent from './BeforePasteEvent'; import ContentChangedEvent from './ContentChangedEvent'; @@ -12,6 +13,7 @@ import { PluginDomEvent } from './PluginDomEvent'; * Editor plugin event interface */ export type PluginEvent = + | BeforeCutCopyEvent | BeforePasteEvent | ContentChangedEvent | EntityOperationEvent diff --git a/packages/roosterjs-editor-types/lib/event/PluginEventType.ts b/packages/roosterjs-editor-types/lib/event/PluginEventType.ts index 5e561232e3a..45ca10f87e0 100644 --- a/packages/roosterjs-editor-types/lib/event/PluginEventType.ts +++ b/packages/roosterjs-editor-types/lib/event/PluginEventType.ts @@ -5,37 +5,42 @@ export const enum PluginEventType { /** * HTML KeyDown event */ - KeyDown, + KeyDown = 0, /** * HTML KeyPress event */ - KeyPress, + KeyPress = 1, /** * HTML KeyUp event */ - KeyUp, + KeyUp = 2, + + /** + * HTML Input / TextInput event + */ + Input = 3, /** * HTML CompositionEnd event */ - CompositionEnd, + CompositionEnd = 4, /** * HTML MouseDown event */ - MouseDown, + MouseDown = 5, /** * HTML MouseUp event */ - MouseUp, + MouseUp = 6, /** * Content changed event */ - ContentChanged, + ContentChanged = 7, /** * Extract Content with a DOM tree event @@ -43,45 +48,45 @@ export const enum PluginEventType { * Plugin can handle this event to remove the UI only markups to return clean HTML * by operating on a cloned DOM tree */ - ExtractContentWithDom, + ExtractContentWithDom = 8, /** - * Before Paste event, provide a chance to change paste content + * Before Paste event, provide a chance to change copied content */ - BeforePaste, + BeforeCutCopy = 9, /** - * Let plugin know editor is ready now + * Before Paste event, provide a chance to change paste content */ - EditorReady, + BeforePaste = 10, /** - * Let plugin know editor is about to dispose + * Let plugin know editor is ready now */ - BeforeDispose, + EditorReady = 11, /** - * HTML Input / TextInput event + * Let plugin know editor is about to dispose */ - Input, + BeforeDispose = 12, /** * Pending format state (bold, italic, underline, ... with collapsed selection) is changed */ - PendingFormatStateChanged, + PendingFormatStateChanged = 13, /** * Dark mode state is changed */ - DarkModeChanged, + DarkModeChanged = 14, /** * Scroll event triggered by scroll container */ - Scroll, + Scroll = 15, /** * Operating on an entity. See enum EntityOperation for more details about each operation */ - EntityOperation, + EntityOperation = 16, } diff --git a/packages/roosterjs-editor-types/lib/index.ts b/packages/roosterjs-editor-types/lib/index.ts index 823aee2fcff..0f76bb7a20f 100644 --- a/packages/roosterjs-editor-types/lib/index.ts +++ b/packages/roosterjs-editor-types/lib/index.ts @@ -22,6 +22,7 @@ export { RegionType } from './enum/RegionType'; export { TableOperation } from './enum/TableOperation'; // Event +export { default as BeforeCutCopyEvent } from './event/BeforeCutCopyEvent'; export { default as BasePluginEvent } from './event/BasePluginEvent'; export { default as BeforeDisposeEvent } from './event/BeforeDisposeEvent'; export { default as BeforePasteEvent } from './event/BeforePasteEvent'; diff --git a/packages/roosterjs-editor-types/lib/interface/CorePlugins.ts b/packages/roosterjs-editor-types/lib/interface/CorePlugins.ts index 75aca53bca4..878ac39c358 100644 --- a/packages/roosterjs-editor-types/lib/interface/CorePlugins.ts +++ b/packages/roosterjs-editor-types/lib/interface/CorePlugins.ts @@ -62,9 +62,9 @@ export default interface CorePlugins { readonly darkMode: PluginWithState; /** - * Core paste plugin for handling onPaste event and extract the pasted content + * Copy and paste plugin for handling onCopy and onPaste event */ - readonly paste: EditorPlugin; + readonly copyPaste: EditorPlugin; /** * Entity Plugin handles all operations related to an entity and generate entity specified events