diff --git a/package.json b/package.json index 231ad11ac4..b4b6d7e7f3 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "@webcomponents/webcomponentsjs": "^2.2.0", "chart.js": "~2.7.2", "chartjs-chart-timeline": "^0.2.1", + "codemirror": "^5.43.0", "deep-clone-simple": "^1.1.1", "es6-object-assign": "^1.1.0", "eslint-import-resolver-webpack": "^0.10.1", diff --git a/src/panels/lovelace/components/hui-code-editor.ts b/src/panels/lovelace/components/hui-code-editor.ts new file mode 100644 index 0000000000..655250bce5 --- /dev/null +++ b/src/panels/lovelace/components/hui-code-editor.ts @@ -0,0 +1,60 @@ +import CodeMirror from "codemirror"; +import "codemirror/mode/yaml/yaml"; +// tslint:disable-next-line +import codeMirrorCSS from "codemirror/lib/codemirror.css"; +import { fireEvent } from "../../../common/dom/fire_event"; + +let _this; + +declare global { + interface HASSDomEvents { + "code-changed": { + value: string; + }; + } +} + +export class HuiCodeEditor extends HTMLElement { + public cm; + private _value; + + constructor() { + super(); + _this = this; + this._value = ""; + const shadowRoot = this.attachShadow({ mode: "open" }); + shadowRoot.innerHTML = ` + `; + } + + set value(value: string) { + if (this.cm) { + if (value !== this.cm.getValue()) { + this.cm.setValue(value); + } + } + this._value = value; + } + + public connectedCallback() { + if (!this.cm) { + this.cm = CodeMirror(this.shadowRoot, { + value: this._value, + lineNumbers: true, + mode: "yaml", + tabSize: 2, + }); + this.cm.on("changes", this._onChange); + } else { + this.cm.refresh(); + } + } + + private _onChange() { + fireEvent(_this, "code-changed", { value: _this.cm.getValue() }); + } +} + +window.customElements.define("hui-code-editor", HuiCodeEditor); diff --git a/src/panels/lovelace/editor/card-editor/hui-edit-card.ts b/src/panels/lovelace/editor/card-editor/hui-edit-card.ts index 7eac2fba87..4c974e7ecf 100644 --- a/src/panels/lovelace/editor/card-editor/hui-edit-card.ts +++ b/src/panels/lovelace/editor/card-editor/hui-edit-card.ts @@ -30,7 +30,6 @@ import "./hui-card-preview"; import { HuiCardPreview } from "./hui-card-preview"; import { LovelaceCardEditor, Lovelace } from "../../types"; import { YamlChangedEvent, ConfigValue, ConfigError } from "../types"; -import { extYamlSchema } from "../yaml-ext-schema"; import { EntityConfig } from "../../entity-rows/types"; import { getCardElementTag } from "../../common/get-card-element-tag"; import { addCard, replaceCard } from "../config-util"; @@ -217,9 +216,7 @@ export class HuiEditCard extends LitElement { const cardConf: LovelaceCardConfig = this._configValue!.format === "yaml" - ? yaml.safeLoad(this._configValue!.value!, { - schema: extYamlSchema, - }) + ? yaml.safeLoad(this._configValue!.value!) : this._configValue!.value!; try { @@ -244,9 +241,9 @@ export class HuiEditCard extends LitElement { private _handleYamlChanged(ev: YamlChangedEvent): void { this._configValue = { format: "yaml", value: ev.detail.yaml }; try { - const config = yaml.safeLoad(this._configValue.value, { - schema: extYamlSchema, - }) as LovelaceCardConfig; + const config = yaml.safeLoad( + this._configValue.value + ) as LovelaceCardConfig; this._updatePreview(config); this._configState = "OK"; } catch (err) { @@ -295,9 +292,7 @@ export class HuiEditCard extends LitElement { this._uiEditor = !this._uiEditor; } else if (this._configElement && this._configValue!.format === "yaml") { const yamlConfig = this._configValue!.value; - const cardConfig = yaml.safeLoad(yamlConfig, { - schema: extYamlSchema, - }) as LovelaceCardConfig; + const cardConfig = yaml.safeLoad(yamlConfig) as LovelaceCardConfig; this._uiEditor = !this._uiEditor; if (cardConfig.type !== this._cardType) { const succes = await this._loadConfigElement(cardConfig); diff --git a/src/panels/lovelace/editor/card-editor/hui-yaml-editor.ts b/src/panels/lovelace/editor/card-editor/hui-yaml-editor.ts index df2767d902..2b04168c5b 100644 --- a/src/panels/lovelace/editor/card-editor/hui-yaml-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-yaml-editor.ts @@ -9,6 +9,8 @@ import "@polymer/paper-input/paper-textarea"; import { HomeAssistant } from "../../../../types"; import { fireEvent } from "../../../../common/dom/fire_event"; +import "../../components/hui-code-editor"; + export class HuiYAMLEditor extends LitElement { protected hass?: HomeAssistant; private _yaml?: string; @@ -28,11 +30,11 @@ export class HuiYAMLEditor extends LitElement { protected render(): TemplateResult | void { return html` ${this.renderStyle()} - + @code-changed="${this._valueChanged}" + > + `; } @@ -46,11 +48,9 @@ export class HuiYAMLEditor extends LitElement { `; } - private _valueChanged(ev: Event): void { - const target = ev.target! as any; - this._yaml = target.value; + private _valueChanged(ev: CustomEvent): void { fireEvent(this, "yaml-changed", { - yaml: target.value, + yaml: ev.detail.value, }); } } diff --git a/src/panels/lovelace/editor/yaml-ext-schema.ts b/src/panels/lovelace/editor/yaml-ext-schema.ts deleted file mode 100644 index 357962d911..0000000000 --- a/src/panels/lovelace/editor/yaml-ext-schema.ts +++ /dev/null @@ -1,22 +0,0 @@ -import yaml from "js-yaml"; - -const secretYamlType = new yaml.Type("!secret", { - kind: "scalar", - construct(data) { - data = data || ""; - return "!secret " + data; - }, -}); - -const includeYamlType = new yaml.Type("!include", { - kind: "scalar", - construct(data) { - data = data || ""; - return "!include " + data; - }, -}); - -export const extYamlSchema = yaml.Schema.create([ - secretYamlType, - includeYamlType, -]); diff --git a/yarn.lock b/yarn.lock index e7c12feae1..0facc9d04e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4281,6 +4281,11 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +codemirror@^5.43.0: + version "5.43.0" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.43.0.tgz#2454b5e0f7005dc9945ab7b0d9594ccf233da040" + integrity sha512-mljwQWUaWIf85I7QwTBryF2ASaIvmYAL4s5UCanCJFfKeXOKhrqdHWdHiZWAMNT+hjLTCnVx2S/SYTORIgxsgA== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"