import { Result } from '@ephox/katamari'; import Editor from '../api/Editor'; import * as Events from '../api/Events'; import DomParser from '../api/html/DomParser'; import HtmlSerializer from '../api/html/Serializer'; import { EditorEvent } from '../api/util/EventDispatcher'; import { Content, GetContentArgs, isTreeNode, SetContentArgs } from './ContentTypes'; const serializeContent = (content: Content): string => isTreeNode(content) ? HtmlSerializer({ validate: false }).serialize(content) : content; const withSerializedContent = >(content: Content, fireEvent: (content: string) => R): R & { content: Content } => { const serializedContent = serializeContent(content); const eventArgs = fireEvent(serializedContent); if (eventArgs.isDefaultPrevented()) { return eventArgs; } else if (isTreeNode(content)) { // Restore the content type back to being an AstNode. If the content has changed we need to // re-parse the new content, otherwise we can return the input. if (eventArgs.content !== serializedContent) { const rootNode = DomParser({ validate: false, forced_root_block: false }).parse(eventArgs.content, { context: content.name }); return { ...eventArgs, content: rootNode }; } else { return { ...eventArgs, content }; } } else { return eventArgs; } }; const preProcessGetContent = (editor: Editor, args: T): Result => { if (args.no_events) { return Result.value(args); } else { const eventArgs = Events.fireBeforeGetContent(editor, args); if (eventArgs.isDefaultPrevented()) { return Result.error(Events.fireGetContent(editor, { content: '', ...eventArgs }).content); } else { return Result.value(eventArgs); } } }; const postProcessGetContent = (editor: Editor, content: Content, args: T): Content => { if (args.no_events) { return content; } else { const processedEventArgs = withSerializedContent(content, (c) => Events.fireGetContent(editor, { ...args, content: c })); return processedEventArgs.content; } }; const preProcessSetContent = (editor: Editor, args: T): Result => { if (args.no_events) { return Result.value(args); } else { const processedEventArgs = withSerializedContent(args.content, (content) => Events.fireBeforeSetContent(editor, { ...args, content })); if (processedEventArgs.isDefaultPrevented()) { Events.fireSetContent(editor, processedEventArgs); return Result.error(undefined); } else { return Result.value(processedEventArgs); } } }; const postProcessSetContent = (editor: Editor, content: string, args: T): void => { if (!args.no_events) { Events.fireSetContent(editor, { ...args, content }); } }; export { preProcessGetContent, postProcessGetContent, preProcessSetContent, postProcessSetContent };