| /** | |
| * @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); | |
| } | |
| } |