121 lines
3.6 KiB
JavaScript
121 lines
3.6 KiB
JavaScript
import { dedupeMixin } from '@lion/core';
|
|
import { formRegistrarManager } from './formRegistrarManager.js';
|
|
import { FormRegisteringMixin } from './FormRegisteringMixin.js';
|
|
|
|
/**
|
|
* This allows an element to become the manager of a register
|
|
*/
|
|
export const FormRegistrarMixin = dedupeMixin(
|
|
superclass =>
|
|
// eslint-disable-next-line no-shadow, no-unused-vars
|
|
class FormRegistrarMixin extends FormRegisteringMixin(superclass) {
|
|
get formElements() {
|
|
return this.__formElements;
|
|
}
|
|
|
|
set formElements(value) {
|
|
this.__formElements = value;
|
|
}
|
|
|
|
get formElementsArray() {
|
|
return this.__formElements;
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this.formElements = [];
|
|
this.__readyForRegistration = false;
|
|
this.__hasBeenRendered = false;
|
|
this.registrationReady = new Promise(resolve => {
|
|
this.__resolveRegistrationReady = resolve;
|
|
});
|
|
|
|
this._onRequestToAddFormElement = this._onRequestToAddFormElement.bind(this);
|
|
this.addEventListener('form-element-register', this._onRequestToAddFormElement);
|
|
}
|
|
|
|
connectedCallback() {
|
|
if (super.connectedCallback) {
|
|
super.connectedCallback();
|
|
}
|
|
formRegistrarManager.add(this);
|
|
if (this.__hasBeenRendered) {
|
|
formRegistrarManager.becomesReady();
|
|
}
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
if (super.disconnectedCallback) {
|
|
super.disconnectedCallback();
|
|
}
|
|
formRegistrarManager.remove(this);
|
|
}
|
|
|
|
isRegisteredFormElement(el) {
|
|
return this.formElementsArray.some(exitingEl => exitingEl === el);
|
|
}
|
|
|
|
firstUpdated(changedProperties) {
|
|
super.firstUpdated(changedProperties);
|
|
this.__resolveRegistrationReady();
|
|
this.__readyForRegistration = true;
|
|
formRegistrarManager.becomesReady();
|
|
this.__hasBeenRendered = true;
|
|
}
|
|
|
|
addFormElement(child, index) {
|
|
// This is a way to let the child element (a lion-fieldset or lion-field) know, about its parent
|
|
// eslint-disable-next-line no-param-reassign
|
|
child.__parentFormGroup = this;
|
|
|
|
if (index > 0) {
|
|
this.formElements.splice(index, 0, child);
|
|
} else {
|
|
this.formElements.push(child);
|
|
}
|
|
}
|
|
|
|
removeFormElement(child) {
|
|
const index = this.formElements.indexOf(child);
|
|
if (index > -1) {
|
|
this.formElements.splice(index, 1);
|
|
}
|
|
}
|
|
|
|
_onRequestToAddFormElement(ev) {
|
|
const child = ev.detail.element;
|
|
if (child === this) {
|
|
// as we fire and listen - don't add ourselves
|
|
return;
|
|
}
|
|
if (this.isRegisteredFormElement(child)) {
|
|
// do not readd already existing elements
|
|
return;
|
|
}
|
|
ev.stopPropagation();
|
|
|
|
// Check for siblings to determine the right order to insert into formElements
|
|
// If there is no next sibling, index is -1
|
|
let indexToInsertAt = -1;
|
|
if (this.formElements && Array.isArray(this.formElements)) {
|
|
indexToInsertAt = this.formElements.indexOf(child.nextElementSibling);
|
|
}
|
|
this.addFormElement(child, indexToInsertAt);
|
|
}
|
|
|
|
_onRequestToRemoveFormElement(ev) {
|
|
const child = ev.detail.element;
|
|
if (child === this) {
|
|
// as we fire and listen - don't add ourselves
|
|
return;
|
|
}
|
|
if (!this.isRegisteredFormElement(child)) {
|
|
// do not readd already existing elements
|
|
return;
|
|
}
|
|
ev.stopPropagation();
|
|
|
|
this.removeFormElement(child);
|
|
}
|
|
},
|
|
);
|