Output now uses CodeMirror editor

This commit is contained in:
n1474335 2022-07-02 19:23:03 +01:00
parent bc949b47d9
commit 68733c74cc
14 changed files with 665 additions and 495 deletions

View file

@ -0,0 +1,87 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2022
* @license Apache-2.0
*/
import {WidgetType, Decoration, ViewPlugin} from "@codemirror/view";
/**
* Adds an HTML widget to the Code Mirror editor
*/
class HTMLWidget extends WidgetType {
/**
* HTMLWidget consructor
*/
constructor(html) {
super();
this.html = html;
}
/**
* Builds the DOM node
* @returns {DOMNode}
*/
toDOM() {
const wrap = document.createElement("span");
wrap.setAttribute("id", "output-html");
wrap.innerHTML = this.html;
return wrap;
}
}
/**
* Decorator function to provide a set of widgets for the editor DOM
* @param {EditorView} view
* @param {string} html
* @returns {DecorationSet}
*/
function decorateHTML(view, html) {
const widgets = [];
if (html.length) {
const deco = Decoration.widget({
widget: new HTMLWidget(html),
side: 1
});
widgets.push(deco.range(0));
}
return Decoration.set(widgets);
}
/**
* An HTML Plugin builder
* @param {Object} htmlOutput
* @returns {ViewPlugin}
*/
export function htmlPlugin(htmlOutput) {
const plugin = ViewPlugin.fromClass(
class {
/**
* Plugin constructor
* @param {EditorView} view
*/
constructor(view) {
this.htmlOutput = htmlOutput;
this.decorations = decorateHTML(view, this.htmlOutput.html);
}
/**
* Editor update listener
* @param {ViewUpdate} update
*/
update(update) {
if (this.htmlOutput.changed) {
this.decorations = decorateHTML(update.view, this.htmlOutput.html);
this.htmlOutput.changed = false;
}
}
}, {
decorations: v => v.decorations
}
);
return plugin;
}