@vaadin/hilla-lit-form
Version:
Hilla form utils
356 lines • 16.8 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _BinderNode_instances, _BinderNode_ownErrors, _BinderNode_validators, _BinderNode_validityStateValidator, _BinderNode_visited, _BinderNode_getChildBinderNodes, _BinderNode_isArray, _BinderNode_isArrayItem, _BinderNode_isObject, _BinderNode_requestValidationOfDescendants, _BinderNode_requestValidationWithAncestors, _BinderNode_runOwnValidators, _BinderNode_setValueState, _a;
import { _createEmptyItemValue, _key, _parent, _validators, AbstractModel, ArrayModel, getObjectModelOwnAndParentGetters, ObjectModel, } from './Models.js';
import { ValidityStateValidator } from './Validators.js';
import { _validity } from './Validity.js';
export const _updateValidation = Symbol('updateValidation');
export const _update = Symbol('update');
export const _setErrorsWithDescendants = Symbol('setErrorsWithDescendants');
export const _clearValidation = Symbol('clearValidation');
const nodes = new WeakMap();
export function getBinderNode(model) {
let node = nodes.get(model);
if (!node) {
node = new BinderNode(model);
nodes.set(model, node);
}
return node;
}
function getErrorPropertyName(valueError) {
return typeof valueError.property === 'string' ? valueError.property : getBinderNode(valueError.property).name;
}
function updateObjectOrArrayKey(model, value, key, keyValue) {
if (model instanceof ObjectModel) {
return {
...value,
[key]: keyValue,
};
}
if (keyValue === undefined) {
throw new TypeError('Unexpected undefined value');
}
if (model instanceof ArrayModel) {
const array = value.slice();
array[key] = keyValue;
return array;
}
throw new TypeError(`Unknown model type ${model.constructor.name}`);
}
export const CHANGED = new Event('binder-node-changed');
class NotArrayModelError extends Error {
constructor() {
super('The model does not represent array');
}
}
class NotArrayItemModelError extends Error {
constructor() {
super('The model does not represent array item');
}
}
const defaultArrayItemCache = new WeakMap();
export class BinderNode extends EventTarget {
constructor(model) {
super();
_BinderNode_instances.add(this);
Object.defineProperty(this, "model", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, _a, {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
_BinderNode_ownErrors.set(this, void 0);
_BinderNode_validators.set(this, void 0);
_BinderNode_validityStateValidator.set(this, void 0);
_BinderNode_visited.set(this, false);
this.model = model;
nodes.set(model, this);
__classPrivateFieldSet(this, _BinderNode_validityStateValidator, new ValidityStateValidator(), "f");
__classPrivateFieldSet(this, _BinderNode_validators, model[_validators], "f");
if (this.constructor === BinderNode) {
this.initializeValue();
}
}
get binder() {
const binder = this.parent?.binder;
if (!binder) {
throw new TypeError('BinderNode is detached');
}
return binder;
}
get defaultValue() {
const key = this.model[_key];
const parentDefaultValue = this.parent.defaultValue;
if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArrayItem).call(this) && !(key in parentDefaultValue)) {
if (defaultArrayItemCache.has(this.parent)) {
return defaultArrayItemCache.get(this.parent);
}
const value = this.model.constructor.createEmptyValue();
defaultArrayItemCache.set(this.parent, value);
return value;
}
return parentDefaultValue[key];
}
get dirty() {
return this.value !== this.defaultValue;
}
get errors() {
return [...Array.from(__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this), (node) => node.errors).flat(), ...this.ownErrors];
}
get invalid() {
return this.errors.length > 0;
}
get name() {
let { model } = this;
let name = '';
while (model[_parent] instanceof AbstractModel) {
name = `${String(model[_key])}${name ? `.${name}` : ''}`;
model = model[_parent];
}
return name;
}
get ownErrors() {
return __classPrivateFieldGet(this, _BinderNode_ownErrors, "f") ? __classPrivateFieldGet(this, _BinderNode_ownErrors, "f") : [];
}
get parent() {
const modelParent = this.model[_parent];
return modelParent instanceof AbstractModel ? getBinderNode(modelParent) : undefined;
}
get required() {
return __classPrivateFieldGet(this, _BinderNode_validators, "f").some((validator) => validator.impliesRequired);
}
get validators() {
return __classPrivateFieldGet(this, _BinderNode_validators, "f");
}
set validators(validators) {
__classPrivateFieldSet(this, _BinderNode_validators, validators, "f");
this.dispatchEvent(CHANGED);
}
get value() {
if (!this.parent) {
return undefined;
}
this.initializeValue();
const key = this.model[_key];
return this.parent.value[key];
}
set value(value) {
this.initializeValue(true);
const oldValue = this.value;
if (value !== oldValue) {
__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, value, undefined);
this[_updateValidation]().catch(() => { });
}
}
get visited() {
return __classPrivateFieldGet(this, _BinderNode_visited, "f");
}
set visited(v) {
if (__classPrivateFieldGet(this, _BinderNode_visited, "f") !== v) {
__classPrivateFieldSet(this, _BinderNode_visited, v, "f");
this.dispatchEvent(CHANGED);
}
}
addValidator(validator) {
this.validators = [...__classPrivateFieldGet(this, _BinderNode_validators, "f"), validator];
this.dispatchEvent(CHANGED);
}
appendItem(item) {
if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) {
const itemValueOrEmptyValue = item ?? this.model[_createEmptyItemValue]();
const newValue = [...(this.value ?? []), itemValueOrEmptyValue];
const newDefaultValue = [...(this.defaultValue ?? []), itemValueOrEmptyValue];
__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, newValue, newDefaultValue);
}
else {
throw new NotArrayModelError();
}
}
for(model) {
const binderNode = getBinderNode(model);
if (binderNode.binder !== this.binder) {
throw new Error('Unknown binder');
}
return binderNode;
}
prependItem(item) {
if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) {
const itemValueOrEmptyValue = item ?? this.model[_createEmptyItemValue]();
const newValue = [itemValueOrEmptyValue, ...(this.value ?? [])];
const newDefaultValue = [itemValueOrEmptyValue, ...(this.defaultValue ?? [])];
__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, newValue, newDefaultValue);
}
else {
throw new NotArrayModelError();
}
}
removeSelf() {
var _b;
if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArrayItem).call(this)) {
const newValue = (this.parent.value ?? []).filter((_, i) => i !== this.model[_key]);
const newDefaultValue = (this.parent.defaultValue ?? []).filter((_, i) => i !== this.model[_key]);
__classPrivateFieldGet((_b = this.parent), _BinderNode_instances, "m", _BinderNode_setValueState).call(_b, newValue, newDefaultValue);
}
else {
throw new NotArrayItemModelError();
}
}
async validate() {
const errors = await Promise.all([
...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_requestValidationOfDescendants).call(this),
...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_requestValidationWithAncestors).call(this),
]).then((arr) => arr.flat());
this[_setErrorsWithDescendants](errors.length ? errors : undefined);
this[_update]();
return errors;
}
[(_BinderNode_ownErrors = new WeakMap(), _BinderNode_validators = new WeakMap(), _BinderNode_validityStateValidator = new WeakMap(), _BinderNode_visited = new WeakMap(), _BinderNode_instances = new WeakSet(), _a = _validity, _clearValidation)]() {
if (__classPrivateFieldGet(this, _BinderNode_visited, "f")) {
__classPrivateFieldSet(this, _BinderNode_visited, false, "f");
this.dispatchEvent(CHANGED);
}
let needsUpdate = false;
if (__classPrivateFieldGet(this, _BinderNode_ownErrors, "f")) {
__classPrivateFieldSet(this, _BinderNode_ownErrors, undefined, "f");
needsUpdate = true;
this.dispatchEvent(CHANGED);
}
if ([...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)].filter((childBinderNode) => childBinderNode[_clearValidation]()).length > 0) {
needsUpdate = true;
}
return needsUpdate;
}
[_setErrorsWithDescendants](errors) {
const { name } = this;
const ownErrors = errors
? errors.filter((valueError) => getErrorPropertyName(valueError) === name)
: undefined;
const relatedErrors = errors
? errors.filter((valueError) => getErrorPropertyName(valueError).startsWith(name))
: undefined;
__classPrivateFieldSet(this, _BinderNode_ownErrors, ownErrors, "f");
for (const childBinderNode of __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)) {
childBinderNode[_setErrorsWithDescendants](relatedErrors);
}
this.dispatchEvent(CHANGED);
}
[_update](_) {
if (this.parent) {
this.parent[_update]();
}
}
async [_updateValidation]() {
if (this.invalid) {
await this.validate();
}
}
initializeValue(forceInitialize = false) {
if (this.parent &&
(this.parent.value === undefined || this.parent.defaultValue === undefined)) {
this.parent.initializeValue(true);
}
const key = this.model[_key];
let value = this.parent
? this.parent.value[this.model[_key]]
: undefined;
const defaultValue = this.parent
? this.parent.defaultValue[this.model[_key]]
: undefined;
if (value === undefined) {
if (forceInitialize || !this.parent) {
value = this.model.constructor.createEmptyValue();
__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, value, defaultValue === undefined ? value : defaultValue);
}
else if (this.parent.model instanceof ObjectModel &&
!(key in (this.parent.value || {}))) {
__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, undefined, defaultValue === undefined ? value : defaultValue);
}
}
}
}
_BinderNode_getChildBinderNodes = function* _BinderNode_getChildBinderNodes() {
if (this.value === undefined || this.defaultValue === undefined) {
return;
}
if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isObject).call(this)) {
for (const [, getter] of getObjectModelOwnAndParentGetters(this.model)) {
const childModel = getter.call(this.model);
if (childModel[_key] in this.defaultValue) {
yield getBinderNode(childModel);
}
}
}
else if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) {
for (const childBinderNode of this.model) {
yield childBinderNode;
}
}
}, _BinderNode_isArray = function _BinderNode_isArray() {
return this.model instanceof ArrayModel;
}, _BinderNode_isArrayItem = function _BinderNode_isArrayItem() {
return this.model[_parent] instanceof ArrayModel;
}, _BinderNode_isObject = function _BinderNode_isObject() {
return this.model instanceof ObjectModel;
}, _BinderNode_requestValidationOfDescendants = function* _BinderNode_requestValidationOfDescendants() {
for (const node of __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)) {
yield* __classPrivateFieldGet(node, _BinderNode_instances, "m", _BinderNode_runOwnValidators).call(node);
yield* __classPrivateFieldGet(node, _BinderNode_instances, "m", _BinderNode_requestValidationOfDescendants).call(node);
}
}, _BinderNode_requestValidationWithAncestors = function* _BinderNode_requestValidationWithAncestors() {
var _b;
yield* __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_runOwnValidators).call(this);
if (this.parent) {
yield* __classPrivateFieldGet((_b = this.parent), _BinderNode_instances, "m", _BinderNode_requestValidationWithAncestors).call(_b);
}
}, _BinderNode_runOwnValidators = function* _BinderNode_runOwnValidators() {
const hasInvalidState = this[_validity] && !this[_validity].valid;
const hasBadInput = !!this[_validity]?.badInput;
if ((hasInvalidState && !hasBadInput) || !hasInvalidState) {
for (const validator of __classPrivateFieldGet(this, _BinderNode_validators, "f")) {
yield this.binder.requestValidation(this.model, validator);
}
}
if (hasInvalidState) {
yield this.binder.requestValidation(this.model, __classPrivateFieldGet(this, _BinderNode_validityStateValidator, "f"));
}
}, _BinderNode_setValueState = function _BinderNode_setValueState(value, defaultValue) {
const { parent } = this;
if (parent) {
const key = this.model[_key];
const parentValue = updateObjectOrArrayKey(parent.model, parent.value, key, value);
const keepPristine = value === defaultValue && parent.value === parent.defaultValue;
if (keepPristine) {
__classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, parentValue);
}
else if (defaultValue !== undefined) {
const parentDefaultValue = updateObjectOrArrayKey(parent.model, parent.defaultValue, key, defaultValue);
__classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, parentDefaultValue);
}
else {
__classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, undefined);
}
}
else {
const binder = this;
if (defaultValue !== undefined) {
binder.defaultValue = defaultValue;
}
binder.value = value;
}
};
//# sourceMappingURL=BinderNode.js.map