* @private
(name: string, newValue: PropertyValue)
| 722 | * @private |
| 723 | */ |
| 724 | _updateAttribute(name: string, newValue: PropertyValue) { |
| 725 | const ctor = this.constructor as typeof UI5Element; |
| 726 | |
| 727 | if (!ctor.getMetadata().hasAttribute(name)) { |
| 728 | return; |
| 729 | } |
| 730 | |
| 731 | const properties = ctor.getMetadata().getProperties(); |
| 732 | const propData = properties[name]; |
| 733 | |
| 734 | // Object and Array properties are not reflected to attributes. The attribute is only |
| 735 | // consumed as a declarative input (parsed via fromAttribute on attributeChangedCallback), |
| 736 | // so the framework must neither write nor remove it - leave any author-set attribute alone. |
| 737 | if (propData.type === Object || propData.type === Array) { |
| 738 | return; |
| 739 | } |
| 740 | |
| 741 | const attrName = camelToKebabCase(name); |
| 742 | const converter = propData.converter || defaultConverter; |
| 743 | |
| 744 | if (DEV_MODE) { |
| 745 | const tag = (this.constructor as typeof UI5Element).getMetadata().getTag(); |
| 746 | if (typeof newValue === "boolean" && propData.type !== Boolean) { |
| 747 | // eslint-disable-next-line |
| 748 | console.error(`[UI5-FWK] boolean value for property [${name}] of component [${tag}] is missing "{ type: Boolean }" in its property decorator. Attribute conversion will treat it as a string. If this is intended, pass the value converted to string, otherwise add the type to the property decorator`); |
| 749 | } |
| 750 | if (typeof newValue === "number" && propData.type !== Number) { |
| 751 | // eslint-disable-next-line |
| 752 | console.error(`[UI5-FWK] numeric value for property [${name}] of component [${tag}] is missing "{ type: Number }" in its property decorator. Attribute conversion will treat it as a string. If this is intended, pass the value converted to string, otherwise add the type to the property decorator`); |
| 753 | } |
| 754 | if (typeof newValue === "string" && propData.type && propData.type !== String) { |
| 755 | // eslint-disable-next-line |
| 756 | console.error(`[UI5-FWK] string value for property [${name}] of component [${tag}] which has a non-string type [${propData.type}] in its property decorator. Attribute conversion will stop and keep the string value in the property.`); |
| 757 | } |
| 758 | } |
| 759 | |
| 760 | const newAttrValue = converter.toAttribute(newValue, propData.type); |
| 761 | this._doNotSyncAttributes.add(attrName); // skip the attributeChangedCallback call for this attribute |
| 762 | if (newAttrValue === null || newAttrValue === undefined) { // null means there must be no attribute for the current value of the property |
| 763 | this.removeAttribute(attrName); // remove the attribute safely (will not trigger synchronization to the property value due to the above line) |
| 764 | } else { |
| 765 | this.setAttribute(attrName, newAttrValue); // setting attributes from properties should not trigger the property setter again |
| 766 | } |
| 767 | this._doNotSyncAttributes.delete(attrName); // enable synchronization again for this attribute |
| 768 | } |
| 769 | |
| 770 | /** |
| 771 | * Returns a singleton event listener for the "change" event of a child in a given slot |
nothing calls this directly
no test coverage detected
searching dependent graphs…