import { Extension } from '@tiptap/core' import { InvisibleCharactersPlugin, InvisibleCharactersPluginKey } from './plugin/index.js' import { HardBreakNode } from './plugin/invisible-characters/hardBreak.js' import { ParagraphNode } from './plugin/invisible-characters/paragraph.js' import { SpaceCharacter } from './plugin/invisible-characters/space.js' import type { InvisibleCharactersOptions } from './types.js' export { HardBreakNode, ParagraphNode, SpaceCharacter } declare module '@tiptap/core' { interface Commands { invisibleCharacters: { /** * Show invisible characters */ showInvisibleCharacters: (show?: boolean) => ReturnType /** * Hide invisible characters */ hideInvisibleCharacters: () => ReturnType /** * Toggle invisible characters */ toggleInvisibleCharacters: () => ReturnType } } } export const InvisibleCharacters = Extension.create({ name: 'invisibleCharacters', addOptions() { return { visible: true, builders: [new SpaceCharacter(), new ParagraphNode(), new HardBreakNode()], injectCSS: true, injectNonce: undefined, } }, addProseMirrorPlugins() { return [InvisibleCharactersPlugin(this.editor.state, this.options)] }, addStorage() { return { visibility: () => this.options.visible, } }, onBeforeCreate() { this.storage.visibility = () => { return InvisibleCharactersPluginKey.getState(this.editor.state)?.visible } }, addCommands() { return { showInvisibleCharacters: (visibility = true) => ({ dispatch, tr }) => { if (dispatch) { tr.setMeta('setInvisibleCharactersVisible', visibility) } return true }, hideInvisibleCharacters: () => ({ dispatch, tr }) => { if (dispatch) { tr.setMeta('setInvisibleCharactersVisible', false) } return true }, toggleInvisibleCharacters: () => ({ dispatch, tr, state }) => { const visibility = !InvisibleCharactersPluginKey.getState(state)?.visible if (dispatch) { tr.setMeta('setInvisibleCharactersVisible', visibility) } return true }, } }, }) export default InvisibleCharacters