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"