diff --git a/demos/src/Examples/Default/React/index.jsx b/demos/src/Examples/Default/React/index.jsx index fddcfd2d3..f77ba9211 100644 --- a/demos/src/Examples/Default/React/index.jsx +++ b/demos/src/Examples/Default/React/index.jsx @@ -230,6 +230,6 @@ const content = ` export default () => { return ( - } extensions={extensions} content={content}> + } extensions={extensions} content={content} rendering={{ addTypeAttributes: true }}> ) } diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index 120bf95c7..f1d19fda8 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -16,7 +16,6 @@ import { ClipboardTextSerializer, Commands, Drop, Editable, FocusEvents, Keymap, Paste, Tabindex, } from './extensions/index.js' -import { Typenames } from './extensions/typenames.js' import { createDocument } from './helpers/createDocument.js' import { getAttributes } from './helpers/getAttributes.js' import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js' @@ -79,8 +78,9 @@ export class Editor extends EventEmitter { coreExtensionOptions: {}, enableInputRules: true, enablePasteRules: true, - enableCoreExtensions: { typenames: false }, + enableCoreExtensions: true, enableContentCheck: false, + addTypeAttributes: false, onBeforeCreate: () => null, onCreate: () => null, onUpdate: () => null, @@ -287,7 +287,6 @@ export class Editor extends EventEmitter { Tabindex, Drop, Paste, - Typenames, ].filter(ext => { if (typeof this.options.enableCoreExtensions === 'object') { return this.options.enableCoreExtensions[ext.name as keyof typeof this.options.enableCoreExtensions] !== false diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index a0fda44be..55392ab10 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -272,6 +272,7 @@ export class ExtensionManager { const extensionAttributes = this.attributes.filter( attribute => attribute.type === extension.name, ) + const context = { name: extension.name, options: extension.options, diff --git a/packages/core/src/extensions/typenames.ts b/packages/core/src/extensions/typenames.ts deleted file mode 100644 index b6e8cc9b3..000000000 --- a/packages/core/src/extensions/typenames.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Extension } from '../Extension.js' - -export const Typenames = Extension.create({ - name: 'typenames', - - addGlobalAttributes() { - return this.extensions.filter(extension => { - return extension.name !== 'text' && extension.name !== 'doc' - }).map(extension => ({ - types: [extension.name], - attributes: { - 'data-tiptap': { - default: extension.name, - rendered: true, - }, - }, - })) - }, -}) diff --git a/packages/core/src/helpers/getHTMLFromFragment.ts b/packages/core/src/helpers/getHTMLFromFragment.ts index 17ded0a16..a33a30586 100644 --- a/packages/core/src/helpers/getHTMLFromFragment.ts +++ b/packages/core/src/helpers/getHTMLFromFragment.ts @@ -3,11 +3,6 @@ import { DOMSerializer, Fragment, Schema } from '@tiptap/pm/model' export function getHTMLFromFragment(fragment: Fragment, schema: Schema): string { const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment) - // remove the data-tiptap attribute - documentFragment.querySelectorAll('[data-tiptap]').forEach(node => { - node.removeAttribute('data-tiptap') - }) - const temporaryDocument = document.implementation.createHTMLDocument() const container = temporaryDocument.createElement('div') diff --git a/packages/core/src/helpers/getSchemaByResolvedExtensions.ts b/packages/core/src/helpers/getSchemaByResolvedExtensions.ts index 25b856140..f7d8a53e3 100644 --- a/packages/core/src/helpers/getSchemaByResolvedExtensions.ts +++ b/packages/core/src/helpers/getSchemaByResolvedExtensions.ts @@ -106,10 +106,19 @@ export function getSchemaByResolvedExtensions(extensions: Extensions, editor?: E ) if (renderHTML) { - schema.toDOM = node => renderHTML({ - node, - HTMLAttributes: getRenderedAttributes(node, extensionAttributes), - }) + schema.toDOM = node => { + const HTMLAttributes = getRenderedAttributes(node, extensionAttributes) + + if (editor?.options.addTypeAttributes) { + HTMLAttributes['data-tiptap-element'] = '' + HTMLAttributes['data-tiptap-name'] = extension.name + } + + return renderHTML({ + node, + HTMLAttributes, + }) + } } const renderText = getExtensionField( @@ -186,10 +195,19 @@ export function getSchemaByResolvedExtensions(extensions: Extensions, editor?: E ) if (renderHTML) { - schema.toDOM = mark => renderHTML({ - mark, - HTMLAttributes: getRenderedAttributes(mark, extensionAttributes), - }) + schema.toDOM = mark => { + const HTMLAttributes = getRenderedAttributes(mark, extensionAttributes) + + if (editor?.options.addTypeAttributes) { + HTMLAttributes['data-tiptap-element'] = '' + HTMLAttributes['data-tiptap-name'] = extension.name + } + + return renderHTML({ + mark, + HTMLAttributes, + }) + } } return [extension.name, schema] diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 63d37c07f..7332a686b 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -114,7 +114,6 @@ export interface EditorOptions { | 'focusEvents' | 'keymap' | 'tabindex' - | 'typenames' | 'drop' | 'paste', false @@ -127,6 +126,10 @@ export interface EditorOptions { * @default false */ enableContentCheck: boolean; + /** + * If `true`, all editor nodes will have a `data-tiptap-element` attribute with the node type name. + */ + addTypeAttributes?: boolean; onBeforeCreate: (props: EditorEvents['beforeCreate']) => void; onCreate: (props: EditorEvents['create']) => void; /**