diff --git a/src/core/plugin.ts b/src/core/plugin.ts index 285da246..95b57b3f 100644 --- a/src/core/plugin.ts +++ b/src/core/plugin.ts @@ -21,15 +21,16 @@ export abstract class UIPPlugin extends ESLBaseElement { return this._root; } protected set root(root: UIPRoot | null) { - this._root && this._root.removeEventListener('state:change', this._onRootChange); + this._root && this._root.removeEventListener('state:change', this._onRootStateChange); this._root = root; - this._root && this._root.addEventListener('state:change', this._onRootChange); + this._root && this._root.addEventListener('state:change', this._onRootStateChange); } protected connectedCallback() { super.connectedCallback(); this.classList.add('uip-plugin'); this.root = this.closest(`${UIPRoot.is}`) as UIPRoot; + this.root && this.handleChange(); } protected disconnectedCallback() { this.root = null; @@ -42,9 +43,9 @@ export abstract class UIPPlugin extends ESLBaseElement { /** Handles root state change event. Delegate non self triggered events to the {@link handleChange}*/ @bind - protected _onRootChange(e: CustomEvent) { + protected _onRootStateChange(e: CustomEvent) { if (e.detail.origin === this) return; - this.handleChange(e); + this.handleChange(); } /** Dispatch change state */ @@ -57,5 +58,5 @@ export abstract class UIPPlugin extends ESLBaseElement { } /** Handles root state change. Will not process self triggered changes */ - protected abstract handleChange(e: CustomEvent): void; + protected abstract handleChange(): void; } diff --git a/src/core/root.ts b/src/core/root.ts index b9c1da06..9e3a6559 100644 --- a/src/core/root.ts +++ b/src/core/root.ts @@ -1,18 +1,24 @@ import {bind} from '@exadel/esl'; import {ESLBaseElement} from '@exadel/esl/modules/esl-base-element/core'; import {EventUtils} from '@exadel/esl/modules/esl-utils/dom/events'; +import {UIPStateModel} from '../utils/state-model/state-model'; export class UIPRoot extends ESLBaseElement { public static is = 'uip-root'; - private _state: string; + private _model: UIPStateModel; - public get state() { - return this._state; + public get model(): UIPStateModel { + return this._model; + } + + public set model(model: UIPStateModel) { + this._model = model; } protected connectedCallback() { super.connectedCallback(); this.bindEvents(); + this.model = new UIPStateModel(); } protected disconnectedCallback() { @@ -30,7 +36,7 @@ export class UIPRoot extends ESLBaseElement { @bind protected _onStateChange(e: CustomEvent) { - this._state = e.detail.markup; + this.model.html = e.detail.markup; const detail = Object.assign({ origin: e.target }, e.detail); diff --git a/src/editor/editor.ts b/src/editor/editor.ts index e14504f4..bcb160d5 100644 --- a/src/editor/editor.ts +++ b/src/editor/editor.ts @@ -44,8 +44,8 @@ export class UIPEditor extends UIPPlugin { }, 1000); @bind - protected handleChange(e: CustomEvent): void { - const {markup} = e.detail; + protected handleChange(): void { + const markup = this.root!.model.html; const $inner = document.createElement('div'); $inner.classList.add('uip-editor-inner'); diff --git a/src/preview/preview.ts b/src/preview/preview.ts index 759d4016..69901d4a 100644 --- a/src/preview/preview.ts +++ b/src/preview/preview.ts @@ -13,9 +13,8 @@ export class UIPPreview extends UIPPlugin { } @bind - protected handleChange(e: CustomEvent): void { - const {markup} = e.detail; - this.$inner.innerHTML = markup; + protected handleChange(): void { + this.$inner.innerHTML = this.root!.model.html; this.innerHTML = ''; this.appendChild(this.$inner); } diff --git a/src/settings/settings.ts b/src/settings/settings.ts index d842327b..81dd6364 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -3,7 +3,6 @@ import {bind} from '@exadel/esl/modules/esl-utils/decorators/bind'; import {attr} from '@exadel/esl/modules/esl-base-element/core'; import {CSSClassUtils} from '@exadel/esl'; import {UIPPlugin} from '../core/plugin'; -import {UIPStateModel} from '../utils/state-model/state-model'; export class UIPSettings extends UIPPlugin { public static is = 'uip-settings'; @@ -12,13 +11,10 @@ export class UIPSettings extends UIPPlugin { @attr({defaultValue: 'Settings'}) public label: string; @attr({defaultValue: 'settings-attached'}) public rootClass: string; - protected model: UIPStateModel; - protected connectedCallback() { super.connectedCallback(); this.bindEvents(); this.root && CSSClassUtils.add(this.root, this.rootClass); - this.model = new UIPStateModel(); } protected disconnectedCallback(): void { @@ -36,10 +32,11 @@ export class UIPSettings extends UIPPlugin { } protected _onSettingChanged(e: any) { - (e.target as UIPSetting).applyTo(this.model); - this.settings.forEach(setting => setting.updateFrom(this.model)); + if (!this.root) return; - this.dispatchChange(this.model.html); + (e.target as UIPSetting).applyTo(this.root.model); + this.settings.forEach(setting => setting.updateFrom(this.root!.model)); + this.dispatchChange(this.root.model.html); } protected get settings(): UIPSetting[] { @@ -47,11 +44,11 @@ export class UIPSettings extends UIPPlugin { } @bind - public handleChange(e: CustomEvent): void { - this.model.html = e.detail.markup; + protected handleChange(): void { + const model = this.root!.model; for (const setting of this.settings) { - setting.updateFrom(this.model); + setting.updateFrom(model); } } } diff --git a/src/utils/state-model/state-model.ts b/src/utils/state-model/state-model.ts index 5025f1a9..7080585e 100644 --- a/src/utils/state-model/state-model.ts +++ b/src/utils/state-model/state-model.ts @@ -6,7 +6,7 @@ export class UIPStateModel { } public get html(): string { - return this.root.innerHTML; + return this.root? this.root.innerHTML : ''; } public getAttribute(target: string, name: string): (string | null)[] {