UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

167 lines (166 loc) 5.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PeritextDataTransfer = void 0; /** * This class provides methods for transferring data between Peritext and other * formats, such as JSON, HTML, Markdown, etc. A Peritext {@link Fragment} can * be converted to a JSON object, which can be converted to HTML, Markdown, etc. * The reverse is also possible. */ class PeritextDataTransfer { constructor(txt, opts) { this.txt = txt; this.opts = opts; } // ------------------------------------------------------------------ exports toView(range) { return this.txt.editor.export(range); } toFragment(range) { const fragment = this.txt.fragment(range); fragment.refresh(); return fragment; } toJson(range) { const fragment = this.toFragment(range); return fragment.toJson(); } htmlE() { const tools = this.opts.htmlExport; if (!tools) throw new Error('NO_HTML_EXPORT_TOOLS'); return tools; } toJsonMl(range) { const tools = this.htmlE(); const json = this.toJson(range); return tools.toJsonMl(json); } toHast(range) { const tools = this.htmlE(); const json = this.toJson(range); return tools.toHast(json); } toHtml(range, tab, indent) { const tools = this.htmlE(); const json = this.toJson(range); return tools.toHtml(json, tab, indent); } mdE() { const tools = this.opts.mdExport; if (!tools) throw new Error('NO_MD_EXPORT_TOOLS'); return tools; } toMdast(range) { const tools = this.mdE(); const json = this.toJson(range); return tools.toMdast(json); } toMarkdown(range) { const tools = this.mdE(); const json = this.toJson(range); return tools.toMarkdown(json); } toClipboard(range) { const view = this.txt.editor.export(range); const node = this.toJson(range); const html = this.htmlE().exportHtml(view, node); return { 'text/plain': range.text(), 'text/html': html, }; } toFormat(range) { const json = this.txt.editor.exportStyle(range); const html = this.htmlE().exportStyle(json); return { 'text/html': html }; } // ------------------------------------------------------------------ imports fromView(pos, view) { return this.txt.editor.import(pos, view); } fromJson(pos, json) { const tools = this.htmlI(); const view = tools.toViewRange(json); return this.fromView(pos, view); } _imp(pos, data, transform) { const registry = this.txt.editor.getRegistry(); const json = transform(data, registry); return this.fromJson(pos, json); } htmlI() { const tools = this.opts.htmlImport; if (!tools) throw new Error('NO_HTML_IMPORT_TOOLS'); return tools; } fromJsonMl(pos, jsonml) { return this._imp(pos, jsonml, this.htmlI().fromJsonMl); } fromHast(pos, hast) { return this._imp(pos, hast, this.htmlI().fromHast); } fromHtml(pos, html) { return this._imp(pos, html, this.htmlI().fromHtml); } mdI() { const tools = this.opts.mdImport; if (!tools) throw new Error('NO_MD_IMPORT_TOOLS'); return tools; } fromMdast(pos, mdast) { return this._imp(pos, mdast, this.mdI().fromMdast); } fromMarkdown(pos, markdown) { return this._imp(pos, markdown, this.mdI().fromMarkdown); } textFromHtml(html) { return this.htmlI().textFromHtml(html); } /** * Inserts data from the clipboard at a given position. Returns the number * of characters inserted, this can be used by the caller to move the cursor * to the end of the inserted data. * * @param pos View position to insert the data at. * @param data Clipboard data to attempt to insert. * @returns The number of characters inserted. */ fromClipboard(range, data) { const txt = this.txt; const html = data.html; const collapseRange = () => { if (!range.isCollapsed()) txt.editor.delRange(range); range.collapseToStart(); return range.start.viewPos(); }; if (html) { const [view, style] = this.htmlI().importHtml(html, txt.editor.getRegistry()); if (style) { txt.editor.importStyle(range, style); return 0; } else if (view) { const pos = collapseRange(); return this.fromView(pos, view); } } const text = data.text; if (!text) return 0; const pos = collapseRange(); this.txt.insAt(pos, text); return text.length; } fromStyle(range, html) { const style = this.htmlI().importStyle(html); if (!style) return; this.txt.editor.importStyle(range, style); } } exports.PeritextDataTransfer = PeritextDataTransfer;