Skip to content

Commit

Permalink
feat(uip-model): merge setAttribute & transformAttribute methods
Browse files Browse the repository at this point in the history
  • Loading branch information
nattallius committed Jun 25, 2021
1 parent 3320e8d commit c192ae2
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 52 deletions.
44 changes: 23 additions & 21 deletions src/core/state-model.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import {Observable} from '@exadel/esl';
import {UIPPlugin} from './plugin';

export interface changeAttributeConfig {
export type TransformSignature = (current: string | null) => string | boolean | null;

export type ChangeAttrConfig = {
target: string,
name: string,
modifier: UIPPlugin,
value?: string | boolean,
transform?: (current: string | null) => string | null
}
attribute: string,
modifier: UIPPlugin
} & ({
value: string | boolean
} | {
transform: TransformSignature
});

export class UIPStateModel extends Observable {
private _html = new DOMParser().parseFromString('', 'text/html').body;
Expand All @@ -34,30 +38,28 @@ export class UIPStateModel extends Observable {
return Array.from(this._html.querySelectorAll(target)).map(el => el.getAttribute(name));
}

public setAttribute(cfg: changeAttributeConfig): void {
const {target, name, value, modifier} = cfg;
public changeAttribute(cfg: ChangeAttrConfig) {
const {target, attribute, modifier} = cfg;
const elements = Array.from(this._html.querySelectorAll(target));
if (!elements.length || typeof value === 'undefined') return;
if (!elements.length) return;

if (typeof value === 'string') {
elements.forEach(el => el.setAttribute(name, value));
if ('transform' in cfg) {
UIPStateModel.setAttribute(elements, attribute, cfg.transform);
} else {
elements.forEach(el => value ? el.setAttribute(name, '') : el.removeAttribute(name));
UIPStateModel.setAttribute(elements, attribute, cfg.value);
}
this._lastModifier = modifier;
this.fire();
}

public transformAttribute(cfg: changeAttributeConfig) {
const {target, name, transform, modifier} = cfg;
const elements = Array.from(this._html.querySelectorAll(target));
if (!elements.length || !transform) return;

public static setAttribute(elements: Element[], name: string, transform: TransformSignature | string | boolean) {
elements.forEach(el => {
const transformed = transform(el.getAttribute(name));
transformed === null ? el.removeAttribute(name) : el.setAttribute(name, transformed);
const transformed = typeof transform === 'function' ? transform(el.getAttribute(name)) : transform;
if (typeof transformed === 'string') {
el.setAttribute(name, transformed);
} else {
transformed ? el.setAttribute(name, '') : el.removeAttribute(name);
}
});
this._lastModifier = modifier;
this.fire();
}
}
28 changes: 15 additions & 13 deletions src/settings/setting/bool-setting/bool-setting.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {attr} from '@exadel/esl/modules/esl-base-element/core';

import {UIPSetting} from '../setting';
import {UIPStateModel} from '../../../core/state-model';
import TokenListUtils from '../../../utils/array-utils/token-list-utils';
import {ChangeAttrConfig, UIPStateModel} from '../../../core/state-model';
import TokenListUtils from '../../../utils/token-list/token-list-utils';
import {WARN} from '../../../utils/warn-messages/warn';

export class UIPBoolSetting extends UIPSetting {
Expand Down Expand Up @@ -34,21 +34,23 @@ export class UIPBoolSetting extends UIPSetting {
applyTo(model: UIPStateModel) {
if (this.mode === 'replace') return super.applyTo(model);

const val = this.getDisplayedValue();
const cfg = {
const cfg: ChangeAttrConfig = {
target: this.target,
name: this.attribute,
attribute: this.attribute,
modifier: this.settings,
transform: (attrValue: string | null) => {
if (!attrValue) return val || null;
transform: this.transform.bind(this, this.getDisplayedValue()),
};

const attrTokens = TokenListUtils.remove(TokenListUtils.split(attrValue), this.value);
val && attrTokens.push(this.value);
model.changeAttribute(cfg);
}

return TokenListUtils.join(attrTokens);
},
};
model.transformAttribute(cfg);
transform(value: string | false, attrValue: string | null) {
if (!attrValue) return value || null;

const attrTokens = TokenListUtils.remove(TokenListUtils.split(attrValue), this.value);
value && attrTokens.push(this.value);

return TokenListUtils.join(attrTokens);
}

updateFrom(model: UIPStateModel) {
Expand Down
29 changes: 15 additions & 14 deletions src/settings/setting/select-setting/select-setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {ESLSelect} from '@exadel/esl';
import {generateUId} from '@exadel/esl/modules/esl-utils/misc/uid';

import {UIPSetting} from '../setting';
import {UIPStateModel} from '../../../core/state-model';
import TokenListUtils from '../../../utils/array-utils/token-list-utils';
import {ChangeAttrConfig, UIPStateModel} from '../../../core/state-model';
import TokenListUtils from '../../../utils/token-list/token-list-utils';
import {WARN} from '../../../utils/warn-messages/warn';

export class UIPSelectSetting extends UIPSetting {
Expand Down Expand Up @@ -57,23 +57,24 @@ export class UIPSelectSetting extends UIPSetting {
applyTo(model: UIPStateModel) {
if (this.mode === 'replace') return super.applyTo(model);

const val = this.getDisplayedValue();
const cfg = {
const cfg: ChangeAttrConfig = {
target: this.target,
name: this.attribute,
attribute: this.attribute,
modifier: this.settings,
transform: (attrValue: string | null) => {
if (!attrValue) return val || null;
transform: this.transformValue.bind(this, this.getDisplayedValue())
};

model.changeAttribute(cfg);
}

const attrTokens = this.settingOptions.reduce((tokens, option) =>
TokenListUtils.remove(tokens, option), TokenListUtils.split(attrValue));
val && attrTokens.push(val);
transformValue(value: string, attrValue: string | null ) {
if (!attrValue) return value || null;

return TokenListUtils.join(attrTokens);
}
};
const attrTokens = this.settingOptions.reduce((tokens, option) =>
TokenListUtils.remove(tokens, option), TokenListUtils.split(attrValue));
value && attrTokens.push(value);

model.transformAttribute(cfg);
return TokenListUtils.join(attrTokens);
}

updateFrom(model: UIPStateModel) {
Expand Down
8 changes: 4 additions & 4 deletions src/settings/setting/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {attr, ESLBaseElement} from '@exadel/esl/modules/esl-base-element/core';
import {EventUtils} from '@exadel/esl/modules/esl-utils/dom/events';
import {bind} from '@exadel/esl/modules/esl-utils/decorators/bind';

import {UIPStateModel} from '../../core/state-model';
import {ChangeAttrConfig, UIPStateModel} from '../../core/state-model';
import {UIPSettings} from '../settings';
import {WARN} from '../../utils/warn-messages/warn';

Expand Down Expand Up @@ -51,13 +51,13 @@ export abstract class UIPSetting extends ESLBaseElement {
}

public applyTo(model: UIPStateModel): void {
const cfg = {
const cfg: ChangeAttrConfig = {
target: this.target,
name: this.attribute,
attribute: this.attribute,
value: this.getDisplayedValue(),
modifier: this.settings
};
this.isValid() ? model.setAttribute(cfg) : this.setInconsistency(WARN.invalid);
this.isValid() ? model.changeAttribute(cfg) : this.setInconsistency(WARN.invalid);
}

public updateFrom(model: UIPStateModel): void {
Expand Down
File renamed without changes.

0 comments on commit c192ae2

Please sign in to comment.