mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-23 01:01:20 +00:00
78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import { basicSetup } from "@codemirror/basic-setup";
|
|
import { xml } from "@codemirror/lang-xml";
|
|
import { EditorState } from "@codemirror/state";
|
|
import { EditorView } from "@codemirror/view";
|
|
import { css, html, LitElement, TemplateResult } from "lit";
|
|
import { customElement, queryAssignedNodes, state } from "lit/decorators.js";
|
|
import prettifyXML from "xml-formatter";
|
|
|
|
@customElement("xml-editor")
|
|
export class XMLEditor extends LitElement {
|
|
@queryAssignedNodes("textarea", true)
|
|
_textarea!: NodeListOf<HTMLTextAreaElement>;
|
|
|
|
@state()
|
|
editorState!: EditorState;
|
|
|
|
@state()
|
|
editorView!: EditorView;
|
|
|
|
firstUpdated(): void {
|
|
const minHeightEditor = EditorView.theme({
|
|
".cm-content, .cm-gutter": {
|
|
minHeight: this._textarea[0].clientHeight + "px",
|
|
},
|
|
});
|
|
|
|
this.editorState = EditorState.create({
|
|
doc: this._textarea[0].value
|
|
? prettifyXML(this._textarea[0].value, {
|
|
indentation: " ",
|
|
})
|
|
: "",
|
|
extensions: [basicSetup, xml(), minHeightEditor],
|
|
});
|
|
|
|
this.editorView = new EditorView({
|
|
state: this.editorState,
|
|
root: this.shadowRoot as ShadowRoot,
|
|
parent: this.shadowRoot as ShadowRoot,
|
|
});
|
|
|
|
this._textarea[0].hidden = true;
|
|
if (this._textarea[0].form) {
|
|
this._textarea[0].form.addEventListener("submit", () => {
|
|
this._textarea[0].value = this.editorView.state.doc.toString();
|
|
});
|
|
}
|
|
}
|
|
|
|
disconnectedCallback(): void {
|
|
if (this._textarea[0].form) {
|
|
this._textarea[0].form.removeEventListener("submit", () => {
|
|
this._textarea[0].value = this.editorView.state.doc.toString();
|
|
});
|
|
}
|
|
}
|
|
|
|
static styles = css`
|
|
.cm-wrap {
|
|
border-radius: 0.5rem;
|
|
overflow: hidden;
|
|
border: 3px solid #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.cm-editor.cm-focused {
|
|
outline: 2px solid transparent;
|
|
box-shadow: 0 0 0 2px #e7f9e4, 0 0 0 calc(4px) #009486;
|
|
}
|
|
.cm-gutters {
|
|
background-color: #ffffff !important;
|
|
}
|
|
`;
|
|
|
|
render(): TemplateResult<1> {
|
|
return html`<slot name="textarea"></slot>`;
|
|
}
|
|
}
|