@tiptap/extension-details 3.27.4 → 3.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34,7 +34,11 @@ var import_state = require("@tiptap/pm/state");
34
34
  // src/helpers/isNodeVisible.ts
35
35
  var isNodeVisible = (position, editor) => {
36
36
  const node = editor.view.domAtPos(position).node;
37
- const isOpen = node.offsetParent !== null;
37
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
38
+ if (!element) {
39
+ return false;
40
+ }
41
+ const isOpen = element.offsetParent !== null;
38
42
  return isOpen;
39
43
  };
40
44
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/details.ts","../src/helpers/isNodeVisible.ts","../src/helpers/findClosestVisibleNode.ts","../src/helpers/setGapCursor.ts","../src/content/details-content.ts","../src/summary/details-summary.ts"],"sourcesContent":["import { Details } from './details.js'\n\nexport * from './content/index.js'\nexport * from './details.js'\nexport * from './summary/index.js'\n\nexport default Details\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findChildren,\n findParentNode,\n isActive,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey, Selection, TextSelection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nimport { findClosestVisibleNode } from './helpers/findClosestVisibleNode.js'\nimport { isNodeVisible } from './helpers/isNodeVisible.js'\nimport { setGapCursor } from './helpers/setGapCursor.js'\n\nexport interface DetailsRenderToggleButtonOptions {\n /**\n * The toggle button element rendered by the node view.\n */\n element: HTMLButtonElement\n /**\n * The current open state of the details node.\n */\n isOpen: boolean\n /**\n * The current node used to derive toggle button state.\n */\n node: ProseMirrorNode\n}\n\nexport interface DetailsOptions {\n /**\n * Specify if the open status should be saved in the document. Defaults to `false`.\n */\n persist: boolean\n /**\n * Specifies a CSS class that is set when toggling the content. Defaults to `is-open`.\n */\n openClassName: string\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n /**\n * Customizes the rendered toggle button.\n */\n renderToggleButton: (options: DetailsRenderToggleButtonOptions) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n details: {\n /**\n * Set a details node\n */\n setDetails: () => ReturnType\n /**\n * Unset a details node\n */\n unsetDetails: () => ReturnType\n }\n }\n}\n\nexport const Details = Node.create<DetailsOptions>({\n name: 'details',\n\n content: 'detailsSummary detailsContent',\n\n group: 'block',\n\n defining: true,\n\n isolating: true,\n\n // @ts-ignore reason: `allowGapCursor` is not a valid property by default, but the `GapCursor` extension adds it to the Nodeconfig type\n allowGapCursor: false,\n\n addOptions() {\n return {\n persist: false,\n openClassName: 'is-open',\n HTMLAttributes: {},\n renderToggleButton: ({ element, isOpen }) => {\n element.setAttribute(\n 'aria-label',\n isOpen ? 'Collapse details content' : 'Expand details content',\n )\n },\n }\n },\n\n addAttributes() {\n if (!this.options.persist) {\n return []\n }\n\n return {\n open: {\n default: false,\n parseHTML: element => element.hasAttribute('open'),\n renderHTML: ({ open }) => {\n if (!open) {\n return {}\n }\n\n return { open: '' }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'details',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['details', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'details',\n content: 'block',\n }),\n\n addNodeView() {\n return ({ editor, getPos, node, HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n const toggle = document.createElement('button')\n\n toggle.type = 'button'\n\n const renderToggleButton = (options: Omit<DetailsRenderToggleButtonOptions, 'element'>) => {\n this.options.renderToggleButton({\n element: toggle,\n ...options,\n })\n }\n\n dom.append(toggle)\n\n const content = document.createElement('div')\n\n dom.append(content)\n\n const toggleDetailsContent = (options?: { setToValue?: boolean; node?: ProseMirrorNode }) => {\n const { setToValue, node: currentNode = node } = options || {}\n\n if (setToValue !== undefined) {\n if (setToValue) {\n if (dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.add(this.options.openClassName)\n } else {\n if (!dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.remove(this.options.openClassName)\n }\n } else {\n dom.classList.toggle(this.options.openClassName)\n }\n\n const isOpen = dom.classList.contains(this.options.openClassName)\n\n renderToggleButton({\n isOpen,\n node: currentNode,\n })\n\n const event = new Event('toggleDetailsContent')\n const detailsContent = content.querySelector(':scope > div[data-type=\"detailsContent\"]')\n\n detailsContent?.dispatchEvent(event)\n }\n\n renderToggleButton({\n isOpen: Boolean(node.attrs.open),\n node,\n })\n\n if (node.attrs.open) {\n setTimeout(() => toggleDetailsContent())\n }\n\n toggle.addEventListener('click', () => {\n toggleDetailsContent()\n\n if (!this.options.persist) {\n editor.commands.focus(undefined, { scrollIntoView: false })\n\n return\n }\n\n if (editor.isEditable && typeof getPos === 'function') {\n const { from, to } = editor.state.selection\n\n editor\n .chain()\n .command(({ tr }) => {\n const pos = getPos()\n\n if (typeof pos !== 'number') {\n return false\n }\n\n const currentNode = tr.doc.nodeAt(pos)\n\n if (currentNode?.type !== this.type) {\n return false\n }\n\n tr.setNodeMarkup(pos, undefined, {\n open: !currentNode.attrs.open,\n })\n\n return true\n })\n .setTextSelection({\n from,\n to,\n })\n .focus(undefined, { scrollIntoView: false })\n .run()\n }\n })\n\n return {\n dom,\n contentDOM: content,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n const target = mutation.target\n const isInsideWrapper = dom.contains(target)\n const isInsideToggleButton = toggle.contains(target)\n\n return isInsideToggleButton || !isInsideWrapper || dom === target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n // Only update the open state if set\n if (updatedNode.attrs.open !== undefined) {\n toggleDetailsContent({\n setToValue: updatedNode.attrs.open,\n node: updatedNode,\n })\n } else {\n renderToggleButton({\n isOpen: dom.classList.contains(this.options.openClassName),\n node: updatedNode,\n })\n }\n\n return true\n },\n }\n }\n },\n\n addCommands() {\n return {\n setDetails:\n () =>\n ({ state, chain }) => {\n const { schema, selection } = state\n const { $from, $to } = selection\n const range = $from.blockRange($to)\n\n if (!range) {\n return false\n }\n\n const slice = state.doc.slice(range.start, range.end)\n const match = schema.nodes.detailsContent.contentMatch.matchFragment(slice.content)\n\n if (!match) {\n return false\n }\n\n const content = slice.toJSON()?.content || []\n\n return chain()\n .insertContentAt(\n { from: range.start, to: range.end },\n {\n type: this.name,\n content: [\n {\n type: 'detailsSummary',\n },\n {\n type: 'detailsContent',\n content,\n },\n ],\n },\n )\n .setTextSelection(range.start + 2)\n .run()\n },\n\n unsetDetails:\n () =>\n ({ state, chain }) => {\n const { selection, schema } = state\n const details = findParentNode(node => node.type === this.type)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsSummary,\n )\n const detailsContents = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsSummaries.length || !detailsContents.length) {\n return false\n }\n\n const detailsSummary = detailsSummaries[0]\n const detailsContent = detailsContents[0]\n const from = details.pos\n const $from = state.doc.resolve(from)\n const to = from + details.node.nodeSize\n const range = { from, to }\n const content = (detailsContent.node.content.toJSON() as []) || []\n const defaultTypeForSummary = $from.parent.type.contentMatch.defaultType\n\n // TODO: this may break for some custom schemas\n const summaryContent = defaultTypeForSummary\n ?.create(null, detailsSummary.node.content)\n .toJSON()\n const mergedContent = [summaryContent, ...content]\n\n return chain()\n .insertContentAt(range, mergedContent)\n .setTextSelection(from + 1)\n .run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => {\n const { schema, selection } = this.editor.state\n const { empty, $anchor } = selection\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n // for some reason safari removes the whole text content within a `<summary>`tag on backspace\n // so we have to remove the text manually\n // see: https://discuss.prosemirror.net/t/safari-backspace-bug-with-details-tag/4223\n if ($anchor.parentOffset !== 0) {\n return this.editor.commands.command(({ tr }) => {\n const from = $anchor.pos - 1\n const to = $anchor.pos\n\n tr.delete(from, to)\n\n return true\n })\n }\n\n return this.editor.commands.unsetDetails()\n },\n\n // Creates a new node below it if it is closed.\n // Otherwise inside `DetailsContent`.\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { schema, selection } = state\n const { $head } = selection\n\n if ($head.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n const isVisible = isNodeVisible($head.after() + 1, editor)\n const above = isVisible ? state.doc.nodeAt($head.after()) : $head.node(-2)\n\n if (!above) {\n return false\n }\n\n const after = isVisible ? 0 : $head.indexAfter(-1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const pos = isVisible ? $head.after() + 1 : $head.after(-1)\n const tr = state.tr.replaceWith(pos, pos, node)\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowRight: ({ editor }) => {\n return setGapCursor(editor, 'right')\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowDown: ({ editor }) => {\n return setGapCursor(editor, 'down')\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [\n // This plugin prevents text selections within the hidden content in `DetailsContent`.\n // The cursor is moved to the next visible position.\n new Plugin({\n key: new PluginKey('detailsSelection'),\n appendTransaction: (transactions, oldState, newState) => {\n const { editor, type } = this\n const isComposing = editor.view.composing\n\n if (isComposing) {\n return\n }\n\n const selectionSet = transactions.some(transaction => transaction.selectionSet)\n\n if (!selectionSet || !oldState.selection.empty || !newState.selection.empty) {\n return\n }\n\n const detailsIsActive = isActive(newState, type.name)\n\n if (!detailsIsActive) {\n return\n }\n\n const { $from } = newState.selection\n const isVisible = isNodeVisible($from.pos, editor)\n\n if (isVisible) {\n return\n }\n\n const details = findClosestVisibleNode($from, node => node.type === type, editor)\n\n if (!details) {\n return\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === newState.schema.nodes.detailsSummary,\n )\n\n if (!detailsSummaries.length) {\n return\n }\n\n const detailsSummary = detailsSummaries[0]\n const selectionDirection =\n oldState.selection.from < newState.selection.from ? 'forward' : 'backward'\n const correctedPosition =\n selectionDirection === 'forward'\n ? details.start + detailsSummary.pos\n : details.pos + detailsSummary.pos + detailsSummary.node.nodeSize\n const selection = TextSelection.create(newState.doc, correctedPosition)\n const transaction = newState.tr.setSelection(selection)\n\n return transaction\n },\n }),\n ]\n },\n})\n","import type { Editor } from '@tiptap/core'\n\nexport const isNodeVisible = (position: number, editor: Editor): boolean => {\n const node = editor.view.domAtPos(position).node as HTMLElement\n const isOpen = node.offsetParent !== null\n\n return isOpen\n}\n","import type { Editor, Predicate } from '@tiptap/core'\nimport type { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const findClosestVisibleNode = (\n $pos: ResolvedPos,\n predicate: Predicate,\n editor: Editor,\n):\n | {\n pos: number\n start: number\n depth: number\n node: ProseMirrorNode\n }\n | undefined => {\n for (let i = $pos.depth; i > 0; i -= 1) {\n const node = $pos.node(i)\n const match = predicate(node)\n const isVisible = isNodeVisible($pos.start(i), editor)\n\n if (match && isVisible) {\n return {\n pos: i > 0 ? $pos.before(i) : 0,\n start: $pos.start(i),\n depth: i,\n node,\n }\n }\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { findChildren, findParentNode } from '@tiptap/core'\nimport { GapCursor } from '@tiptap/pm/gapcursor'\nimport type { ResolvedPos } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const setGapCursor = (editor: Editor, direction: 'down' | 'right') => {\n const { state, view, extensionManager } = editor\n const { schema, selection } = state\n const { empty, $anchor } = selection\n const hasGapCursorExtension = !!extensionManager.extensions.find(\n extension => extension.name === 'gapCursor',\n )\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary || !hasGapCursorExtension) {\n return false\n }\n\n if (direction === 'right' && $anchor.parentOffset !== $anchor.parent.nodeSize - 2) {\n return false\n }\n\n const details = findParentNode(node => node.type === schema.nodes.details)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsContent = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsContent.length) {\n return false\n }\n\n const isOpen = isNodeVisible(details.start + detailsContent[0].pos + 1, editor)\n\n if (isOpen) {\n return false\n }\n\n const $position = state.doc.resolve(details.pos + details.node.nodeSize)\n const $validPosition = GapCursor.findFrom($position, 1, false) as unknown as null | ResolvedPos\n\n if (!$validPosition) {\n return false\n }\n\n const { tr } = state\n const gapCursorSelection = new GapCursor($validPosition) as Selection\n\n tr.setSelection(gapCursorSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n}\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findParentNode,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport { Selection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nexport interface DetailsContentOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsContent = Node.create<DetailsContentOptions>({\n name: 'detailsContent',\n\n content: 'block+',\n\n defining: true,\n\n selectable: false,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `div[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }),\n 0,\n ]\n },\n\n addNodeView() {\n return ({ HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n hidden: 'hidden',\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n dom.addEventListener('toggleDetailsContent', () => {\n dom.toggleAttribute('hidden')\n })\n\n return {\n dom,\n contentDOM: dom,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n return !dom.contains(mutation.target) || dom === mutation.target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n return true\n },\n }\n }\n },\n\n addKeyboardShortcuts() {\n return {\n // Escape node on double enter\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { selection } = state\n const { $from, empty } = selection\n const detailsContent = findParentNode(node => node.type === this.type)(selection)\n\n if (!empty || !detailsContent || !detailsContent.node.childCount) {\n return false\n }\n\n const fromIndex = $from.index(detailsContent.depth)\n const { childCount } = detailsContent.node\n const isAtEnd = childCount === fromIndex + 1\n\n if (!isAtEnd) {\n return false\n }\n\n const defaultChildType = detailsContent.node.type.contentMatch.defaultType\n const defaultChildNode = defaultChildType?.createAndFill()\n\n if (!defaultChildNode) {\n return false\n }\n\n const $childPos = state.doc.resolve(detailsContent.pos + 1)\n const lastChildIndex = childCount - 1\n const lastChildNode = detailsContent.node.child(lastChildIndex)\n const lastChildPos = $childPos.posAtIndex(lastChildIndex, detailsContent.depth)\n const lastChildNodeIsEmpty = lastChildNode.eq(defaultChildNode)\n\n if (!lastChildNodeIsEmpty) {\n return false\n }\n\n // get parent of details node\n const above = $from.node(-3)\n\n if (!above) {\n return false\n }\n\n // get default node type after details node\n const after = $from.indexAfter(-3)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const { tr } = state\n const pos = $from.after(-2)\n\n tr.replaceWith(pos, pos, node)\n\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n\n const deleteFrom = lastChildPos\n const deleteTo = lastChildPos + lastChildNode.nodeSize\n\n tr.delete(deleteFrom, deleteTo)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n }\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsContent',\n }),\n})\n","import { createBlockMarkdownSpec, mergeAttributes, Node } from '@tiptap/core'\n\nexport interface DetailsSummaryOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsSummary = Node.create<DetailsSummaryOptions>({\n name: 'detailsSummary',\n\n content: 'text*',\n\n defining: true,\n\n selectable: false,\n\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'summary',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['summary', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsSummary',\n content: 'inline',\n }),\n})\n"],"mappings":"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","names":["import_core","transaction","import_core","import_state","node","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/details.ts","../src/helpers/isNodeVisible.ts","../src/helpers/findClosestVisibleNode.ts","../src/helpers/setGapCursor.ts","../src/content/details-content.ts","../src/summary/details-summary.ts"],"sourcesContent":["import { Details } from './details.js'\n\nexport * from './content/index.js'\nexport * from './details.js'\nexport * from './summary/index.js'\n\nexport default Details\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findChildren,\n findParentNode,\n isActive,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey, Selection, TextSelection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nimport { findClosestVisibleNode } from './helpers/findClosestVisibleNode.js'\nimport { isNodeVisible } from './helpers/isNodeVisible.js'\nimport { setGapCursor } from './helpers/setGapCursor.js'\n\nexport interface DetailsRenderToggleButtonOptions {\n /**\n * The toggle button element rendered by the node view.\n */\n element: HTMLButtonElement\n /**\n * The current open state of the details node.\n */\n isOpen: boolean\n /**\n * The current node used to derive toggle button state.\n */\n node: ProseMirrorNode\n}\n\nexport interface DetailsOptions {\n /**\n * Specify if the open status should be saved in the document. Defaults to `false`.\n */\n persist: boolean\n /**\n * Specifies a CSS class that is set when toggling the content. Defaults to `is-open`.\n */\n openClassName: string\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n /**\n * Customizes the rendered toggle button.\n */\n renderToggleButton: (options: DetailsRenderToggleButtonOptions) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n details: {\n /**\n * Set a details node\n */\n setDetails: () => ReturnType\n /**\n * Unset a details node\n */\n unsetDetails: () => ReturnType\n }\n }\n}\n\nexport const Details = Node.create<DetailsOptions>({\n name: 'details',\n\n content: 'detailsSummary detailsContent',\n\n group: 'block',\n\n defining: true,\n\n isolating: true,\n\n // @ts-ignore reason: `allowGapCursor` is not a valid property by default, but the `GapCursor` extension adds it to the Nodeconfig type\n allowGapCursor: false,\n\n addOptions() {\n return {\n persist: false,\n openClassName: 'is-open',\n HTMLAttributes: {},\n renderToggleButton: ({ element, isOpen }) => {\n element.setAttribute(\n 'aria-label',\n isOpen ? 'Collapse details content' : 'Expand details content',\n )\n },\n }\n },\n\n addAttributes() {\n if (!this.options.persist) {\n return []\n }\n\n return {\n open: {\n default: false,\n parseHTML: element => element.hasAttribute('open'),\n renderHTML: ({ open }) => {\n if (!open) {\n return {}\n }\n\n return { open: '' }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'details',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['details', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'details',\n content: 'block',\n }),\n\n addNodeView() {\n return ({ editor, getPos, node, HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n const toggle = document.createElement('button')\n\n toggle.type = 'button'\n\n const renderToggleButton = (options: Omit<DetailsRenderToggleButtonOptions, 'element'>) => {\n this.options.renderToggleButton({\n element: toggle,\n ...options,\n })\n }\n\n dom.append(toggle)\n\n const content = document.createElement('div')\n\n dom.append(content)\n\n const toggleDetailsContent = (options?: { setToValue?: boolean; node?: ProseMirrorNode }) => {\n const { setToValue, node: currentNode = node } = options || {}\n\n if (setToValue !== undefined) {\n if (setToValue) {\n if (dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.add(this.options.openClassName)\n } else {\n if (!dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.remove(this.options.openClassName)\n }\n } else {\n dom.classList.toggle(this.options.openClassName)\n }\n\n const isOpen = dom.classList.contains(this.options.openClassName)\n\n renderToggleButton({\n isOpen,\n node: currentNode,\n })\n\n const event = new Event('toggleDetailsContent')\n const detailsContent = content.querySelector(':scope > div[data-type=\"detailsContent\"]')\n\n detailsContent?.dispatchEvent(event)\n }\n\n renderToggleButton({\n isOpen: Boolean(node.attrs.open),\n node,\n })\n\n if (node.attrs.open) {\n setTimeout(() => toggleDetailsContent())\n }\n\n toggle.addEventListener('click', () => {\n toggleDetailsContent()\n\n if (!this.options.persist) {\n editor.commands.focus(undefined, { scrollIntoView: false })\n\n return\n }\n\n if (editor.isEditable && typeof getPos === 'function') {\n const { from, to } = editor.state.selection\n\n editor\n .chain()\n .command(({ tr }) => {\n const pos = getPos()\n\n if (typeof pos !== 'number') {\n return false\n }\n\n const currentNode = tr.doc.nodeAt(pos)\n\n if (currentNode?.type !== this.type) {\n return false\n }\n\n tr.setNodeMarkup(pos, undefined, {\n open: !currentNode.attrs.open,\n })\n\n return true\n })\n .setTextSelection({\n from,\n to,\n })\n .focus(undefined, { scrollIntoView: false })\n .run()\n }\n })\n\n return {\n dom,\n contentDOM: content,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n const target = mutation.target\n const isInsideWrapper = dom.contains(target)\n const isInsideToggleButton = toggle.contains(target)\n\n return isInsideToggleButton || !isInsideWrapper || dom === target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n // Only update the open state if set\n if (updatedNode.attrs.open !== undefined) {\n toggleDetailsContent({\n setToValue: updatedNode.attrs.open,\n node: updatedNode,\n })\n } else {\n renderToggleButton({\n isOpen: dom.classList.contains(this.options.openClassName),\n node: updatedNode,\n })\n }\n\n return true\n },\n }\n }\n },\n\n addCommands() {\n return {\n setDetails:\n () =>\n ({ state, chain }) => {\n const { schema, selection } = state\n const { $from, $to } = selection\n const range = $from.blockRange($to)\n\n if (!range) {\n return false\n }\n\n const slice = state.doc.slice(range.start, range.end)\n const match = schema.nodes.detailsContent.contentMatch.matchFragment(slice.content)\n\n if (!match) {\n return false\n }\n\n const content = slice.toJSON()?.content || []\n\n return chain()\n .insertContentAt(\n { from: range.start, to: range.end },\n {\n type: this.name,\n content: [\n {\n type: 'detailsSummary',\n },\n {\n type: 'detailsContent',\n content,\n },\n ],\n },\n )\n .setTextSelection(range.start + 2)\n .run()\n },\n\n unsetDetails:\n () =>\n ({ state, chain }) => {\n const { selection, schema } = state\n const details = findParentNode(node => node.type === this.type)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsSummary,\n )\n const detailsContents = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsSummaries.length || !detailsContents.length) {\n return false\n }\n\n const detailsSummary = detailsSummaries[0]\n const detailsContent = detailsContents[0]\n const from = details.pos\n const $from = state.doc.resolve(from)\n const to = from + details.node.nodeSize\n const range = { from, to }\n const content = (detailsContent.node.content.toJSON() as []) || []\n const defaultTypeForSummary = $from.parent.type.contentMatch.defaultType\n\n // TODO: this may break for some custom schemas\n const summaryContent = defaultTypeForSummary\n ?.create(null, detailsSummary.node.content)\n .toJSON()\n const mergedContent = [summaryContent, ...content]\n\n return chain()\n .insertContentAt(range, mergedContent)\n .setTextSelection(from + 1)\n .run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => {\n const { schema, selection } = this.editor.state\n const { empty, $anchor } = selection\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n // for some reason safari removes the whole text content within a `<summary>`tag on backspace\n // so we have to remove the text manually\n // see: https://discuss.prosemirror.net/t/safari-backspace-bug-with-details-tag/4223\n if ($anchor.parentOffset !== 0) {\n return this.editor.commands.command(({ tr }) => {\n const from = $anchor.pos - 1\n const to = $anchor.pos\n\n tr.delete(from, to)\n\n return true\n })\n }\n\n return this.editor.commands.unsetDetails()\n },\n\n // Creates a new node below it if it is closed.\n // Otherwise inside `DetailsContent`.\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { schema, selection } = state\n const { $head } = selection\n\n if ($head.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n const isVisible = isNodeVisible($head.after() + 1, editor)\n const above = isVisible ? state.doc.nodeAt($head.after()) : $head.node(-2)\n\n if (!above) {\n return false\n }\n\n const after = isVisible ? 0 : $head.indexAfter(-1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const pos = isVisible ? $head.after() + 1 : $head.after(-1)\n const tr = state.tr.replaceWith(pos, pos, node)\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowRight: ({ editor }) => {\n return setGapCursor(editor, 'right')\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowDown: ({ editor }) => {\n return setGapCursor(editor, 'down')\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [\n // This plugin prevents text selections within the hidden content in `DetailsContent`.\n // The cursor is moved to the next visible position.\n new Plugin({\n key: new PluginKey('detailsSelection'),\n appendTransaction: (transactions, oldState, newState) => {\n const { editor, type } = this\n const isComposing = editor.view.composing\n\n if (isComposing) {\n return\n }\n\n const selectionSet = transactions.some(transaction => transaction.selectionSet)\n\n if (!selectionSet || !oldState.selection.empty || !newState.selection.empty) {\n return\n }\n\n const detailsIsActive = isActive(newState, type.name)\n\n if (!detailsIsActive) {\n return\n }\n\n const { $from } = newState.selection\n const isVisible = isNodeVisible($from.pos, editor)\n\n if (isVisible) {\n return\n }\n\n const details = findClosestVisibleNode($from, node => node.type === type, editor)\n\n if (!details) {\n return\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === newState.schema.nodes.detailsSummary,\n )\n\n if (!detailsSummaries.length) {\n return\n }\n\n const detailsSummary = detailsSummaries[0]\n const selectionDirection =\n oldState.selection.from < newState.selection.from ? 'forward' : 'backward'\n const correctedPosition =\n selectionDirection === 'forward'\n ? details.start + detailsSummary.pos\n : details.pos + detailsSummary.pos + detailsSummary.node.nodeSize\n const selection = TextSelection.create(newState.doc, correctedPosition)\n const transaction = newState.tr.setSelection(selection)\n\n return transaction\n },\n }),\n ]\n },\n})\n","import type { Editor } from '@tiptap/core'\n\nexport const isNodeVisible = (position: number, editor: Editor): boolean => {\n const node = editor.view.domAtPos(position).node\n // Use the node for elements and its parent for text nodes.\n const element = node.nodeType === Node.ELEMENT_NODE ? (node as HTMLElement) : node.parentElement\n\n if (!element) {\n return false\n }\n\n // Hidden elements have no offset parent.\n const isOpen = element.offsetParent !== null\n\n return isOpen\n}\n","import type { Editor, Predicate } from '@tiptap/core'\nimport type { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const findClosestVisibleNode = (\n $pos: ResolvedPos,\n predicate: Predicate,\n editor: Editor,\n):\n | {\n pos: number\n start: number\n depth: number\n node: ProseMirrorNode\n }\n | undefined => {\n for (let i = $pos.depth; i > 0; i -= 1) {\n const node = $pos.node(i)\n const match = predicate(node)\n const isVisible = isNodeVisible($pos.start(i), editor)\n\n if (match && isVisible) {\n return {\n pos: i > 0 ? $pos.before(i) : 0,\n start: $pos.start(i),\n depth: i,\n node,\n }\n }\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { findChildren, findParentNode } from '@tiptap/core'\nimport { GapCursor } from '@tiptap/pm/gapcursor'\nimport type { ResolvedPos } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const setGapCursor = (editor: Editor, direction: 'down' | 'right') => {\n const { state, view, extensionManager } = editor\n const { schema, selection } = state\n const { empty, $anchor } = selection\n const hasGapCursorExtension = !!extensionManager.extensions.find(\n extension => extension.name === 'gapCursor',\n )\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary || !hasGapCursorExtension) {\n return false\n }\n\n if (direction === 'right' && $anchor.parentOffset !== $anchor.parent.nodeSize - 2) {\n return false\n }\n\n const details = findParentNode(node => node.type === schema.nodes.details)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsContent = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsContent.length) {\n return false\n }\n\n const isOpen = isNodeVisible(details.start + detailsContent[0].pos + 1, editor)\n\n if (isOpen) {\n return false\n }\n\n const $position = state.doc.resolve(details.pos + details.node.nodeSize)\n const $validPosition = GapCursor.findFrom($position, 1, false) as unknown as null | ResolvedPos\n\n if (!$validPosition) {\n return false\n }\n\n const { tr } = state\n const gapCursorSelection = new GapCursor($validPosition) as Selection\n\n tr.setSelection(gapCursorSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n}\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findParentNode,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport { Selection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nexport interface DetailsContentOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsContent = Node.create<DetailsContentOptions>({\n name: 'detailsContent',\n\n content: 'block+',\n\n defining: true,\n\n selectable: false,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `div[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }),\n 0,\n ]\n },\n\n addNodeView() {\n return ({ HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n hidden: 'hidden',\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n dom.addEventListener('toggleDetailsContent', () => {\n dom.toggleAttribute('hidden')\n })\n\n return {\n dom,\n contentDOM: dom,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n return !dom.contains(mutation.target) || dom === mutation.target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n return true\n },\n }\n }\n },\n\n addKeyboardShortcuts() {\n return {\n // Escape node on double enter\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { selection } = state\n const { $from, empty } = selection\n const detailsContent = findParentNode(node => node.type === this.type)(selection)\n\n if (!empty || !detailsContent || !detailsContent.node.childCount) {\n return false\n }\n\n const fromIndex = $from.index(detailsContent.depth)\n const { childCount } = detailsContent.node\n const isAtEnd = childCount === fromIndex + 1\n\n if (!isAtEnd) {\n return false\n }\n\n const defaultChildType = detailsContent.node.type.contentMatch.defaultType\n const defaultChildNode = defaultChildType?.createAndFill()\n\n if (!defaultChildNode) {\n return false\n }\n\n const $childPos = state.doc.resolve(detailsContent.pos + 1)\n const lastChildIndex = childCount - 1\n const lastChildNode = detailsContent.node.child(lastChildIndex)\n const lastChildPos = $childPos.posAtIndex(lastChildIndex, detailsContent.depth)\n const lastChildNodeIsEmpty = lastChildNode.eq(defaultChildNode)\n\n if (!lastChildNodeIsEmpty) {\n return false\n }\n\n // get parent of details node\n const above = $from.node(-3)\n\n if (!above) {\n return false\n }\n\n // get default node type after details node\n const after = $from.indexAfter(-3)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const { tr } = state\n const pos = $from.after(-2)\n\n tr.replaceWith(pos, pos, node)\n\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n\n const deleteFrom = lastChildPos\n const deleteTo = lastChildPos + lastChildNode.nodeSize\n\n tr.delete(deleteFrom, deleteTo)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n }\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsContent',\n }),\n})\n","import { createBlockMarkdownSpec, mergeAttributes, Node } from '@tiptap/core'\n\nexport interface DetailsSummaryOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsSummary = Node.create<DetailsSummaryOptions>({\n name: 'detailsSummary',\n\n content: 'text*',\n\n defining: true,\n\n selectable: false,\n\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'summary',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['summary', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsSummary',\n content: 'inline',\n }),\n})\n"],"mappings":"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","names":["import_core","transaction","import_core","import_state","node","import_core"]}
package/dist/index.js CHANGED
@@ -6,14 +6,18 @@ import {
6
6
  findParentNode as findParentNode2,
7
7
  isActive,
8
8
  mergeAttributes,
9
- Node
9
+ Node as Node2
10
10
  } from "@tiptap/core";
11
11
  import { Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
12
12
 
13
13
  // src/helpers/isNodeVisible.ts
14
14
  var isNodeVisible = (position, editor) => {
15
15
  const node = editor.view.domAtPos(position).node;
16
- const isOpen = node.offsetParent !== null;
16
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
17
+ if (!element) {
18
+ return false;
19
+ }
20
+ const isOpen = element.offsetParent !== null;
17
21
  return isOpen;
18
22
  };
19
23
 
@@ -79,7 +83,7 @@ var setGapCursor = (editor, direction) => {
79
83
  };
80
84
 
81
85
  // src/details.ts
82
- var Details = Node.create({
86
+ var Details = Node2.create({
83
87
  name: "details",
84
88
  content: "detailsSummary detailsContent",
85
89
  group: "block",
@@ -418,10 +422,10 @@ import {
418
422
  defaultBlockAt as defaultBlockAt2,
419
423
  findParentNode as findParentNode3,
420
424
  mergeAttributes as mergeAttributes2,
421
- Node as Node2
425
+ Node as Node3
422
426
  } from "@tiptap/core";
423
427
  import { Selection as Selection2 } from "@tiptap/pm/state";
424
- var DetailsContent = Node2.create({
428
+ var DetailsContent = Node3.create({
425
429
  name: "detailsContent",
426
430
  content: "block+",
427
431
  defining: true,
@@ -538,8 +542,8 @@ var DetailsContent = Node2.create({
538
542
  });
539
543
 
540
544
  // src/summary/details-summary.ts
541
- import { createBlockMarkdownSpec as createBlockMarkdownSpec3, mergeAttributes as mergeAttributes3, Node as Node3 } from "@tiptap/core";
542
- var DetailsSummary = Node3.create({
545
+ import { createBlockMarkdownSpec as createBlockMarkdownSpec3, mergeAttributes as mergeAttributes3, Node as Node4 } from "@tiptap/core";
546
+ var DetailsSummary = Node4.create({
543
547
  name: "detailsSummary",
544
548
  content: "text*",
545
549
  defining: true,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/details.ts","../src/helpers/isNodeVisible.ts","../src/helpers/findClosestVisibleNode.ts","../src/helpers/setGapCursor.ts","../src/content/details-content.ts","../src/summary/details-summary.ts","../src/index.ts"],"sourcesContent":["import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findChildren,\n findParentNode,\n isActive,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey, Selection, TextSelection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nimport { findClosestVisibleNode } from './helpers/findClosestVisibleNode.js'\nimport { isNodeVisible } from './helpers/isNodeVisible.js'\nimport { setGapCursor } from './helpers/setGapCursor.js'\n\nexport interface DetailsRenderToggleButtonOptions {\n /**\n * The toggle button element rendered by the node view.\n */\n element: HTMLButtonElement\n /**\n * The current open state of the details node.\n */\n isOpen: boolean\n /**\n * The current node used to derive toggle button state.\n */\n node: ProseMirrorNode\n}\n\nexport interface DetailsOptions {\n /**\n * Specify if the open status should be saved in the document. Defaults to `false`.\n */\n persist: boolean\n /**\n * Specifies a CSS class that is set when toggling the content. Defaults to `is-open`.\n */\n openClassName: string\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n /**\n * Customizes the rendered toggle button.\n */\n renderToggleButton: (options: DetailsRenderToggleButtonOptions) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n details: {\n /**\n * Set a details node\n */\n setDetails: () => ReturnType\n /**\n * Unset a details node\n */\n unsetDetails: () => ReturnType\n }\n }\n}\n\nexport const Details = Node.create<DetailsOptions>({\n name: 'details',\n\n content: 'detailsSummary detailsContent',\n\n group: 'block',\n\n defining: true,\n\n isolating: true,\n\n // @ts-ignore reason: `allowGapCursor` is not a valid property by default, but the `GapCursor` extension adds it to the Nodeconfig type\n allowGapCursor: false,\n\n addOptions() {\n return {\n persist: false,\n openClassName: 'is-open',\n HTMLAttributes: {},\n renderToggleButton: ({ element, isOpen }) => {\n element.setAttribute(\n 'aria-label',\n isOpen ? 'Collapse details content' : 'Expand details content',\n )\n },\n }\n },\n\n addAttributes() {\n if (!this.options.persist) {\n return []\n }\n\n return {\n open: {\n default: false,\n parseHTML: element => element.hasAttribute('open'),\n renderHTML: ({ open }) => {\n if (!open) {\n return {}\n }\n\n return { open: '' }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'details',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['details', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'details',\n content: 'block',\n }),\n\n addNodeView() {\n return ({ editor, getPos, node, HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n const toggle = document.createElement('button')\n\n toggle.type = 'button'\n\n const renderToggleButton = (options: Omit<DetailsRenderToggleButtonOptions, 'element'>) => {\n this.options.renderToggleButton({\n element: toggle,\n ...options,\n })\n }\n\n dom.append(toggle)\n\n const content = document.createElement('div')\n\n dom.append(content)\n\n const toggleDetailsContent = (options?: { setToValue?: boolean; node?: ProseMirrorNode }) => {\n const { setToValue, node: currentNode = node } = options || {}\n\n if (setToValue !== undefined) {\n if (setToValue) {\n if (dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.add(this.options.openClassName)\n } else {\n if (!dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.remove(this.options.openClassName)\n }\n } else {\n dom.classList.toggle(this.options.openClassName)\n }\n\n const isOpen = dom.classList.contains(this.options.openClassName)\n\n renderToggleButton({\n isOpen,\n node: currentNode,\n })\n\n const event = new Event('toggleDetailsContent')\n const detailsContent = content.querySelector(':scope > div[data-type=\"detailsContent\"]')\n\n detailsContent?.dispatchEvent(event)\n }\n\n renderToggleButton({\n isOpen: Boolean(node.attrs.open),\n node,\n })\n\n if (node.attrs.open) {\n setTimeout(() => toggleDetailsContent())\n }\n\n toggle.addEventListener('click', () => {\n toggleDetailsContent()\n\n if (!this.options.persist) {\n editor.commands.focus(undefined, { scrollIntoView: false })\n\n return\n }\n\n if (editor.isEditable && typeof getPos === 'function') {\n const { from, to } = editor.state.selection\n\n editor\n .chain()\n .command(({ tr }) => {\n const pos = getPos()\n\n if (typeof pos !== 'number') {\n return false\n }\n\n const currentNode = tr.doc.nodeAt(pos)\n\n if (currentNode?.type !== this.type) {\n return false\n }\n\n tr.setNodeMarkup(pos, undefined, {\n open: !currentNode.attrs.open,\n })\n\n return true\n })\n .setTextSelection({\n from,\n to,\n })\n .focus(undefined, { scrollIntoView: false })\n .run()\n }\n })\n\n return {\n dom,\n contentDOM: content,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n const target = mutation.target\n const isInsideWrapper = dom.contains(target)\n const isInsideToggleButton = toggle.contains(target)\n\n return isInsideToggleButton || !isInsideWrapper || dom === target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n // Only update the open state if set\n if (updatedNode.attrs.open !== undefined) {\n toggleDetailsContent({\n setToValue: updatedNode.attrs.open,\n node: updatedNode,\n })\n } else {\n renderToggleButton({\n isOpen: dom.classList.contains(this.options.openClassName),\n node: updatedNode,\n })\n }\n\n return true\n },\n }\n }\n },\n\n addCommands() {\n return {\n setDetails:\n () =>\n ({ state, chain }) => {\n const { schema, selection } = state\n const { $from, $to } = selection\n const range = $from.blockRange($to)\n\n if (!range) {\n return false\n }\n\n const slice = state.doc.slice(range.start, range.end)\n const match = schema.nodes.detailsContent.contentMatch.matchFragment(slice.content)\n\n if (!match) {\n return false\n }\n\n const content = slice.toJSON()?.content || []\n\n return chain()\n .insertContentAt(\n { from: range.start, to: range.end },\n {\n type: this.name,\n content: [\n {\n type: 'detailsSummary',\n },\n {\n type: 'detailsContent',\n content,\n },\n ],\n },\n )\n .setTextSelection(range.start + 2)\n .run()\n },\n\n unsetDetails:\n () =>\n ({ state, chain }) => {\n const { selection, schema } = state\n const details = findParentNode(node => node.type === this.type)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsSummary,\n )\n const detailsContents = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsSummaries.length || !detailsContents.length) {\n return false\n }\n\n const detailsSummary = detailsSummaries[0]\n const detailsContent = detailsContents[0]\n const from = details.pos\n const $from = state.doc.resolve(from)\n const to = from + details.node.nodeSize\n const range = { from, to }\n const content = (detailsContent.node.content.toJSON() as []) || []\n const defaultTypeForSummary = $from.parent.type.contentMatch.defaultType\n\n // TODO: this may break for some custom schemas\n const summaryContent = defaultTypeForSummary\n ?.create(null, detailsSummary.node.content)\n .toJSON()\n const mergedContent = [summaryContent, ...content]\n\n return chain()\n .insertContentAt(range, mergedContent)\n .setTextSelection(from + 1)\n .run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => {\n const { schema, selection } = this.editor.state\n const { empty, $anchor } = selection\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n // for some reason safari removes the whole text content within a `<summary>`tag on backspace\n // so we have to remove the text manually\n // see: https://discuss.prosemirror.net/t/safari-backspace-bug-with-details-tag/4223\n if ($anchor.parentOffset !== 0) {\n return this.editor.commands.command(({ tr }) => {\n const from = $anchor.pos - 1\n const to = $anchor.pos\n\n tr.delete(from, to)\n\n return true\n })\n }\n\n return this.editor.commands.unsetDetails()\n },\n\n // Creates a new node below it if it is closed.\n // Otherwise inside `DetailsContent`.\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { schema, selection } = state\n const { $head } = selection\n\n if ($head.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n const isVisible = isNodeVisible($head.after() + 1, editor)\n const above = isVisible ? state.doc.nodeAt($head.after()) : $head.node(-2)\n\n if (!above) {\n return false\n }\n\n const after = isVisible ? 0 : $head.indexAfter(-1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const pos = isVisible ? $head.after() + 1 : $head.after(-1)\n const tr = state.tr.replaceWith(pos, pos, node)\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowRight: ({ editor }) => {\n return setGapCursor(editor, 'right')\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowDown: ({ editor }) => {\n return setGapCursor(editor, 'down')\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [\n // This plugin prevents text selections within the hidden content in `DetailsContent`.\n // The cursor is moved to the next visible position.\n new Plugin({\n key: new PluginKey('detailsSelection'),\n appendTransaction: (transactions, oldState, newState) => {\n const { editor, type } = this\n const isComposing = editor.view.composing\n\n if (isComposing) {\n return\n }\n\n const selectionSet = transactions.some(transaction => transaction.selectionSet)\n\n if (!selectionSet || !oldState.selection.empty || !newState.selection.empty) {\n return\n }\n\n const detailsIsActive = isActive(newState, type.name)\n\n if (!detailsIsActive) {\n return\n }\n\n const { $from } = newState.selection\n const isVisible = isNodeVisible($from.pos, editor)\n\n if (isVisible) {\n return\n }\n\n const details = findClosestVisibleNode($from, node => node.type === type, editor)\n\n if (!details) {\n return\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === newState.schema.nodes.detailsSummary,\n )\n\n if (!detailsSummaries.length) {\n return\n }\n\n const detailsSummary = detailsSummaries[0]\n const selectionDirection =\n oldState.selection.from < newState.selection.from ? 'forward' : 'backward'\n const correctedPosition =\n selectionDirection === 'forward'\n ? details.start + detailsSummary.pos\n : details.pos + detailsSummary.pos + detailsSummary.node.nodeSize\n const selection = TextSelection.create(newState.doc, correctedPosition)\n const transaction = newState.tr.setSelection(selection)\n\n return transaction\n },\n }),\n ]\n },\n})\n","import type { Editor } from '@tiptap/core'\n\nexport const isNodeVisible = (position: number, editor: Editor): boolean => {\n const node = editor.view.domAtPos(position).node as HTMLElement\n const isOpen = node.offsetParent !== null\n\n return isOpen\n}\n","import type { Editor, Predicate } from '@tiptap/core'\nimport type { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const findClosestVisibleNode = (\n $pos: ResolvedPos,\n predicate: Predicate,\n editor: Editor,\n):\n | {\n pos: number\n start: number\n depth: number\n node: ProseMirrorNode\n }\n | undefined => {\n for (let i = $pos.depth; i > 0; i -= 1) {\n const node = $pos.node(i)\n const match = predicate(node)\n const isVisible = isNodeVisible($pos.start(i), editor)\n\n if (match && isVisible) {\n return {\n pos: i > 0 ? $pos.before(i) : 0,\n start: $pos.start(i),\n depth: i,\n node,\n }\n }\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { findChildren, findParentNode } from '@tiptap/core'\nimport { GapCursor } from '@tiptap/pm/gapcursor'\nimport type { ResolvedPos } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const setGapCursor = (editor: Editor, direction: 'down' | 'right') => {\n const { state, view, extensionManager } = editor\n const { schema, selection } = state\n const { empty, $anchor } = selection\n const hasGapCursorExtension = !!extensionManager.extensions.find(\n extension => extension.name === 'gapCursor',\n )\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary || !hasGapCursorExtension) {\n return false\n }\n\n if (direction === 'right' && $anchor.parentOffset !== $anchor.parent.nodeSize - 2) {\n return false\n }\n\n const details = findParentNode(node => node.type === schema.nodes.details)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsContent = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsContent.length) {\n return false\n }\n\n const isOpen = isNodeVisible(details.start + detailsContent[0].pos + 1, editor)\n\n if (isOpen) {\n return false\n }\n\n const $position = state.doc.resolve(details.pos + details.node.nodeSize)\n const $validPosition = GapCursor.findFrom($position, 1, false) as unknown as null | ResolvedPos\n\n if (!$validPosition) {\n return false\n }\n\n const { tr } = state\n const gapCursorSelection = new GapCursor($validPosition) as Selection\n\n tr.setSelection(gapCursorSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n}\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findParentNode,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport { Selection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nexport interface DetailsContentOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsContent = Node.create<DetailsContentOptions>({\n name: 'detailsContent',\n\n content: 'block+',\n\n defining: true,\n\n selectable: false,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `div[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }),\n 0,\n ]\n },\n\n addNodeView() {\n return ({ HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n hidden: 'hidden',\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n dom.addEventListener('toggleDetailsContent', () => {\n dom.toggleAttribute('hidden')\n })\n\n return {\n dom,\n contentDOM: dom,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n return !dom.contains(mutation.target) || dom === mutation.target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n return true\n },\n }\n }\n },\n\n addKeyboardShortcuts() {\n return {\n // Escape node on double enter\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { selection } = state\n const { $from, empty } = selection\n const detailsContent = findParentNode(node => node.type === this.type)(selection)\n\n if (!empty || !detailsContent || !detailsContent.node.childCount) {\n return false\n }\n\n const fromIndex = $from.index(detailsContent.depth)\n const { childCount } = detailsContent.node\n const isAtEnd = childCount === fromIndex + 1\n\n if (!isAtEnd) {\n return false\n }\n\n const defaultChildType = detailsContent.node.type.contentMatch.defaultType\n const defaultChildNode = defaultChildType?.createAndFill()\n\n if (!defaultChildNode) {\n return false\n }\n\n const $childPos = state.doc.resolve(detailsContent.pos + 1)\n const lastChildIndex = childCount - 1\n const lastChildNode = detailsContent.node.child(lastChildIndex)\n const lastChildPos = $childPos.posAtIndex(lastChildIndex, detailsContent.depth)\n const lastChildNodeIsEmpty = lastChildNode.eq(defaultChildNode)\n\n if (!lastChildNodeIsEmpty) {\n return false\n }\n\n // get parent of details node\n const above = $from.node(-3)\n\n if (!above) {\n return false\n }\n\n // get default node type after details node\n const after = $from.indexAfter(-3)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const { tr } = state\n const pos = $from.after(-2)\n\n tr.replaceWith(pos, pos, node)\n\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n\n const deleteFrom = lastChildPos\n const deleteTo = lastChildPos + lastChildNode.nodeSize\n\n tr.delete(deleteFrom, deleteTo)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n }\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsContent',\n }),\n})\n","import { createBlockMarkdownSpec, mergeAttributes, Node } from '@tiptap/core'\n\nexport interface DetailsSummaryOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsSummary = Node.create<DetailsSummaryOptions>({\n name: 'detailsSummary',\n\n content: 'text*',\n\n defining: true,\n\n selectable: false,\n\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'summary',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['summary', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsSummary',\n content: 'inline',\n }),\n})\n","import { Details } from './details.js'\n\nexport * from './content/index.js'\nexport * from './details.js'\nexport * from './summary/index.js'\n\nexport default Details\n"],"mappings":"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","names":["findChildren","findParentNode","findParentNode","findChildren","transaction","createBlockMarkdownSpec","defaultBlockAt","findParentNode","mergeAttributes","Node","Selection","node","createBlockMarkdownSpec","mergeAttributes","Node"]}
1
+ {"version":3,"sources":["../src/details.ts","../src/helpers/isNodeVisible.ts","../src/helpers/findClosestVisibleNode.ts","../src/helpers/setGapCursor.ts","../src/content/details-content.ts","../src/summary/details-summary.ts","../src/index.ts"],"sourcesContent":["import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findChildren,\n findParentNode,\n isActive,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey, Selection, TextSelection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nimport { findClosestVisibleNode } from './helpers/findClosestVisibleNode.js'\nimport { isNodeVisible } from './helpers/isNodeVisible.js'\nimport { setGapCursor } from './helpers/setGapCursor.js'\n\nexport interface DetailsRenderToggleButtonOptions {\n /**\n * The toggle button element rendered by the node view.\n */\n element: HTMLButtonElement\n /**\n * The current open state of the details node.\n */\n isOpen: boolean\n /**\n * The current node used to derive toggle button state.\n */\n node: ProseMirrorNode\n}\n\nexport interface DetailsOptions {\n /**\n * Specify if the open status should be saved in the document. Defaults to `false`.\n */\n persist: boolean\n /**\n * Specifies a CSS class that is set when toggling the content. Defaults to `is-open`.\n */\n openClassName: string\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n /**\n * Customizes the rendered toggle button.\n */\n renderToggleButton: (options: DetailsRenderToggleButtonOptions) => void\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n details: {\n /**\n * Set a details node\n */\n setDetails: () => ReturnType\n /**\n * Unset a details node\n */\n unsetDetails: () => ReturnType\n }\n }\n}\n\nexport const Details = Node.create<DetailsOptions>({\n name: 'details',\n\n content: 'detailsSummary detailsContent',\n\n group: 'block',\n\n defining: true,\n\n isolating: true,\n\n // @ts-ignore reason: `allowGapCursor` is not a valid property by default, but the `GapCursor` extension adds it to the Nodeconfig type\n allowGapCursor: false,\n\n addOptions() {\n return {\n persist: false,\n openClassName: 'is-open',\n HTMLAttributes: {},\n renderToggleButton: ({ element, isOpen }) => {\n element.setAttribute(\n 'aria-label',\n isOpen ? 'Collapse details content' : 'Expand details content',\n )\n },\n }\n },\n\n addAttributes() {\n if (!this.options.persist) {\n return []\n }\n\n return {\n open: {\n default: false,\n parseHTML: element => element.hasAttribute('open'),\n renderHTML: ({ open }) => {\n if (!open) {\n return {}\n }\n\n return { open: '' }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'details',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['details', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'details',\n content: 'block',\n }),\n\n addNodeView() {\n return ({ editor, getPos, node, HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n const toggle = document.createElement('button')\n\n toggle.type = 'button'\n\n const renderToggleButton = (options: Omit<DetailsRenderToggleButtonOptions, 'element'>) => {\n this.options.renderToggleButton({\n element: toggle,\n ...options,\n })\n }\n\n dom.append(toggle)\n\n const content = document.createElement('div')\n\n dom.append(content)\n\n const toggleDetailsContent = (options?: { setToValue?: boolean; node?: ProseMirrorNode }) => {\n const { setToValue, node: currentNode = node } = options || {}\n\n if (setToValue !== undefined) {\n if (setToValue) {\n if (dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.add(this.options.openClassName)\n } else {\n if (!dom.classList.contains(this.options.openClassName)) {\n return\n }\n dom.classList.remove(this.options.openClassName)\n }\n } else {\n dom.classList.toggle(this.options.openClassName)\n }\n\n const isOpen = dom.classList.contains(this.options.openClassName)\n\n renderToggleButton({\n isOpen,\n node: currentNode,\n })\n\n const event = new Event('toggleDetailsContent')\n const detailsContent = content.querySelector(':scope > div[data-type=\"detailsContent\"]')\n\n detailsContent?.dispatchEvent(event)\n }\n\n renderToggleButton({\n isOpen: Boolean(node.attrs.open),\n node,\n })\n\n if (node.attrs.open) {\n setTimeout(() => toggleDetailsContent())\n }\n\n toggle.addEventListener('click', () => {\n toggleDetailsContent()\n\n if (!this.options.persist) {\n editor.commands.focus(undefined, { scrollIntoView: false })\n\n return\n }\n\n if (editor.isEditable && typeof getPos === 'function') {\n const { from, to } = editor.state.selection\n\n editor\n .chain()\n .command(({ tr }) => {\n const pos = getPos()\n\n if (typeof pos !== 'number') {\n return false\n }\n\n const currentNode = tr.doc.nodeAt(pos)\n\n if (currentNode?.type !== this.type) {\n return false\n }\n\n tr.setNodeMarkup(pos, undefined, {\n open: !currentNode.attrs.open,\n })\n\n return true\n })\n .setTextSelection({\n from,\n to,\n })\n .focus(undefined, { scrollIntoView: false })\n .run()\n }\n })\n\n return {\n dom,\n contentDOM: content,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n const target = mutation.target\n const isInsideWrapper = dom.contains(target)\n const isInsideToggleButton = toggle.contains(target)\n\n return isInsideToggleButton || !isInsideWrapper || dom === target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n // Only update the open state if set\n if (updatedNode.attrs.open !== undefined) {\n toggleDetailsContent({\n setToValue: updatedNode.attrs.open,\n node: updatedNode,\n })\n } else {\n renderToggleButton({\n isOpen: dom.classList.contains(this.options.openClassName),\n node: updatedNode,\n })\n }\n\n return true\n },\n }\n }\n },\n\n addCommands() {\n return {\n setDetails:\n () =>\n ({ state, chain }) => {\n const { schema, selection } = state\n const { $from, $to } = selection\n const range = $from.blockRange($to)\n\n if (!range) {\n return false\n }\n\n const slice = state.doc.slice(range.start, range.end)\n const match = schema.nodes.detailsContent.contentMatch.matchFragment(slice.content)\n\n if (!match) {\n return false\n }\n\n const content = slice.toJSON()?.content || []\n\n return chain()\n .insertContentAt(\n { from: range.start, to: range.end },\n {\n type: this.name,\n content: [\n {\n type: 'detailsSummary',\n },\n {\n type: 'detailsContent',\n content,\n },\n ],\n },\n )\n .setTextSelection(range.start + 2)\n .run()\n },\n\n unsetDetails:\n () =>\n ({ state, chain }) => {\n const { selection, schema } = state\n const details = findParentNode(node => node.type === this.type)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsSummary,\n )\n const detailsContents = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsSummaries.length || !detailsContents.length) {\n return false\n }\n\n const detailsSummary = detailsSummaries[0]\n const detailsContent = detailsContents[0]\n const from = details.pos\n const $from = state.doc.resolve(from)\n const to = from + details.node.nodeSize\n const range = { from, to }\n const content = (detailsContent.node.content.toJSON() as []) || []\n const defaultTypeForSummary = $from.parent.type.contentMatch.defaultType\n\n // TODO: this may break for some custom schemas\n const summaryContent = defaultTypeForSummary\n ?.create(null, detailsSummary.node.content)\n .toJSON()\n const mergedContent = [summaryContent, ...content]\n\n return chain()\n .insertContentAt(range, mergedContent)\n .setTextSelection(from + 1)\n .run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => {\n const { schema, selection } = this.editor.state\n const { empty, $anchor } = selection\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n // for some reason safari removes the whole text content within a `<summary>`tag on backspace\n // so we have to remove the text manually\n // see: https://discuss.prosemirror.net/t/safari-backspace-bug-with-details-tag/4223\n if ($anchor.parentOffset !== 0) {\n return this.editor.commands.command(({ tr }) => {\n const from = $anchor.pos - 1\n const to = $anchor.pos\n\n tr.delete(from, to)\n\n return true\n })\n }\n\n return this.editor.commands.unsetDetails()\n },\n\n // Creates a new node below it if it is closed.\n // Otherwise inside `DetailsContent`.\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { schema, selection } = state\n const { $head } = selection\n\n if ($head.parent.type !== schema.nodes.detailsSummary) {\n return false\n }\n\n const isVisible = isNodeVisible($head.after() + 1, editor)\n const above = isVisible ? state.doc.nodeAt($head.after()) : $head.node(-2)\n\n if (!above) {\n return false\n }\n\n const after = isVisible ? 0 : $head.indexAfter(-1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const pos = isVisible ? $head.after() + 1 : $head.after(-1)\n const tr = state.tr.replaceWith(pos, pos, node)\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowRight: ({ editor }) => {\n return setGapCursor(editor, 'right')\n },\n\n // The default gapcursor implementation can’t handle hidden content, so we need to fix this.\n ArrowDown: ({ editor }) => {\n return setGapCursor(editor, 'down')\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [\n // This plugin prevents text selections within the hidden content in `DetailsContent`.\n // The cursor is moved to the next visible position.\n new Plugin({\n key: new PluginKey('detailsSelection'),\n appendTransaction: (transactions, oldState, newState) => {\n const { editor, type } = this\n const isComposing = editor.view.composing\n\n if (isComposing) {\n return\n }\n\n const selectionSet = transactions.some(transaction => transaction.selectionSet)\n\n if (!selectionSet || !oldState.selection.empty || !newState.selection.empty) {\n return\n }\n\n const detailsIsActive = isActive(newState, type.name)\n\n if (!detailsIsActive) {\n return\n }\n\n const { $from } = newState.selection\n const isVisible = isNodeVisible($from.pos, editor)\n\n if (isVisible) {\n return\n }\n\n const details = findClosestVisibleNode($from, node => node.type === type, editor)\n\n if (!details) {\n return\n }\n\n const detailsSummaries = findChildren(\n details.node,\n node => node.type === newState.schema.nodes.detailsSummary,\n )\n\n if (!detailsSummaries.length) {\n return\n }\n\n const detailsSummary = detailsSummaries[0]\n const selectionDirection =\n oldState.selection.from < newState.selection.from ? 'forward' : 'backward'\n const correctedPosition =\n selectionDirection === 'forward'\n ? details.start + detailsSummary.pos\n : details.pos + detailsSummary.pos + detailsSummary.node.nodeSize\n const selection = TextSelection.create(newState.doc, correctedPosition)\n const transaction = newState.tr.setSelection(selection)\n\n return transaction\n },\n }),\n ]\n },\n})\n","import type { Editor } from '@tiptap/core'\n\nexport const isNodeVisible = (position: number, editor: Editor): boolean => {\n const node = editor.view.domAtPos(position).node\n // Use the node for elements and its parent for text nodes.\n const element = node.nodeType === Node.ELEMENT_NODE ? (node as HTMLElement) : node.parentElement\n\n if (!element) {\n return false\n }\n\n // Hidden elements have no offset parent.\n const isOpen = element.offsetParent !== null\n\n return isOpen\n}\n","import type { Editor, Predicate } from '@tiptap/core'\nimport type { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const findClosestVisibleNode = (\n $pos: ResolvedPos,\n predicate: Predicate,\n editor: Editor,\n):\n | {\n pos: number\n start: number\n depth: number\n node: ProseMirrorNode\n }\n | undefined => {\n for (let i = $pos.depth; i > 0; i -= 1) {\n const node = $pos.node(i)\n const match = predicate(node)\n const isVisible = isNodeVisible($pos.start(i), editor)\n\n if (match && isVisible) {\n return {\n pos: i > 0 ? $pos.before(i) : 0,\n start: $pos.start(i),\n depth: i,\n node,\n }\n }\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { findChildren, findParentNode } from '@tiptap/core'\nimport { GapCursor } from '@tiptap/pm/gapcursor'\nimport type { ResolvedPos } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\n\nimport { isNodeVisible } from './isNodeVisible.js'\n\nexport const setGapCursor = (editor: Editor, direction: 'down' | 'right') => {\n const { state, view, extensionManager } = editor\n const { schema, selection } = state\n const { empty, $anchor } = selection\n const hasGapCursorExtension = !!extensionManager.extensions.find(\n extension => extension.name === 'gapCursor',\n )\n\n if (!empty || $anchor.parent.type !== schema.nodes.detailsSummary || !hasGapCursorExtension) {\n return false\n }\n\n if (direction === 'right' && $anchor.parentOffset !== $anchor.parent.nodeSize - 2) {\n return false\n }\n\n const details = findParentNode(node => node.type === schema.nodes.details)(selection)\n\n if (!details) {\n return false\n }\n\n const detailsContent = findChildren(\n details.node,\n node => node.type === schema.nodes.detailsContent,\n )\n\n if (!detailsContent.length) {\n return false\n }\n\n const isOpen = isNodeVisible(details.start + detailsContent[0].pos + 1, editor)\n\n if (isOpen) {\n return false\n }\n\n const $position = state.doc.resolve(details.pos + details.node.nodeSize)\n const $validPosition = GapCursor.findFrom($position, 1, false) as unknown as null | ResolvedPos\n\n if (!$validPosition) {\n return false\n }\n\n const { tr } = state\n const gapCursorSelection = new GapCursor($validPosition) as Selection\n\n tr.setSelection(gapCursorSelection)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n}\n","import {\n createBlockMarkdownSpec,\n defaultBlockAt,\n findParentNode,\n mergeAttributes,\n Node,\n} from '@tiptap/core'\nimport { Selection } from '@tiptap/pm/state'\nimport type { ViewMutationRecord } from '@tiptap/pm/view'\n\nexport interface DetailsContentOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsContent = Node.create<DetailsContentOptions>({\n name: 'detailsContent',\n\n content: 'block+',\n\n defining: true,\n\n selectable: false,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `div[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }),\n 0,\n ]\n },\n\n addNodeView() {\n return ({ HTMLAttributes }) => {\n const dom = document.createElement('div')\n const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n hidden: 'hidden',\n })\n\n Object.entries(attributes).forEach(([key, value]) => dom.setAttribute(key, value))\n\n dom.addEventListener('toggleDetailsContent', () => {\n dom.toggleAttribute('hidden')\n })\n\n return {\n dom,\n contentDOM: dom,\n ignoreMutation(mutation: ViewMutationRecord) {\n if (mutation.type === 'selection') {\n return false\n }\n\n return !dom.contains(mutation.target) || dom === mutation.target\n },\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n return true\n },\n }\n }\n },\n\n addKeyboardShortcuts() {\n return {\n // Escape node on double enter\n Enter: ({ editor }) => {\n const { state, view } = editor\n const { selection } = state\n const { $from, empty } = selection\n const detailsContent = findParentNode(node => node.type === this.type)(selection)\n\n if (!empty || !detailsContent || !detailsContent.node.childCount) {\n return false\n }\n\n const fromIndex = $from.index(detailsContent.depth)\n const { childCount } = detailsContent.node\n const isAtEnd = childCount === fromIndex + 1\n\n if (!isAtEnd) {\n return false\n }\n\n const defaultChildType = detailsContent.node.type.contentMatch.defaultType\n const defaultChildNode = defaultChildType?.createAndFill()\n\n if (!defaultChildNode) {\n return false\n }\n\n const $childPos = state.doc.resolve(detailsContent.pos + 1)\n const lastChildIndex = childCount - 1\n const lastChildNode = detailsContent.node.child(lastChildIndex)\n const lastChildPos = $childPos.posAtIndex(lastChildIndex, detailsContent.depth)\n const lastChildNodeIsEmpty = lastChildNode.eq(defaultChildNode)\n\n if (!lastChildNodeIsEmpty) {\n return false\n }\n\n // get parent of details node\n const above = $from.node(-3)\n\n if (!above) {\n return false\n }\n\n // get default node type after details node\n const after = $from.indexAfter(-3)\n const type = defaultBlockAt(above.contentMatchAt(after))\n\n if (!type || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n const node = type.createAndFill()\n\n if (!node) {\n return false\n }\n\n const { tr } = state\n const pos = $from.after(-2)\n\n tr.replaceWith(pos, pos, node)\n\n const $pos = tr.doc.resolve(pos)\n const newSelection = Selection.near($pos, 1)\n\n tr.setSelection(newSelection)\n\n const deleteFrom = lastChildPos\n const deleteTo = lastChildPos + lastChildNode.nodeSize\n\n tr.delete(deleteFrom, deleteTo)\n tr.scrollIntoView()\n view.dispatch(tr)\n\n return true\n },\n }\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsContent',\n }),\n})\n","import { createBlockMarkdownSpec, mergeAttributes, Node } from '@tiptap/core'\n\nexport interface DetailsSummaryOptions {\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n */\n HTMLAttributes: {\n [key: string]: any\n }\n}\n\nexport const DetailsSummary = Node.create<DetailsSummaryOptions>({\n name: 'detailsSummary',\n\n content: 'text*',\n\n defining: true,\n\n selectable: false,\n\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'summary',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['summary', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n ...createBlockMarkdownSpec({\n nodeName: 'detailsSummary',\n content: 'inline',\n }),\n})\n","import { Details } from './details.js'\n\nexport * from './content/index.js'\nexport * from './details.js'\nexport * from './summary/index.js'\n\nexport default Details\n"],"mappings":"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","names":["findChildren","findParentNode","Node","Node","findParentNode","findChildren","transaction","createBlockMarkdownSpec","defaultBlockAt","findParentNode","mergeAttributes","Node","Selection","node","createBlockMarkdownSpec","mergeAttributes","Node"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiptap/extension-details",
3
- "version": "3.27.4",
3
+ "version": "3.28.0",
4
4
  "description": "details extension for tiptap",
5
5
  "keywords": [
6
6
  "tiptap",
@@ -39,14 +39,14 @@
39
39
  }
40
40
  },
41
41
  "devDependencies": {
42
- "@tiptap/core": "^3.27.4",
43
- "@tiptap/extension-text-style": "^3.27.4",
44
- "@tiptap/pm": "^3.27.4"
42
+ "@tiptap/core": "^3.28.0",
43
+ "@tiptap/pm": "^3.28.0",
44
+ "@tiptap/extension-text-style": "^3.28.0"
45
45
  },
46
46
  "peerDependencies": {
47
- "@tiptap/core": "3.27.4",
48
- "@tiptap/extension-text-style": "3.27.4",
49
- "@tiptap/pm": "3.27.4"
47
+ "@tiptap/core": "3.28.0",
48
+ "@tiptap/extension-text-style": "3.28.0",
49
+ "@tiptap/pm": "3.28.0"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup"
@@ -1,8 +1,16 @@
1
1
  import type { Editor } from '@tiptap/core'
2
2
 
3
3
  export const isNodeVisible = (position: number, editor: Editor): boolean => {
4
- const node = editor.view.domAtPos(position).node as HTMLElement
5
- const isOpen = node.offsetParent !== null
4
+ const node = editor.view.domAtPos(position).node
5
+ // Use the node for elements and its parent for text nodes.
6
+ const element = node.nodeType === Node.ELEMENT_NODE ? (node as HTMLElement) : node.parentElement
7
+
8
+ if (!element) {
9
+ return false
10
+ }
11
+
12
+ // Hidden elements have no offset parent.
13
+ const isOpen = element.offsetParent !== null
6
14
 
7
15
  return isOpen
8
16
  }