UNPKG

@jinntec/fore

Version:

Fore - declarative user interfaces in plain HTML

90 lines (80 loc) 2.6 kB
// import { FxAction } from './fx-action.js'; import '../fx-model.js'; import { AbstractAction } from './abstract-action.js'; import { evaluateXPathToFirstNode } from '../xpath-evaluation.js'; import { FxBind } from '../fx-bind.js'; /** * `fx-replace` - replaces the node referred to with 'ref' with node referred to with 'with' attribute. * * @customElement */ export default class FxReplace extends AbstractAction { static get properties() { return { ...super.properties, with: { type: String, }, replaceNode: Object, }; } constructor() { super(); this.with = ''; } connectedCallback() { if (super.connectedCallback) { super.connectedCallback(); } this.with = this.getAttribute('with'); } async perform() { super.perform(); // console.log('replace action variables', this.inScopeVariables); // if (!this.nodeset) { // return; // } const target = evaluateXPathToFirstNode(this.with, this.nodeset, this); if (!target) return; this.replace(this.nodeset, target); } actionPerformed() { this.getModel().updateModel(); this.getOwnerForm().refresh(true); //todo: optimize and update only the affected subtree this.dispatchActionPerformed(); } replace(toReplace, replaceWith) { if (!toReplace || !replaceWith) return; // bail out silently if (!toReplace.nodeName || !replaceWith.nodeName) { console.warn('fx-replace: one argument is not a node'); return; } if (toReplace.nodeType === Node.ATTRIBUTE_NODE) { const { ownerElement } = toReplace; ownerElement.setAttribute(replaceWith.nodeName, replaceWith.textContent); ownerElement.removeAttribute(toReplace.nodeName); } else if (toReplace.nodeType === Node.ELEMENT_NODE) { const cloned = replaceWith.cloneNode(true); toReplace.replaceWith(cloned); } // todo: add selective update and create and notify modelItem for toReplace and replaceWith /* let replaceWithModelItem = this.getModel().getModelItem(replaceWith); if (!replaceWithModelItem) { const replaceWithModelItem = FxBind.createModelItem( this.getAttribute('with'), replaceWith, this, null, ); this.getModel().registerModelItem(replaceWithModelItem); this.getOwnerForm().addToBatchedNotifications(replaceWithModelItem); } */ // this.getModel().changed.push(modelitem); this.needsUpdate = true; } } if (!customElements.get('fx-replace')) { window.customElements.define('fx-replace', FxReplace); }