Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(framework): Make _property-change publicly available #2201

Merged
merged 8 commits into from
Sep 16, 2020
Merged
37 changes: 27 additions & 10 deletions packages/base/src/UI5Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,28 @@ class UI5Element extends HTMLElement {
this._domRefReadyPromise._deferredResolve = deferredResolve;

this._monitoredChildProps = new Map();
this._firePropertyChange = false;
this._propertyChangeListeners = new Set();
this._shouldInvalidateParent = false;
}

addEventListener(type, listener, options) {
if (type === "_property-change") {
this._propertyChangeListeners.add(listener);
}
return super.addEventListener(type, listener, options);
}

removeEventListener(type, listener, options) {
if (type === "_property-change") {
this._propertyChangeListeners.delete(listener);
}
return super.removeEventListener(type, listener, options);
}

_hasPropertyChangeListeners() {
return !!this._propertyChangeListeners.size;
}

/**
* Returns a unique ID for this UI5 Element
*
Expand Down Expand Up @@ -394,17 +412,15 @@ class UI5Element extends HTMLElement {
* @private
*/
_attachChildPropertyUpdated(child, listenFor) {
const childMetadata = child.constructor.getMetadata(),
slotName = this.constructor._getSlotName(child), // all slotted children have the same configuration
childProperties = childMetadata.getProperties();
const slotName = this.constructor._getSlotName(child); // all slotted children have the same configuration

let observedProps = [],
notObservedProps = [];

if (Array.isArray(listenFor)) {
observedProps = listenFor;
} else {
observedProps = Array.isArray(listenFor.props) ? listenFor.props : Object.keys(childProperties);
observedProps = Array.isArray(listenFor.include) ? listenFor.include : [];
notObservedProps = Array.isArray(listenFor.exclude) ? listenFor.exclude : [];
}

Expand All @@ -413,15 +429,13 @@ class UI5Element extends HTMLElement {
}

child.addEventListener("_property-change", this._invalidateParentOnPropertyUpdate);
child._firePropertyChange = true;
}

/**
* @private
*/
_detachChildPropertyUpdated(child) {
child.removeEventListener("_property-change", this._invalidateParentOnPropertyUpdate);
child._firePropertyChange = false;
}

/**
Expand All @@ -430,11 +444,11 @@ class UI5Element extends HTMLElement {
_propertyChange(name, value) {
this._updateAttribute(name, value);

if (this._firePropertyChange) {
if (this._hasPropertyChangeListeners()) {
this.dispatchEvent(new CustomEvent("_property-change", {
detail: { name, newValue: value },
composed: false,
bubbles: true,
bubbles: false,
}));
}
}
Expand All @@ -457,7 +471,10 @@ class UI5Element extends HTMLElement {
}
const { observedProps, notObservedProps } = propsMetadata;

if (observedProps.includes(prop.detail.name) && !notObservedProps.includes(prop.detail.name)) {
const allPropertiesAreObserved = observedProps.length === 1 && observedProps[0] === "*";
const shouldObserve = allPropertiesAreObserved || observedProps.includes(prop.detail.name);
const shouldSkip = notObservedProps.includes(prop.detail.name);
if (shouldObserve && !shouldSkip) {
parentNode._invalidate("_parent_", this);
}
}
Expand Down