UNPKG

lexical-remark

Version:

This package contains Markdown helpers and functionality for Lexical using remark-parse.

112 lines (111 loc) 3.25 kB
/* eslint-disable @typescript-eslint/no-use-before-define */ import lexicalUtils from '@lexical/utils'; import lexical from 'lexical'; function convertAttachmentElement(domNode) { return { node: $createAttachmentNode(domNode.getAttribute('href') ?? '', domNode.getAttribute('download') ?? ''), }; } export class AttachmentNode extends lexical.ElementNode { __filename; __url; constructor(url, filename, key) { super(key); this.__url = url; this.__filename = filename; } static getType() { return 'attachment'; } static clone(node) { return new AttachmentNode(node.__url, node.__filename, node.__key); } createDOM(config, editor) { const dom = document.createElement('a'); dom.href = this.__url; dom.download = this.__filename; return dom; } updateDOM(prevNode, dom, config) { const newText = this.getTextContent() .replace(/^(?:📎)?\s*([^\s]|$)/, '$1') .trim(); if (!newText.length) { this.remove(); return false; } if (!this.getTextContent().startsWith('📎 ') || newText !== this.__filename) { this.setFilename(newText); this.getChildAtIndex(0)?.setTextContent(`📎 ${newText}`); dom.download = newText; } if (prevNode.__url !== this.__url) { dom.href = this.__url; } return false; } static importDOM() { return { a: (domNode) => { if (!lexicalUtils.isHTMLAnchorElement(domNode)) { return null; } if (!domNode.getAttribute('download')) { return null; } return { conversion: convertAttachmentElement, priority: lexical.COMMAND_PRIORITY_HIGH, }; }, }; } static importJSON(serializedNode) { return $createAttachmentNode(serializedNode.url, serializedNode.filename); } exportJSON() { return { ...super.exportJSON(), filename: this.getFilename(), type: 'attachment', url: this.getURL(), version: 1, }; } insertNewAfter(selection, restoreSelection) { const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection); return element; } canInsertTextBefore() { return false; } canInsertTextAfter() { return false; } canBeEmpty() { return false; } isInline() { return true; } getFilename() { return this.getLatest().__filename; } setFilename(filename) { const writable = this.getWritable(); writable.__filename = filename; } getURL() { return this.getLatest().__url; } setURL(url) { const writable = this.getWritable(); writable.__url = url; } } export function $createAttachmentNode(url, filename, key) { return new AttachmentNode(url, filename, key); } export function $isAttachmentNode(node) { return node instanceof AttachmentNode; }