blob: b211a9966ab0b3e23e11b8c6cb7a2d0590cdfd1b [file] [log] [blame]
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '@gerritcodereview/typescript-api/gerrit';
import {PluginApi} from '@gerritcodereview/typescript-api/plugin';
import {html, LitElement} from 'lit';
import {customElement, property, query} from 'lit/decorators.js';
import {setScriptSrc} from './safe-script';
/**
* <codemirror-element> is defined in a separate javascript bundle, so let's
* define its interface here.
*/
interface CodeMirrorElement extends HTMLElement {
lineNum?: number;
prefs?: unknown;
fileContent?: string;
fileType?: string;
}
declare global {
interface HTMLElementTagNameMap {
'gr-editor': GrEditor;
// @ts-ignore TS2717: Subsequent property declarations must have the same
// type.
'codemirror-element': CodeMirrorElement;
}
}
/**
* This component just loads the CodeMirror js bundle lazily and converts the
* Gerrit preferences into CodeMirror params.
*/
@customElement('gr-editor')
export class GrEditor extends LitElement {
@property({type: String}) fileContent?: string;
@property({type: String}) fileType?: string;
@property({type: Number}) lineNum?: number;
@property({type: Object}) prefs?: unknown;
@property({type: Object}) plugin?: PluginApi;
@property({type: Boolean}) darkMode = false;
@query('#codemirror') mirror?: HTMLScriptElement;
override render() {
if (!window.customElements.get('codemirror-element')) return;
return html`
<codemirror-element
id="codemirror"
.lineNum=${this.lineNum}
.prefs=${this.prefs}
.fileContent=${this.fileContent}
.fileType=${this.fileType}
?darkMode=${this.darkMode}
>
</codemirror-element>
`;
}
override connectedCallback() {
super.connectedCallback();
this.loadCodeMirrorElement();
window.customElements.whenDefined('codemirror-element').then(() => {
this.requestUpdate();
});
}
private loadCodeMirrorElement() {
if (document.head.querySelector('#codemirror')) return;
const script = document.createElement('script');
script.id = 'codemirror';
script.crossOrigin = 'anonymous';
setScriptSrc(script, this.plugin?.url() ?? '');
document.head.appendChild(script);
}
}