@domternal/extension-image 0.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/imageUploadPlugin.ts","../src/Image.ts"],"names":["Plugin","PluginKey"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Image Upload Plugin\n *\n * Handles paste/drop of image files with decoration-based placeholders.\n * The document never contains temporary data — a widget decoration shows\n * a loading indicator while the upload is in progress.\n *\n * On success: placeholder removed, real image node inserted.\n * On error: placeholder removed, onUploadError called.\n */\nimport { Plugin, PluginKey } from '@domternal/pm/state';\nimport { Decoration, DecorationSet } from '@domternal/pm/view';\nimport type { EditorView } from '@domternal/pm/view';\nimport type { NodeType } from '@domternal/pm/model';\n\nexport const imageUploadPluginKey = new PluginKey('imageUpload');\n\nexport interface ImageUploadPluginOptions {\n /** The image node type from schema */\n nodeType: NodeType;\n /** Upload handler — must return URL string */\n uploadHandler: (file: File) => Promise<string>;\n /** Allowed MIME types */\n allowedMimeTypes: string[];\n /** Max file size in bytes (0 = unlimited) */\n maxFileSize: number;\n /** Called when upload starts for a file */\n onUploadStart: ((file: File) => void) | null;\n /** Error callback */\n onUploadError: ((error: Error, file: File) => void) | null;\n}\n\n/** Validate file before upload */\nfunction isValidImageFile(\n file: File,\n allowedMimeTypes: string[],\n maxFileSize: number,\n): boolean {\n if (!allowedMimeTypes.includes(file.type)) return false;\n if (maxFileSize > 0 && file.size > maxFileSize) return false;\n return true;\n}\n\n/** Generate unique placeholder ID */\nlet placeholderCounter = 0;\nfunction createPlaceholderId(): string {\n return `image-upload-${String(++placeholderCounter)}`;\n}\n\n/** Reset placeholder counter (for testing) */\nexport function _resetPlaceholderCounter(): void {\n placeholderCounter = 0;\n}\n\n/** Create placeholder DOM element */\nfunction createPlaceholderElement(): HTMLElement {\n const div = document.createElement('div');\n div.className = 'domternal-image-uploading';\n return div;\n}\n\nexport function imageUploadPlugin(options: ImageUploadPluginOptions): Plugin {\n const {\n nodeType,\n uploadHandler,\n allowedMimeTypes,\n maxFileSize,\n onUploadStart,\n onUploadError,\n } = options;\n\n function handleFiles(view: EditorView, files: File[], pos: number): void {\n for (const file of files) {\n const id = createPlaceholderId();\n\n // Add placeholder decoration\n const tr = view.state.tr;\n tr.setMeta(imageUploadPluginKey, { type: 'add', id, pos });\n view.dispatch(tr);\n\n if (onUploadStart) onUploadStart(file);\n\n // Start upload\n uploadHandler(file)\n .then((url) => {\n // Find placeholder position (may have shifted due to edits)\n const decos = imageUploadPluginKey.getState(\n view.state,\n ) as DecorationSet | null;\n const found = decos?.find(\n undefined,\n undefined,\n (spec: Record<string, unknown>) => spec['id'] === id,\n );\n const placeholderPos = found?.[0]?.from;\n\n if (placeholderPos === undefined) return; // placeholder was removed (editor destroyed?)\n\n // Remove placeholder + insert image node\n const insertTr = view.state.tr;\n insertTr.setMeta(imageUploadPluginKey, { type: 'remove', id });\n insertTr.insert(placeholderPos, nodeType.create({ src: url }));\n view.dispatch(insertTr);\n })\n .catch((error: unknown) => {\n // Remove placeholder on error\n const removeTr = view.state.tr;\n removeTr.setMeta(imageUploadPluginKey, { type: 'remove', id });\n view.dispatch(removeTr);\n\n if (onUploadError) {\n onUploadError(\n error instanceof Error ? error : new Error(String(error)),\n file,\n );\n }\n });\n }\n }\n\n return new Plugin({\n key: imageUploadPluginKey,\n\n state: {\n init() {\n return DecorationSet.empty;\n },\n apply(tr, decorations) {\n // Map decorations through document changes\n decorations = decorations.map(tr.mapping, tr.doc);\n\n const action = tr.getMeta(imageUploadPluginKey) as\n | { type: 'add'; id: string; pos: number }\n | { type: 'remove'; id: string }\n | undefined;\n\n if (action?.type === 'add') {\n const widget = Decoration.widget(\n action.pos,\n createPlaceholderElement(),\n { id: action.id },\n );\n return decorations.add(tr.doc, [widget]);\n }\n\n if (action?.type === 'remove') {\n const found = decorations.find(\n undefined,\n undefined,\n (spec: Record<string, unknown>) => spec['id'] === action.id,\n );\n return decorations.remove(found);\n }\n\n return decorations;\n },\n },\n\n props: {\n decorations(state) {\n return imageUploadPluginKey.getState(state) as DecorationSet;\n },\n\n handlePaste(view, event) {\n const items = event.clipboardData?.items;\n if (!items) return false;\n\n const files: File[] = [];\n for (const item of Array.from(items)) {\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (\n file &&\n isValidImageFile(file, allowedMimeTypes, maxFileSize)\n ) {\n files.push(file);\n }\n }\n }\n\n if (files.length === 0) return false;\n\n event.preventDefault();\n handleFiles(view, files, view.state.selection.from);\n return true;\n },\n\n handleDrop(view, event) {\n const dataTransfer = event.dataTransfer;\n if (!dataTransfer?.files || dataTransfer.files.length === 0)\n return false;\n\n const imageFiles: File[] = [];\n for (const file of Array.from(dataTransfer.files)) {\n if (isValidImageFile(file, allowedMimeTypes, maxFileSize)) {\n imageFiles.push(file);\n }\n }\n\n if (imageFiles.length === 0) return false;\n\n event.preventDefault();\n\n // Get drop position\n const pos = view.posAtCoords({\n left: event.clientX,\n top: event.clientY,\n });\n if (!pos) return false;\n\n handleFiles(view, imageFiles, pos.pos);\n return true;\n },\n },\n });\n}\n","/**\n * Image Node\n *\n * Block-level (default) or inline image element.\n * Supports src, alt, title, width, height, loading, crossorigin, float attributes.\n *\n * Options:\n * - inline: false (default) — block-level image | true — inline image within paragraphs\n * - allowBase64: true (default) — allow data:image/ URLs | false — only http/https URLs\n *\n * XSS Protection (blocklist approach):\n * - Blocks javascript:, vbscript:, file: protocols\n * - Blocks data: URLs unless allowBase64 AND specifically data:image/\n * - Allows http(s), relative paths, protocol-relative URLs\n * - Defense in depth: validated in parseHTML, renderHTML, setImage command, and input rule\n */\n\nimport { Node, PluginKey, positionFloating, defaultIcons } from '@domternal/core';\nimport type { Editor, CommandSpec, ToolbarItem } from '@domternal/core';\nimport { Plugin, NodeSelection } from '@domternal/pm/state';\nimport { InputRule } from '@domternal/pm/inputrules';\nimport type { Node as PmNode } from '@domternal/pm/model';\nimport type { EditorView } from '@domternal/pm/view';\nimport { imageUploadPlugin } from './imageUploadPlugin.js';\n\n/** Float values for image text wrapping. */\nexport type ImageFloat = 'none' | 'left' | 'right' | 'center';\n\n/**\n * Typed options for the setImage command.\n * src is required — it makes no sense to insert an image without a source URL.\n */\nexport interface SetImageOptions {\n src: string;\n alt?: string;\n title?: string;\n width?: string | number;\n height?: string | number;\n loading?: 'lazy' | 'eager';\n crossorigin?: 'anonymous' | 'use-credentials';\n float?: ImageFloat;\n}\n\ndeclare module '@domternal/core' {\n interface RawCommands {\n setImage: CommandSpec<[attributes: SetImageOptions]>;\n setImageFloat: CommandSpec<[float: ImageFloat]>;\n deleteImage: CommandSpec;\n }\n}\n\n/**\n * Validates image src URL for XSS protection.\n * Blocks: javascript:, vbscript:, file:, and data: (unless allowBase64 AND data:image/).\n * Allows everything else: http(s), relative paths, protocol-relative URLs, etc.\n */\nfunction isValidImageSrc(value: unknown, allowBase64: boolean): boolean {\n if (value === null || value === undefined) return true; // null is valid (no src)\n if (typeof value !== 'string') return false;\n if (value === '') return true; // empty string is valid\n\n // Block dangerous protocols\n if (/^(javascript|vbscript|file):/i.test(value)) return false;\n\n // Block data: URLs unless allowBase64 AND specifically data:image/\n if (/^data:/i.test(value)) {\n return allowBase64 && /^data:image\\//i.test(value);\n }\n\n // Allow everything else: http(s), relative paths, protocol-relative, etc.\n return true;\n}\n\n/** Reads a File as a base64 data URL. */\nfunction readFileAsDataURL(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => { resolve(reader.result as string); };\n reader.onerror = () => { reject(reader.error ?? new Error('FileReader error')); };\n reader.readAsDataURL(file);\n });\n}\n\nexport interface ImageOptions {\n /**\n * Whether images are inline (within paragraphs) or block-level (default: false)\n * When true, images can appear alongside text within a paragraph.\n */\n inline: boolean;\n /**\n * Allow base64 data:image/ URLs (default: true)\n * When false, only http:// and https:// URLs are allowed\n */\n allowBase64: boolean;\n HTMLAttributes: Record<string, unknown>;\n /**\n * Async function that uploads a file and returns the URL.\n * When provided, enables paste/drop image upload.\n * When null (default), paste/drop is not handled.\n */\n uploadHandler: ((file: File) => Promise<string>) | null;\n /**\n * Allowed MIME types for upload.\n * @default ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml', 'image/avif']\n */\n allowedMimeTypes: string[];\n /**\n * Maximum file size in bytes. 0 = unlimited.\n * @default 0\n */\n maxFileSize: number;\n /**\n * Called when upload starts for a file.\n */\n onUploadStart: ((file: File) => void) | null;\n /**\n * Called when upload fails. Receives the error and the file.\n */\n onUploadError: ((error: Error, file: File) => void) | null;\n}\n\nexport const Image = Node.create<ImageOptions>({\n name: 'image',\n group() {\n return this.options.inline ? 'inline' : 'block';\n },\n inline() {\n return this.options.inline;\n },\n draggable: true,\n atom: true,\n\n addOptions() {\n return {\n inline: false,\n allowBase64: true,\n HTMLAttributes: {},\n uploadHandler: null,\n allowedMimeTypes: [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/avif',\n ],\n maxFileSize: 0,\n onUploadStart: null,\n onUploadError: null,\n };\n },\n\n addAttributes() {\n const { options } = this;\n return {\n src: {\n default: null,\n parseHTML: (element: HTMLElement) => {\n const src = element.getAttribute('src');\n // Validate on parse - reject invalid URLs\n if (src && !isValidImageSrc(src, options.allowBase64)) {\n return null;\n }\n return src;\n },\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['src']) return {};\n return { src: attributes['src'] as string };\n },\n },\n alt: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('alt'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['alt']) return {};\n return { alt: attributes['alt'] as string };\n },\n },\n title: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('title'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['title']) return {};\n return { title: attributes['title'] as string };\n },\n },\n width: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('width'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['width']) return {};\n return { width: attributes['width'] as string };\n },\n },\n height: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('height'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['height']) return {};\n return { height: attributes['height'] as string };\n },\n },\n loading: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('loading'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['loading']) return {};\n return { loading: attributes['loading'] as string };\n },\n },\n crossorigin: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute('crossorigin'),\n renderHTML: (attributes: Record<string, unknown>) => {\n if (!attributes['crossorigin']) return {};\n return { crossorigin: attributes['crossorigin'] as string };\n },\n },\n float: {\n default: 'none',\n parseHTML: (element: HTMLElement) => {\n const style = element.style;\n if (style.float === 'left') return 'left';\n if (style.float === 'right') return 'right';\n if (style.marginLeft === 'auto' && style.marginRight === 'auto') return 'center';\n const align = element.getAttribute('align');\n if (align === 'left') return 'left';\n if (align === 'right') return 'right';\n if (align === 'center' || align === 'middle') return 'center';\n return 'none';\n },\n renderHTML: (attributes: Record<string, unknown>) => {\n const float = attributes['float'] as string;\n if (!float || float === 'none') return {};\n if (float === 'left') return { style: 'float: left; margin: 0 1em 1em 0;' };\n if (float === 'right') return { style: 'float: right; margin: 0 0 1em 1em;' };\n if (float === 'center') return { style: 'display: block; margin-left: auto; margin-right: auto;' };\n return {};\n },\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'img[src]' }];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const src = node.attrs['src'] as string | null;\n\n // XSS protection: defense in depth - validate again on render\n if (src && !isValidImageSrc(src, this.options.allowBase64)) {\n // Return image with empty src if URL is invalid (should not happen due to parse validation)\n return ['img', { ...this.options.HTMLAttributes, ...HTMLAttributes, src: '' }];\n }\n\n return ['img', { ...this.options.HTMLAttributes, ...HTMLAttributes }];\n },\n\n leafText(node) {\n return (node.attrs['alt'] as string | null) ?? '';\n },\n\n addInputRules() {\n const { nodeType, options } = this;\n if (!nodeType) return [];\n\n return [\n new InputRule(\n /(?:^|\\s)(!\\[(.+|:?)]\\((\\S+)(?:(?:\\s+)[\"'\\u201C\\u201D\\u2018\\u2019]([^\"'\\u201C\\u201D\\u2018\\u2019]+)[\"'\\u201C\\u201D\\u2018\\u2019])?\\))$/,\n (state, match, start, end) => {\n const [fullMatch, wrapper, alt, src, title] = match;\n if (!src || !wrapper) return null;\n\n // XSS validation: reject dangerous URLs in markdown syntax too\n if (!isValidImageSrc(src, options.allowBase64)) return null;\n\n const { tr } = state;\n const attrs: Record<string, unknown> = {\n src,\n alt: alt ?? null,\n title: title ?? null,\n };\n\n // Adjust start for leading whitespace before ![\n const offset = fullMatch.length - wrapper.length;\n const from = start + offset;\n\n tr.replaceWith(from, end, nodeType.create(attrs));\n return tr;\n }\n ),\n ];\n },\n\n addToolbarItems(): ToolbarItem[] {\n return [\n // Main toolbar insert button\n {\n type: 'button',\n name: 'image',\n command: 'setImage',\n commandArgs: [{ src: '' }],\n icon: 'image',\n label: 'Insert Image',\n group: 'insert',\n priority: 150,\n emitEvent: 'insertImage',\n },\n // Bubble menu only: float controls\n { type: 'button', name: 'imageFloatNone', command: 'setImageFloat', commandArgs: ['none'], icon: 'textIndent', label: 'Inline', group: 'image-float', priority: 100, isActive: { name: 'image', attributes: { float: 'none' } }, toolbar: false, bubbleMenu: 'image' },\n { type: 'button', name: 'imageFloatLeft', command: 'setImageFloat', commandArgs: ['left'], icon: 'textAlignLeft', label: 'Float left', group: 'image-float', priority: 90, isActive: { name: 'image', attributes: { float: 'left' } }, toolbar: false, bubbleMenu: 'image' },\n { type: 'button', name: 'imageFloatCenter', command: 'setImageFloat', commandArgs: ['center'], icon: 'textAlignCenter', label: 'Center', group: 'image-float', priority: 80, isActive: { name: 'image', attributes: { float: 'center' } }, toolbar: false, bubbleMenu: 'image' },\n { type: 'button', name: 'imageFloatRight', command: 'setImageFloat', commandArgs: ['right'], icon: 'textAlignRight', label: 'Float right', group: 'image-float', priority: 70, isActive: { name: 'image', attributes: { float: 'right' } }, toolbar: false, bubbleMenu: 'image' },\n // Bubble menu only: delete\n { type: 'button', name: 'deleteImage', command: 'deleteImage', icon: 'trash', label: 'Delete', group: 'image-actions', priority: 50, toolbar: false, bubbleMenu: 'image' },\n ];\n },\n\n addNodeView() {\n return (node: PmNode, view: EditorView, getPos: () => number | undefined) => {\n const dom = document.createElement('div');\n dom.className = 'dm-image-resizable';\n dom.draggable = true;\n\n const applyFloat = (float: string): void => {\n if (float && float !== 'none') {\n dom.setAttribute('data-float', float);\n } else {\n dom.removeAttribute('data-float');\n }\n };\n applyFloat(node.attrs['float'] as string);\n\n const img = document.createElement('img');\n img.src = node.attrs['src'] as string;\n if (node.attrs['alt']) img.alt = node.attrs['alt'] as string;\n if (node.attrs['title']) img.title = node.attrs['title'] as string;\n if (node.attrs['width']) {\n img.style.width = `${String(node.attrs['width'] as number)}px`;\n }\n dom.appendChild(img);\n\n // Click-to-select: floated images confuse ProseMirror's posAtCoords,\n // so we explicitly create a NodeSelection on mousedown.\n dom.addEventListener('mousedown', (e) => {\n if ((e.target as HTMLElement).closest('.dm-image-handle')) return;\n const pos = getPos();\n if (pos === undefined) return;\n const { selection } = view.state;\n // Already selected → let default (drag) proceed\n if (selection instanceof NodeSelection && selection.from === pos) return;\n e.preventDefault();\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos)));\n view.focus();\n });\n\n // Resize handles (4 corners)\n for (const corner of ['nw', 'ne', 'sw', 'se']) {\n const handle = document.createElement('div');\n handle.className = `dm-image-handle dm-image-handle-${corner}`;\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n const startX = e.clientX;\n const startWidth = img.offsetWidth;\n const isLeft = corner.includes('w');\n\n const onMouseMove = (ev: MouseEvent): void => {\n const dx = isLeft ? startX - ev.clientX : ev.clientX - startX;\n const newWidth = Math.max(50, startWidth + dx);\n img.style.width = `${String(newWidth)}px`;\n };\n\n const onMouseUp = (): void => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n\n const pos = getPos();\n if (pos === undefined) return;\n const currentNode = view.state.doc.nodeAt(pos);\n if (!currentNode) return;\n const tr = view.state.tr.setNodeMarkup(pos, undefined, {\n ...currentNode.attrs,\n width: img.offsetWidth,\n });\n view.dispatch(tr);\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n document.body.style.cursor = isLeft ? 'nw-resize' : 'ne-resize';\n document.body.style.userSelect = 'none';\n });\n dom.appendChild(handle);\n }\n\n return {\n dom,\n update(updatedNode: PmNode) {\n if (updatedNode.type.name !== 'image') return false;\n img.src = updatedNode.attrs['src'] as string;\n img.alt = updatedNode.attrs['alt'] as string;\n img.title = updatedNode.attrs['title'] as string;\n if (updatedNode.attrs['width']) {\n img.style.width = `${String(updatedNode.attrs['width'] as number)}px`;\n } else {\n img.style.width = '';\n }\n applyFloat(updatedNode.attrs['float'] as string);\n node = updatedNode;\n return true;\n },\n selectNode() {\n dom.classList.add('ProseMirror-selectednode');\n },\n deselectNode() {\n dom.classList.remove('ProseMirror-selectednode');\n },\n };\n };\n },\n\n addCommands() {\n return {\n setImage:\n (attributes: SetImageOptions) =>\n ({ tr, dispatch }) => {\n // XSS protection: validate src URL before inserting\n if (!isValidImageSrc(attributes.src, this.options.allowBase64)) {\n return false;\n }\n\n if (!this.nodeType) return false;\n\n // Refuse insertion inside code blocks\n if (tr.selection.$from.parent.type.spec.code) return false;\n\n if (dispatch) {\n const node = this.nodeType.create(attributes);\n tr.replaceSelectionWith(node);\n dispatch(tr);\n }\n\n return true;\n },\n\n deleteImage:\n () =>\n ({ tr, dispatch }) => {\n if (dispatch) {\n tr.deleteSelection();\n dispatch(tr);\n }\n return true;\n },\n\n setImageFloat:\n (float: ImageFloat) =>\n ({ tr, state, dispatch }) => {\n if (!['none', 'left', 'right', 'center'].includes(float)) return false;\n\n const { selection } = state;\n const node = state.doc.nodeAt(selection.from);\n if (node?.type.name !== 'image') return false;\n\n if (dispatch) {\n tr.setNodeMarkup(selection.from, undefined, {\n ...node.attrs,\n float,\n });\n dispatch(tr);\n }\n return true;\n },\n };\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = [];\n const editor = this.editor as unknown as Editor;\n const nodeType = this.nodeType;\n const options = this.options;\n const storage = this.storage as Record<string, unknown>;\n\n // Image popover + drag overlay + paste/drop plugin\n if (nodeType) {\n // --- Build popover DOM ---\n const el = document.createElement('div');\n el.className = 'dm-image-popover';\n el.setAttribute('data-dm-editor-ui', '');\n\n const urlInput = document.createElement('input');\n urlInput.type = 'url';\n urlInput.placeholder = 'Image URL...';\n urlInput.className = 'dm-image-popover-input';\n\n const applyBtn = document.createElement('button');\n applyBtn.type = 'button';\n applyBtn.className = 'dm-image-popover-btn dm-image-popover-apply';\n applyBtn.title = 'Insert image';\n applyBtn.innerHTML = defaultIcons['check'] ?? '';\n\n const browseBtn = document.createElement('button');\n browseBtn.type = 'button';\n browseBtn.className = 'dm-image-popover-btn dm-image-popover-browse';\n browseBtn.title = 'Browse files';\n browseBtn.innerHTML = defaultIcons['image'] ?? '';\n\n el.appendChild(urlInput);\n el.appendChild(applyBtn);\n el.appendChild(browseBtn);\n\n let isOpen = false;\n let cleanupFloating: (() => void) | null = null;\n let toggleAnchor: HTMLElement | null = null;\n\n const showPopover = (anchorElement?: HTMLElement): void => {\n toggleAnchor = anchorElement ?? null;\n urlInput.value = '';\n el.setAttribute('data-show', '');\n isOpen = true;\n storage['isOpen'] = true;\n // Dispatch to trigger toolbar expanded state refresh\n editor.view.dispatch(editor.view.state.tr);\n\n const reference: Element | { getBoundingClientRect: () => DOMRect } = anchorElement ?? {\n getBoundingClientRect: () => {\n const coords = editor.view.coordsAtPos(editor.view.state.selection.from);\n return new DOMRect(coords.left, coords.top, 0, coords.bottom - coords.top);\n },\n };\n\n cleanupFloating?.();\n cleanupFloating = positionFloating(reference, el, {\n placement: 'bottom',\n offsetValue: 4,\n });\n\n urlInput.focus();\n };\n\n const hidePopover = (): void => {\n if (!isOpen) return;\n toggleAnchor = null;\n cleanupFloating?.();\n cleanupFloating = null;\n el.removeAttribute('data-show');\n isOpen = false;\n storage['isOpen'] = false;\n // Dispatch to trigger toolbar expanded state refresh\n editor.view.dispatch(editor.view.state.tr);\n };\n\n const closePopover = (): void => {\n hidePopover();\n editor.view.focus();\n };\n\n const insertFromFile = (file: File): void => {\n if (options.uploadHandler) {\n options.uploadHandler(file)\n .then((url) => {\n editor.commands.setImage({ src: url });\n })\n .catch((error: unknown) => {\n if (options.onUploadError) {\n options.onUploadError(\n error instanceof Error ? error : new Error(String(error)),\n file,\n );\n }\n });\n } else {\n void readFileAsDataURL(file).then(src => {\n const { tr } = editor.view.state;\n tr.replaceSelectionWith(nodeType.create({ src }));\n editor.view.dispatch(tr);\n });\n }\n };\n\n const applyUrl = (): void => {\n const src = urlInput.value.trim();\n if (src && isValidImageSrc(src, options.allowBase64)) {\n editor.commands.setImage({ src });\n }\n closePopover();\n };\n\n const openFileBrowser = (): void => {\n hidePopover();\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = options.allowedMimeTypes.join(',');\n input.addEventListener('change', () => {\n const file = input.files?.[0];\n if (file) insertFromFile(file);\n editor.view.focus();\n });\n input.click();\n };\n\n // Event: toolbar button or Ctrl+Shift+I\n const onInsertImage = (data: { anchorElement?: HTMLElement }): void => {\n if (isOpen) {\n closePopover();\n } else {\n showPopover(data.anchorElement);\n }\n };\n\n // Popover event listeners\n const onInputKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'Enter') { e.preventDefault(); applyUrl(); }\n else if (e.key === 'Escape') { e.preventDefault(); closePopover(); }\n else if (e.key === 'Tab') { e.preventDefault(); applyBtn.focus(); }\n };\n\n const onButtonKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') { e.preventDefault(); closePopover(); }\n else if (e.key === 'Enter') { e.preventDefault(); (e.target as HTMLElement).click(); }\n else if (e.key === 'Tab') {\n e.preventDefault();\n const target = e.target as HTMLElement;\n if (e.shiftKey) {\n if (target === applyBtn) urlInput.focus();\n else applyBtn.focus();\n } else {\n if (target === applyBtn) browseBtn.focus();\n else urlInput.focus();\n }\n }\n };\n\n const onClickOutside = (e: MouseEvent): void => {\n if (!isOpen || el.contains(e.target as globalThis.Node)) return;\n if (toggleAnchor && (toggleAnchor === e.target || toggleAnchor.contains(e.target as globalThis.Node))) return;\n hidePopover();\n };\n\n const onPreventBlur = (e: MouseEvent): void => { e.preventDefault(); };\n\n // --- Drag overlay helpers ---\n let dragCounter = 0;\n\n const hasImageItems = (dt: DataTransfer | null): boolean => {\n if (!dt?.items) return false;\n for (const item of Array.from(dt.items)) {\n if (item.kind === 'file' && item.type.startsWith('image/')) return true;\n }\n return false;\n };\n\n plugins.push(new Plugin({\n key: new PluginKey('imageFileBrowser'),\n props: {\n handleDOMEvents: {\n dragenter(view, event) {\n if (!hasImageItems(event.dataTransfer)) return false;\n dragCounter++;\n view.dom.closest('.dm-editor')?.classList.add('dm-dragover');\n return false;\n },\n dragleave(view) {\n dragCounter--;\n if (dragCounter <= 0) {\n dragCounter = 0;\n view.dom.closest('.dm-editor')?.classList.remove('dm-dragover');\n }\n return false;\n },\n drop(view) {\n dragCounter = 0;\n view.dom.closest('.dm-editor')?.classList.remove('dm-dragover');\n return false;\n },\n },\n handlePaste(view, event) {\n // When uploadHandler is set, let imageUploadPlugin handle paste\n if (options.uploadHandler) return false;\n const items = event.clipboardData?.items;\n if (!items) return false;\n\n for (const item of Array.from(items)) {\n if (item.kind === 'file' && item.type.startsWith('image/')) {\n const file = item.getAsFile();\n if (!file) continue;\n if (!options.allowedMimeTypes.includes(file.type)) continue;\n if (options.maxFileSize > 0 && file.size > options.maxFileSize) continue;\n\n event.preventDefault();\n void readFileAsDataURL(file).then(src => {\n const { tr } = view.state;\n tr.replaceSelectionWith(nodeType.create({ src }));\n view.dispatch(tr);\n });\n return true;\n }\n }\n return false;\n },\n handleDrop(view, event) {\n // When uploadHandler is set, let imageUploadPlugin handle it\n if (options.uploadHandler) return false;\n const files = event.dataTransfer?.files;\n if (!files?.length) return false;\n\n const file = files[0];\n if (!file || !options.allowedMimeTypes.includes(file.type)) return false;\n if (options.maxFileSize > 0 && file.size > options.maxFileSize) return false;\n\n event.preventDefault();\n const pos = view.posAtCoords({ left: event.clientX, top: event.clientY });\n if (!pos) return false;\n\n void readFileAsDataURL(file).then(src => {\n const tr = view.state.tr;\n tr.insert(pos.pos, nodeType.create({ src }));\n view.dispatch(tr);\n });\n return true;\n },\n },\n view() {\n // Append popover to body (escape overflow:hidden on .dm-editor)\n document.body.appendChild(el);\n\n // Register popover event listeners\n urlInput.addEventListener('keydown', onInputKeydown);\n applyBtn.addEventListener('mousedown', onPreventBlur);\n applyBtn.addEventListener('click', applyUrl);\n applyBtn.addEventListener('keydown', onButtonKeydown);\n browseBtn.addEventListener('mousedown', onPreventBlur);\n browseBtn.addEventListener('click', openFileBrowser);\n browseBtn.addEventListener('keydown', onButtonKeydown);\n document.addEventListener('mousedown', onClickOutside);\n\n // 'insertImage' is a dynamic event not in EditorEvents — cast once\n interface DynEvents { on(e: string, fn: typeof onInsertImage): void; off(e: string, fn: typeof onInsertImage): void }\n const dynEditor = editor as unknown as DynEvents;\n dynEditor.on('insertImage', onInsertImage);\n\n return {\n destroy() {\n hidePopover();\n urlInput.removeEventListener('keydown', onInputKeydown);\n applyBtn.removeEventListener('mousedown', onPreventBlur);\n applyBtn.removeEventListener('click', applyUrl);\n applyBtn.removeEventListener('keydown', onButtonKeydown);\n browseBtn.removeEventListener('mousedown', onPreventBlur);\n browseBtn.removeEventListener('click', openFileBrowser);\n browseBtn.removeEventListener('keydown', onButtonKeydown);\n document.removeEventListener('mousedown', onClickOutside);\n dynEditor.off('insertImage', onInsertImage);\n el.remove();\n },\n };\n },\n }));\n }\n\n // Paste/drop upload plugin\n if (options.uploadHandler && nodeType) {\n plugins.push(\n imageUploadPlugin({\n nodeType,\n uploadHandler: options.uploadHandler,\n allowedMimeTypes: options.allowedMimeTypes,\n maxFileSize: options.maxFileSize,\n onUploadStart: options.onUploadStart,\n onUploadError: options.onUploadError,\n }),\n );\n }\n\n return plugins;\n },\n});\n"]}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@domternal/extension-image",
3
+ "version": "0.2.0",
4
+ "description": "Image node extension for Domternal editor",
5
+ "author": "https://github.com/ThomasNowHere",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "engines": {
10
+ "node": ">=20"
11
+ },
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "require": {
22
+ "types": "./dist/index.d.cts",
23
+ "default": "./dist/index.cjs"
24
+ }
25
+ }
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsup --clean",
32
+ "dev": "tsup --watch",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
35
+ "lint": "eslint src",
36
+ "typecheck": "tsc --noEmit",
37
+ "prepublishOnly": "node -e \"const p=JSON.parse(require('fs').readFileSync('package.json','utf8'));delete p.devDependencies;if(p.dependencies){for(const[k,v]of Object.entries(p.dependencies)){if(v==='workspace:*')p.dependencies[k]='>=0.2.0'}}require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\"",
38
+ "postpublish": "git checkout package.json"
39
+ },
40
+ "peerDependencies": {
41
+ "@domternal/core": ">=0.2.0",
42
+ "@domternal/pm": ">=0.2.0"
43
+ },
44
+ "keywords": [
45
+ "prosemirror",
46
+ "editor",
47
+ "image",
48
+ "domternal"
49
+ ],
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/domternal/domternal.git",
53
+ "directory": "packages/extension-image"
54
+ },
55
+ "bugs": {
56
+ "url": "https://github.com/domternal/domternal/issues"
57
+ },
58
+ "homepage": "https://domternal.dev"
59
+ }