@ui5/webcomponents-base 0.0.0-1b568f22b → 0.0.0-1e08ebdef
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/CHANGELOG.md +179 -0
- package/README.md +26 -2
- package/bundle.esm.js +16 -7
- package/dist/AssetRegistry.js +8 -7
- package/dist/Boot.js +43 -0
- package/dist/CSP.js +59 -0
- package/dist/CustomElementsScope.js +108 -0
- package/dist/DOMObserver.js +65 -0
- package/dist/Device.js +66 -776
- package/dist/EventProvider.js +30 -26
- package/dist/FontFace.js +19 -62
- package/dist/InitialConfiguration.js +43 -8
- package/dist/Keys.js +78 -0
- package/dist/ManagedStyles.js +83 -0
- package/dist/MediaRange.js +109 -0
- package/dist/{util/parseProperties.js → PropertiesFileFormat.js} +6 -0
- package/dist/Render.js +175 -0
- package/dist/RenderQueue.js +41 -17
- package/dist/RenderScheduler.js +24 -158
- package/dist/StaticArea.js +1 -39
- package/dist/StaticAreaItem.js +56 -63
- package/dist/SystemCSSVars.js +4 -25
- package/dist/Theming.js +2 -1
- package/dist/UI5Element.js +391 -351
- package/dist/UI5ElementMetadata.js +157 -17
- package/dist/asset-registries/Icons.js +129 -14
- package/dist/asset-registries/Illustrations.js +30 -0
- package/dist/asset-registries/LocaleData.js +99 -65
- package/dist/asset-registries/Themes.js +23 -32
- package/dist/asset-registries/i18n.js +63 -48
- package/dist/assets-meta/IconCollectionsAlias.js +18 -0
- package/dist/config/AnimationMode.js +11 -1
- package/dist/config/Language.js +33 -6
- package/dist/config/Theme.js +14 -0
- package/dist/css/FontFace.css +45 -0
- package/dist/css/OverrideFontFace.css +32 -0
- package/dist/css/SystemCSSVars.css +17 -0
- package/dist/delegate/ItemNavigation.js +239 -170
- package/dist/delegate/ResizeHandler.js +78 -37
- package/dist/delegate/ScrollEnablement.js +49 -20
- package/dist/features/OpenUI5Support.js +42 -7
- package/dist/generated/AssetParameters.js +1 -1
- package/dist/generated/css/FontFace.css.js +5 -0
- package/dist/generated/css/OverrideFontFace.css.js +5 -0
- package/dist/generated/css/SystemCSSVars.css.js +5 -0
- package/dist/getSharedResource.js +30 -0
- package/dist/i18nBundle.js +58 -5
- package/dist/isLegacyBrowser.js +3 -0
- package/dist/locale/applyDirection.js +6 -4
- package/dist/locale/directionChange.js +32 -0
- package/dist/locale/getEffectiveDir.js +28 -0
- package/dist/locale/getLocale.js +12 -2
- package/dist/locale/languageChange.js +1 -1
- package/dist/renderer/LitRenderer.js +26 -7
- package/dist/renderer/directives/style-map.js +72 -0
- package/dist/renderer/executeTemplate.js +17 -0
- package/dist/resources/bundle.esm.js +17 -109
- package/dist/resources/bundle.esm.js.map +1 -1
- package/dist/sap/base/Log.js +241 -0
- package/dist/sap/base/assert.js +8 -0
- package/dist/sap/base/security/URLListValidator.js +148 -0
- package/dist/sap/base/security/encodeCSS.js +14 -0
- package/dist/sap/base/security/encodeXML.js +23 -0
- package/dist/sap/base/security/sanitizeHTML.js +16 -0
- package/dist/sap/base/strings/toHex.js +8 -0
- package/dist/sap/base/util/now.js +7 -0
- package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +3585 -0
- package/dist/test-resources/assets/Themes.js +10 -6
- package/dist/test-resources/elements/Parent.js +6 -2
- package/dist/test-resources/elements/WithStaticArea.js +2 -1
- package/dist/test-resources/pages/AllTestElements.html +3 -3
- package/dist/test-resources/pages/Configuration.html +0 -2
- package/dist/test-resources/pages/ConfigurationScript.html +0 -2
- package/dist/test-resources/pages/assets/messagebundle_de.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_en.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_es.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_fr.properties +1 -0
- package/dist/test-resources/pages/i18n.html +33 -0
- package/dist/test-resources/specs/ConfigurationChange.spec.js +10 -8
- package/dist/test-resources/specs/ConfigurationScript.spec.js +25 -23
- package/dist/test-resources/specs/ConfigurationURL.spec.js +65 -17
- package/dist/test-resources/specs/CustomTheme.spec.js +9 -7
- package/dist/test-resources/specs/EventProvider.spec.js +63 -0
- package/dist/test-resources/specs/StaticArea.spec.js +56 -12
- package/dist/test-resources/specs/Theming.spec.js +12 -10
- package/dist/test-resources/specs/UI5ElementInvalidation.js +54 -70
- package/dist/test-resources/specs/UI5ElementLifecycle.js +19 -14
- package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +25 -51
- package/dist/test-resources/specs/UI5ElementMetadataExt.js +9 -7
- package/dist/test-resources/specs/UI5ElementPropertyValidation.js +7 -5
- package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +37 -35
- package/dist/test-resources/specs/UI5ElementShadowDOM.js +10 -8
- package/dist/test-resources/specs/UI5ElementSlots.js +10 -8
- package/dist/theming/CustomStyle.js +47 -6
- package/dist/theming/ThemeLoaded.js +22 -0
- package/dist/theming/applyTheme.js +13 -15
- package/dist/theming/getConstructableStyle.js +15 -10
- package/dist/theming/getEffectiveLinksHrefs.js +20 -0
- package/dist/theming/getEffectiveStyle.js +23 -8
- package/dist/theming/getStylesString.js +15 -0
- package/dist/theming/getThemeDesignerTheme.js +25 -5
- package/dist/theming/preloadLinks.js +23 -0
- package/dist/types/CSSColor.js +9 -0
- package/dist/types/CalendarType.js +1 -1
- package/dist/types/DataType.js +13 -1
- package/dist/types/Float.js +4 -0
- package/dist/types/Integer.js +4 -0
- package/dist/types/InvisibleMessageMode.js +30 -0
- package/dist/types/ItemNavigationBehavior.js +2 -7
- package/dist/types/PopupState.js +1 -1
- package/dist/types/ValueState.js +1 -1
- package/dist/updateShadowRoot.js +30 -0
- package/dist/util/AriaLabelHelper.js +41 -0
- package/dist/util/Caret.js +45 -0
- package/dist/util/ColorConversion.js +370 -0
- package/dist/util/FocusableElements.js +25 -7
- package/dist/util/HTMLSanitizer.js +7 -0
- package/dist/util/InvisibleMessage.js +58 -0
- package/dist/util/PopupUtils.js +93 -0
- package/dist/util/SlotsHelper.js +43 -0
- package/dist/util/TabbableElements.js +1 -1
- package/dist/util/arraysAreEqual.js +15 -0
- package/dist/util/clamp.js +12 -0
- package/dist/util/createLinkInHead.js +19 -0
- package/dist/util/debounce.js +17 -0
- package/dist/util/escapeRegex.js +10 -0
- package/dist/util/generateHighlightedMarkup.js +42 -0
- package/dist/util/getActiveElement.js +11 -0
- package/dist/util/getClassCopy.js +10 -0
- package/dist/util/getEffectiveContentDensity.js +5 -0
- package/dist/util/getSingletonElementInstance.js +13 -0
- package/dist/util/isElementInView.js +15 -0
- package/dist/util/isNodeHidden.js +1 -5
- package/dist/util/isNodeTabbable.js +4 -4
- package/dist/util/isValidPropertyName.js +9 -3
- package/hash.txt +1 -0
- package/index.js +1 -1
- package/lib/generate-asset-parameters/index.js +0 -1
- package/lib/generate-styles/index.js +18 -0
- package/package-scripts.js +37 -19
- package/package.json +20 -13
- package/src/AssetRegistry.js +8 -7
- package/src/Boot.js +43 -0
- package/src/CSP.js +59 -0
- package/src/CustomElementsScope.js +108 -0
- package/src/DOMObserver.js +65 -0
- package/src/Device.js +66 -776
- package/src/EventProvider.js +30 -26
- package/src/FontFace.js +19 -62
- package/src/InitialConfiguration.js +43 -8
- package/src/Keys.js +78 -0
- package/src/ManagedStyles.js +83 -0
- package/src/MediaRange.js +109 -0
- package/src/{util/parseProperties.js → PropertiesFileFormat.js} +6 -0
- package/src/Render.js +175 -0
- package/src/RenderQueue.js +41 -17
- package/src/RenderScheduler.js +24 -158
- package/src/StaticArea.js +1 -39
- package/src/StaticAreaItem.js +56 -63
- package/src/SystemCSSVars.js +4 -25
- package/src/Theming.js +2 -1
- package/src/UI5Element.js +391 -351
- package/src/UI5ElementMetadata.js +157 -17
- package/src/asset-registries/Icons.js +129 -14
- package/src/asset-registries/Illustrations.js +30 -0
- package/src/asset-registries/LocaleData.js +99 -65
- package/src/asset-registries/Themes.js +23 -32
- package/src/asset-registries/i18n.js +63 -48
- package/src/assets-meta/IconCollectionsAlias.js +18 -0
- package/src/config/AnimationMode.js +11 -1
- package/src/config/Language.js +33 -6
- package/src/config/Theme.js +14 -0
- package/src/css/FontFace.css +45 -0
- package/src/css/OverrideFontFace.css +32 -0
- package/src/css/SystemCSSVars.css +17 -0
- package/src/delegate/ItemNavigation.js +239 -170
- package/src/delegate/ResizeHandler.js +78 -37
- package/src/delegate/ScrollEnablement.js +49 -20
- package/src/features/OpenUI5Support.js +42 -7
- package/src/getSharedResource.js +30 -0
- package/src/i18nBundle.js +58 -5
- package/src/isLegacyBrowser.js +3 -0
- package/src/locale/applyDirection.js +6 -4
- package/src/locale/directionChange.js +32 -0
- package/src/locale/getEffectiveDir.js +28 -0
- package/src/locale/getLocale.js +12 -2
- package/src/locale/languageChange.js +1 -1
- package/src/renderer/LitRenderer.js +26 -7
- package/src/renderer/directives/style-map.js +72 -0
- package/src/renderer/executeTemplate.js +17 -0
- package/src/theming/CustomStyle.js +47 -6
- package/src/theming/ThemeLoaded.js +22 -0
- package/src/theming/applyTheme.js +13 -15
- package/src/theming/getConstructableStyle.js +15 -10
- package/src/theming/getEffectiveLinksHrefs.js +20 -0
- package/src/theming/getEffectiveStyle.js +23 -8
- package/src/theming/getStylesString.js +15 -0
- package/src/theming/getThemeDesignerTheme.js +25 -5
- package/src/theming/preloadLinks.js +23 -0
- package/src/types/CSSColor.js +9 -0
- package/src/types/CalendarType.js +1 -1
- package/src/types/DataType.js +13 -1
- package/src/types/Float.js +4 -0
- package/src/types/Integer.js +4 -0
- package/src/types/InvisibleMessageMode.js +30 -0
- package/src/types/ItemNavigationBehavior.js +2 -7
- package/src/types/PopupState.js +1 -1
- package/src/types/ValueState.js +1 -1
- package/src/updateShadowRoot.js +30 -0
- package/src/util/AriaLabelHelper.js +41 -0
- package/src/util/Caret.js +45 -0
- package/src/util/ColorConversion.js +370 -0
- package/src/util/FocusableElements.js +25 -7
- package/src/util/HTMLSanitizer.js +7 -0
- package/src/util/InvisibleMessage.js +58 -0
- package/src/util/PopupUtils.js +93 -0
- package/src/util/SlotsHelper.js +43 -0
- package/src/util/TabbableElements.js +1 -1
- package/src/util/arraysAreEqual.js +15 -0
- package/src/util/clamp.js +12 -0
- package/src/util/createLinkInHead.js +19 -0
- package/src/util/debounce.js +17 -0
- package/src/util/escapeRegex.js +10 -0
- package/src/util/generateHighlightedMarkup.js +42 -0
- package/src/util/getActiveElement.js +11 -0
- package/src/util/getClassCopy.js +10 -0
- package/src/util/getEffectiveContentDensity.js +5 -0
- package/src/util/getSingletonElementInstance.js +13 -0
- package/src/util/isElementInView.js +15 -0
- package/src/util/isNodeHidden.js +1 -5
- package/src/util/isNodeTabbable.js +4 -4
- package/src/util/isValidPropertyName.js +9 -3
- package/used-modules.txt +10 -0
- package/bundle.es5.js +0 -28
- package/dist/SVGIconRegistry.js +0 -60
- package/dist/boot.js +0 -34
- package/dist/compatibility/DOMObserver.js +0 -62
- package/dist/compatibility/patchNodeValue.js +0 -24
- package/dist/compatibility/whenPolyfillLoaded.js +0 -26
- package/dist/delegate/CustomResize.js +0 -78
- package/dist/delegate/NativeResize.js +0 -44
- package/dist/features/PropertiesFormatSupport.js +0 -8
- package/dist/features/browsersupport/Edge.js +0 -6
- package/dist/features/browsersupport/IE11.js +0 -41
- package/dist/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
- package/dist/renderer/ifDefined.js +0 -21
- package/dist/resources/bundle.es5.js +0 -212
- package/dist/resources/bundle.es5.js.map +0 -1
- package/dist/theming/CSSVarsPonyfill.js +0 -24
- package/dist/theming/adaptCSSForIE.js +0 -90
- package/dist/theming/createComponentStyleTag.js +0 -49
- package/dist/theming/createThemePropertiesStyleTag.js +0 -20
- package/dist/thirdparty/Array.from.js +0 -16
- package/dist/thirdparty/Array.prototype.fill.js +0 -44
- package/dist/thirdparty/Array.prototype.find.js +0 -46
- package/dist/thirdparty/Array.prototype.includes.js +0 -51
- package/dist/thirdparty/Element.prototype.closest.js +0 -11
- package/dist/thirdparty/Element.prototype.matches.js +0 -6
- package/dist/thirdparty/Map.prototype.keys.js +0 -9
- package/dist/thirdparty/Number.isInteger.js +0 -5
- package/dist/thirdparty/Number.isNaN.js +0 -1
- package/dist/thirdparty/Number.parseInt.js +0 -1
- package/dist/thirdparty/Object.assign.js +0 -31
- package/dist/thirdparty/Object.entries.js +0 -11
- package/dist/thirdparty/Symbol.js +0 -2
- package/dist/thirdparty/WeakSet.js +0 -27
- package/dist/thirdparty/es6-string-methods.js +0 -182
- package/dist/thirdparty/events-polyfills.js +0 -89
- package/dist/thirdparty/fetch.js +0 -1
- package/dist/thirdparty/template.js +0 -600
- package/dist/thirdparty/webcomponents-sd-ce-pf.js +0 -318
- package/dist/util/isSlot.js +0 -3
- package/dist/webcomponentsjs/LICENSE.md +0 -19
- package/dist/webcomponentsjs/README.md +0 -229
- package/dist/webcomponentsjs/bundles/webcomponents-ce.js +0 -63
- package/dist/webcomponentsjs/bundles/webcomponents-ce.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js +0 -297
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js +0 -208
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd.js +0 -166
- package/dist/webcomponentsjs/bundles/webcomponents-sd.js.map +0 -1
- package/dist/webcomponentsjs/custom-elements-es5-adapter.js +0 -15
- package/dist/webcomponentsjs/package.json +0 -46
- package/dist/webcomponentsjs/src/entrypoints/custom-elements-es5-adapter-index.js +0 -16
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-bundle-index.js +0 -53
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-ce-index.js +0 -17
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-index.js +0 -19
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-pf-index.js +0 -28
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-index.js +0 -18
- package/dist/webcomponentsjs/webcomponents-bundle.js +0 -298
- package/dist/webcomponentsjs/webcomponents-bundle.js.map +0 -1
- package/dist/webcomponentsjs/webcomponents-loader.js +0 -185
- package/src/SVGIconRegistry.js +0 -60
- package/src/boot.js +0 -34
- package/src/compatibility/DOMObserver.js +0 -62
- package/src/compatibility/patchNodeValue.js +0 -24
- package/src/compatibility/whenPolyfillLoaded.js +0 -26
- package/src/delegate/CustomResize.js +0 -78
- package/src/delegate/NativeResize.js +0 -44
- package/src/features/PropertiesFormatSupport.js +0 -8
- package/src/features/browsersupport/Edge.js +0 -6
- package/src/features/browsersupport/IE11.js +0 -41
- package/src/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
- package/src/renderer/ifDefined.js +0 -21
- package/src/theming/CSSVarsPonyfill.js +0 -24
- package/src/theming/adaptCSSForIE.js +0 -90
- package/src/theming/createComponentStyleTag.js +0 -49
- package/src/theming/createThemePropertiesStyleTag.js +0 -20
- package/src/thirdparty/Array.from.js +0 -16
- package/src/thirdparty/Array.prototype.fill.js +0 -44
- package/src/thirdparty/Array.prototype.find.js +0 -46
- package/src/thirdparty/Array.prototype.includes.js +0 -51
- package/src/thirdparty/Element.prototype.closest.js +0 -11
- package/src/thirdparty/Element.prototype.matches.js +0 -6
- package/src/thirdparty/Map.prototype.keys.js +0 -9
- package/src/thirdparty/Number.isInteger.js +0 -5
- package/src/thirdparty/Number.isNaN.js +0 -1
- package/src/thirdparty/Number.parseInt.js +0 -1
- package/src/thirdparty/Object.assign.js +0 -31
- package/src/thirdparty/Object.entries.js +0 -11
- package/src/thirdparty/Symbol.js +0 -2
- package/src/thirdparty/WeakSet.js +0 -27
- package/src/thirdparty/es6-string-methods.js +0 -182
- package/src/thirdparty/events-polyfills.js +0 -89
- package/src/thirdparty/fetch.js +0 -1
- package/src/thirdparty/template.js +0 -600
- package/src/thirdparty/webcomponents-sd-ce-pf.js +0 -318
- package/src/util/isSlot.js +0 -3
package/src/UI5Element.js
CHANGED
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
import merge from "./thirdparty/merge.js";
|
|
2
|
-
import boot from "./
|
|
2
|
+
import { boot } from "./Boot.js";
|
|
3
3
|
import UI5ElementMetadata from "./UI5ElementMetadata.js";
|
|
4
|
+
import EventProvider from "./EventProvider.js";
|
|
5
|
+
import getSingletonElementInstance from "./util/getSingletonElementInstance.js";
|
|
4
6
|
import StaticAreaItem from "./StaticAreaItem.js";
|
|
5
|
-
import
|
|
7
|
+
import updateShadowRoot from "./updateShadowRoot.js";
|
|
8
|
+
import { renderDeferred, renderImmediately, cancelRender } from "./Render.js";
|
|
6
9
|
import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js";
|
|
7
|
-
import
|
|
10
|
+
import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js";
|
|
8
11
|
import { skipOriginalEvent } from "./config/NoConflict.js";
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import createComponentStyleTag from "./theming/createComponentStyleTag.js";
|
|
12
|
-
import getEffectiveStyle from "./theming/getEffectiveStyle.js";
|
|
13
|
-
import Integer from "./types/Integer.js";
|
|
14
|
-
import Float from "./types/Float.js";
|
|
12
|
+
import getEffectiveDir from "./locale/getEffectiveDir.js";
|
|
13
|
+
import DataType from "./types/DataType.js";
|
|
15
14
|
import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js";
|
|
16
15
|
import isValidPropertyName from "./util/isValidPropertyName.js";
|
|
17
|
-
import
|
|
16
|
+
import isDescendantOf from "./util/isDescendantOf.js";
|
|
17
|
+
import { isSlot, getSlotName, getSlottedElementsList } from "./util/SlotsHelper.js";
|
|
18
|
+
import arraysAreEqual from "./util/arraysAreEqual.js";
|
|
19
|
+
import getClassCopy from "./util/getClassCopy.js";
|
|
18
20
|
import { markAsRtlAware } from "./locale/RTLAwareRegistry.js";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
events: {
|
|
22
|
-
"_property-change": {},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
21
|
+
import preloadLinks from "./theming/preloadLinks.js";
|
|
22
|
+
import "focus-visible";
|
|
25
23
|
|
|
26
24
|
let autoId = 0;
|
|
27
25
|
|
|
28
26
|
const elementTimeouts = new Map();
|
|
27
|
+
const uniqueDependenciesCache = new Map();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Triggers re-rendering of a UI5Element instance due to state change.
|
|
31
|
+
*
|
|
32
|
+
* @param changeInfo An object with information about the change that caused invalidation.
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
function _invalidate(changeInfo) {
|
|
36
|
+
// Invalidation should be suppressed: 1) before the component is rendered for the first time 2) and during the execution of onBeforeRendering
|
|
37
|
+
// This is necessary not only as an optimization, but also to avoid infinite loops on invalidation between children and parents (when invalidateOnChildChange is used)
|
|
38
|
+
if (this._suppressInvalidation) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
// Call the onInvalidation hook
|
|
43
|
+
this.onInvalidation(changeInfo);
|
|
44
|
+
|
|
45
|
+
this._changedState.push(changeInfo);
|
|
46
|
+
renderDeferred(this);
|
|
47
|
+
this._eventProvider.fireEvent("invalidate", { ...changeInfo, target: this });
|
|
48
|
+
}
|
|
32
49
|
|
|
33
50
|
/**
|
|
34
51
|
* Base class for all UI5 Web Components
|
|
@@ -43,56 +60,40 @@ const GLOBAL_DIR_CSS_VAR = "--_ui5_dir";
|
|
|
43
60
|
class UI5Element extends HTMLElement {
|
|
44
61
|
constructor() {
|
|
45
62
|
super();
|
|
46
|
-
this._generateId();
|
|
47
|
-
this._initializeState();
|
|
48
|
-
this._upgradeAllProperties();
|
|
49
|
-
this._initializeContainers();
|
|
50
|
-
this._upToDate = false;
|
|
51
63
|
|
|
64
|
+
this._changedState = []; // Filled on each invalidation, cleared on re-render (used for debugging)
|
|
65
|
+
this._suppressInvalidation = true; // A flag telling whether all invalidations should be ignored. Initialized with "true" because a UI5Element can not be invalidated until it is rendered for the first time
|
|
66
|
+
this._inDOM = false; // A flag telling whether the UI5Element is currently in the DOM tree of the document or not
|
|
67
|
+
this._fullyConnected = false; // A flag telling whether the UI5Element's onEnterDOM hook was called (since it's possible to have the element removed from DOM before that)
|
|
68
|
+
this._childChangeListeners = new Map(); // used to store lazy listeners per slot for the child change event of every child inside that slot
|
|
69
|
+
this._slotChangeListeners = new Map(); // used to store lazy listeners per slot for the slotchange event of all slot children inside that slot
|
|
70
|
+
this._eventProvider = new EventProvider(); // used by parent components for listening to changes to child components
|
|
52
71
|
let deferredResolve;
|
|
53
72
|
this._domRefReadyPromise = new Promise(resolve => {
|
|
54
73
|
deferredResolve = resolve;
|
|
55
74
|
});
|
|
56
75
|
this._domRefReadyPromise._deferredResolve = deferredResolve;
|
|
57
76
|
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
}
|
|
77
|
+
this._initializeState();
|
|
78
|
+
this._upgradeAllProperties();
|
|
61
79
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
_generateId() {
|
|
66
|
-
this._id = `ui5wc_${++autoId}`;
|
|
80
|
+
if (this.constructor._needsShadowDOM()) {
|
|
81
|
+
this.attachShadow({ mode: "open" });
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
/**
|
|
70
|
-
*
|
|
86
|
+
* Returns a unique ID for this UI5 Element
|
|
87
|
+
*
|
|
88
|
+
* @deprecated - This property is not guaranteed in future releases
|
|
89
|
+
* @protected
|
|
71
90
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// Init Shadow Root
|
|
77
|
-
if (needsShadowDOM) {
|
|
78
|
-
this.attachShadow({ mode: "open" });
|
|
79
|
-
|
|
80
|
-
// IE11, Edge
|
|
81
|
-
if (window.ShadyDOM) {
|
|
82
|
-
createComponentStyleTag(this.constructor);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Chrome
|
|
86
|
-
if (document.adoptedStyleSheets) {
|
|
87
|
-
const style = getConstructableStyle(this.constructor);
|
|
88
|
-
this.shadowRoot.adoptedStyleSheets = [style];
|
|
89
|
-
}
|
|
91
|
+
get _id() {
|
|
92
|
+
if (!this.__id) {
|
|
93
|
+
this.__id = `ui5wc_${++autoId}`;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
if (needsStaticArea) {
|
|
94
|
-
this.staticAreaItem = new StaticAreaItem(this);
|
|
95
|
-
}
|
|
96
|
+
return this.__id;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
/**
|
|
@@ -100,27 +101,27 @@ class UI5Element extends HTMLElement {
|
|
|
100
101
|
* @private
|
|
101
102
|
*/
|
|
102
103
|
async connectedCallback() {
|
|
103
|
-
|
|
104
|
+
this.setAttribute(this.constructor.getMetadata().getPureTag(), "");
|
|
105
|
+
|
|
104
106
|
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
if (needsShadowDOM) {
|
|
108
|
-
if (slotsAreManaged) {
|
|
109
|
-
// always register the observer before yielding control to the main thread (await)
|
|
110
|
-
this._startObservingDOMChildren();
|
|
111
|
-
await this._processChildren();
|
|
112
|
-
}
|
|
108
|
+
this._inDOM = true;
|
|
113
109
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
if (slotsAreManaged) {
|
|
111
|
+
// always register the observer before yielding control to the main thread (await)
|
|
112
|
+
this._startObservingDOMChildren();
|
|
113
|
+
await this._processChildren();
|
|
114
|
+
}
|
|
117
115
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
if (!this._inDOM) { // Component removed from DOM while _processChildren was running
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
renderImmediately(this);
|
|
121
|
+
this._domRefReadyPromise._deferredResolve();
|
|
122
|
+
this._fullyConnected = true;
|
|
123
|
+
if (typeof this.onEnterDOM === "function") {
|
|
124
|
+
this.onEnterDOM();
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
|
|
@@ -129,24 +130,26 @@ class UI5Element extends HTMLElement {
|
|
|
129
130
|
* @private
|
|
130
131
|
*/
|
|
131
132
|
disconnectedCallback() {
|
|
132
|
-
const needsShadowDOM = this.constructor._needsShadowDOM();
|
|
133
|
-
const needsStaticArea = this.constructor._needsStaticArea();
|
|
134
133
|
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
this._inDOM = false;
|
|
136
|
+
|
|
137
|
+
if (slotsAreManaged) {
|
|
138
|
+
this._stopObservingDOMChildren();
|
|
139
|
+
}
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
if (this._fullyConnected) {
|
|
142
142
|
if (typeof this.onExitDOM === "function") {
|
|
143
143
|
this.onExitDOM();
|
|
144
144
|
}
|
|
145
|
+
this._fullyConnected = false;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
if (
|
|
148
|
-
this.staticAreaItem.
|
|
148
|
+
if (this.staticAreaItem && this.staticAreaItem.parentElement) {
|
|
149
|
+
this.staticAreaItem.parentElement.removeChild(this.staticAreaItem);
|
|
149
150
|
}
|
|
151
|
+
|
|
152
|
+
cancelRender(this);
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
/**
|
|
@@ -162,16 +165,16 @@ class UI5Element extends HTMLElement {
|
|
|
162
165
|
const mutationObserverOptions = {
|
|
163
166
|
childList: true,
|
|
164
167
|
subtree: canSlotText,
|
|
165
|
-
characterData:
|
|
168
|
+
characterData: canSlotText,
|
|
166
169
|
};
|
|
167
|
-
|
|
170
|
+
observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions);
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
/**
|
|
171
174
|
* @private
|
|
172
175
|
*/
|
|
173
176
|
_stopObservingDOMChildren() {
|
|
174
|
-
|
|
177
|
+
unobserveDOMNode(this);
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
/**
|
|
@@ -193,8 +196,14 @@ class UI5Element extends HTMLElement {
|
|
|
193
196
|
const canSlotText = this.constructor.getMetadata().canSlotText();
|
|
194
197
|
const domChildren = Array.from(canSlotText ? this.childNodes : this.children);
|
|
195
198
|
|
|
196
|
-
//
|
|
199
|
+
const slotsCachedContentMap = new Map(); // Store here the content of each slot before the mutation occurred
|
|
200
|
+
const propertyNameToSlotMap = new Map(); // Used for reverse lookup to determine to which slot the property name corresponds
|
|
201
|
+
|
|
202
|
+
// Init the _state object based on the supported slots and store the previous values
|
|
197
203
|
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
204
|
+
const propertyName = slotData.propertyName || slotName;
|
|
205
|
+
propertyNameToSlotMap.set(propertyName, slotName);
|
|
206
|
+
slotsCachedContentMap.set(propertyName, [...this._state[propertyName]]);
|
|
198
207
|
this._clearSlot(slotName, slotData);
|
|
199
208
|
}
|
|
200
209
|
|
|
@@ -203,7 +212,7 @@ class UI5Element extends HTMLElement {
|
|
|
203
212
|
|
|
204
213
|
const allChildrenUpgraded = domChildren.map(async (child, idx) => {
|
|
205
214
|
// Determine the type of the child (mainly by the slot attribute)
|
|
206
|
-
const slotName =
|
|
215
|
+
const slotName = getSlotName(child);
|
|
207
216
|
const slotData = slotsMap[slotName];
|
|
208
217
|
|
|
209
218
|
// Check if the slotName is supported
|
|
@@ -241,12 +250,14 @@ class UI5Element extends HTMLElement {
|
|
|
241
250
|
|
|
242
251
|
child = this.constructor.getMetadata().constructor.validateSlotValue(child, slotData);
|
|
243
252
|
|
|
244
|
-
if (
|
|
245
|
-
|
|
253
|
+
// Listen for any invalidation on the child if invalidateOnChildChange is true or an object (ignore when false or not set)
|
|
254
|
+
if (child.isUI5Element && slotData.invalidateOnChildChange) {
|
|
255
|
+
child.attachInvalidate(this._getChildChangeListener(slotName));
|
|
246
256
|
}
|
|
247
257
|
|
|
258
|
+
// Listen for the slotchange event if the child is a slot itself
|
|
248
259
|
if (isSlot(child)) {
|
|
249
|
-
this._attachSlotChange(child);
|
|
260
|
+
this._attachSlotChange(child, slotName);
|
|
250
261
|
}
|
|
251
262
|
|
|
252
263
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -262,10 +273,33 @@ class UI5Element extends HTMLElement {
|
|
|
262
273
|
|
|
263
274
|
// Distribute the child in the _state object, keeping the Light DOM order,
|
|
264
275
|
// not the order elements are defined.
|
|
265
|
-
slottedChildrenMap.forEach((children,
|
|
266
|
-
this._state[
|
|
276
|
+
slottedChildrenMap.forEach((children, propertyName) => {
|
|
277
|
+
this._state[propertyName] = children.sort((a, b) => a.idx - b.idx).map(_ => _.child);
|
|
267
278
|
});
|
|
268
|
-
|
|
279
|
+
|
|
280
|
+
// Compare the content of each slot with the cached values and invalidate for the ones that changed
|
|
281
|
+
let invalidated = false;
|
|
282
|
+
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
283
|
+
const propertyName = slotData.propertyName || slotName;
|
|
284
|
+
if (!arraysAreEqual(slotsCachedContentMap.get(propertyName), this._state[propertyName])) {
|
|
285
|
+
_invalidate.call(this, {
|
|
286
|
+
type: "slot",
|
|
287
|
+
name: propertyNameToSlotMap.get(propertyName),
|
|
288
|
+
reason: "children",
|
|
289
|
+
});
|
|
290
|
+
invalidated = true;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// If none of the slots had an invalidation due to changes to immediate children,
|
|
295
|
+
// the change is considered to be text content of the default slot
|
|
296
|
+
if (!invalidated) {
|
|
297
|
+
_invalidate.call(this, {
|
|
298
|
+
type: "slot",
|
|
299
|
+
name: "default",
|
|
300
|
+
reason: "textcontent",
|
|
301
|
+
});
|
|
302
|
+
}
|
|
269
303
|
}
|
|
270
304
|
|
|
271
305
|
/**
|
|
@@ -274,24 +308,61 @@ class UI5Element extends HTMLElement {
|
|
|
274
308
|
*/
|
|
275
309
|
_clearSlot(slotName, slotData) {
|
|
276
310
|
const propertyName = slotData.propertyName || slotName;
|
|
277
|
-
|
|
278
|
-
let children = this._state[propertyName];
|
|
279
|
-
if (!Array.isArray(children)) {
|
|
280
|
-
children = [children];
|
|
281
|
-
}
|
|
311
|
+
const children = this._state[propertyName];
|
|
282
312
|
|
|
283
313
|
children.forEach(child => {
|
|
284
314
|
if (child && child.isUI5Element) {
|
|
285
|
-
this.
|
|
315
|
+
child.detachInvalidate(this._getChildChangeListener(slotName));
|
|
286
316
|
}
|
|
287
317
|
|
|
288
318
|
if (isSlot(child)) {
|
|
289
|
-
this._detachSlotChange(child);
|
|
319
|
+
this._detachSlotChange(child, slotName);
|
|
290
320
|
}
|
|
291
321
|
});
|
|
292
322
|
|
|
293
323
|
this._state[propertyName] = [];
|
|
294
|
-
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Attach a callback that will be executed whenever the component is invalidated
|
|
328
|
+
*
|
|
329
|
+
* @param callback
|
|
330
|
+
* @public
|
|
331
|
+
*/
|
|
332
|
+
attachInvalidate(callback) {
|
|
333
|
+
this._eventProvider.attachEvent("invalidate", callback);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Detach the callback that is executed whenever the component is invalidated
|
|
338
|
+
*
|
|
339
|
+
* @param callback
|
|
340
|
+
* @public
|
|
341
|
+
*/
|
|
342
|
+
detachInvalidate(callback) {
|
|
343
|
+
this._eventProvider.detachEvent("invalidate", callback);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Callback that is executed whenever a monitored child changes its state
|
|
348
|
+
*
|
|
349
|
+
* @param slotName the slot in which a child was invalidated
|
|
350
|
+
* @param childChangeInfo the changeInfo object for the child in the given slot
|
|
351
|
+
* @private
|
|
352
|
+
*/
|
|
353
|
+
_onChildChange(slotName, childChangeInfo) {
|
|
354
|
+
if (!this.constructor.getMetadata().shouldInvalidateOnChildChange(slotName, childChangeInfo.type, childChangeInfo.name)) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// The component should be invalidated as this type of change on the child is listened for
|
|
359
|
+
// However, no matter what changed on the child (property/slot), the invalidation is registered as "type=slot" for the component itself
|
|
360
|
+
_invalidate.call(this, {
|
|
361
|
+
type: "slot",
|
|
362
|
+
name: slotName,
|
|
363
|
+
reason: "childchange",
|
|
364
|
+
child: childChangeInfo.target,
|
|
365
|
+
});
|
|
295
366
|
}
|
|
296
367
|
|
|
297
368
|
/**
|
|
@@ -306,12 +377,8 @@ class UI5Element extends HTMLElement {
|
|
|
306
377
|
const propertyTypeClass = properties[nameInCamelCase].type;
|
|
307
378
|
if (propertyTypeClass === Boolean) {
|
|
308
379
|
newValue = newValue !== null;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
newValue = parseInt(newValue);
|
|
312
|
-
}
|
|
313
|
-
if (propertyTypeClass === Float) {
|
|
314
|
-
newValue = parseFloat(newValue);
|
|
380
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
381
|
+
newValue = propertyTypeClass.attributeToProperty(newValue);
|
|
315
382
|
}
|
|
316
383
|
this[nameInCamelCase] = newValue;
|
|
317
384
|
}
|
|
@@ -324,22 +391,24 @@ class UI5Element extends HTMLElement {
|
|
|
324
391
|
if (!this.constructor.getMetadata().hasAttribute(name)) {
|
|
325
392
|
return;
|
|
326
393
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
|
|
394
|
+
const properties = this.constructor.getMetadata().getProperties();
|
|
395
|
+
const propertyTypeClass = properties[name].type;
|
|
332
396
|
const attrName = camelToKebabCase(name);
|
|
333
397
|
const attrValue = this.getAttribute(attrName);
|
|
334
|
-
|
|
398
|
+
|
|
399
|
+
if (propertyTypeClass === Boolean) {
|
|
335
400
|
if (newValue === true && attrValue === null) {
|
|
336
401
|
this.setAttribute(attrName, "");
|
|
337
402
|
} else if (newValue === false && attrValue !== null) {
|
|
338
403
|
this.removeAttribute(attrName);
|
|
339
404
|
}
|
|
340
|
-
} else if (
|
|
341
|
-
this.setAttribute(attrName, newValue);
|
|
342
|
-
}
|
|
405
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
406
|
+
this.setAttribute(attrName, propertyTypeClass.propertyToAttribute(newValue));
|
|
407
|
+
} else if (typeof newValue !== "object") {
|
|
408
|
+
if (attrValue !== newValue) {
|
|
409
|
+
this.setAttribute(attrName, newValue);
|
|
410
|
+
}
|
|
411
|
+
} // else { return; } // old object handling
|
|
343
412
|
}
|
|
344
413
|
|
|
345
414
|
/**
|
|
@@ -365,120 +434,96 @@ class UI5Element extends HTMLElement {
|
|
|
365
434
|
* @private
|
|
366
435
|
*/
|
|
367
436
|
_initializeState() {
|
|
368
|
-
|
|
369
|
-
this._state = Object.assign({}, defaultState);
|
|
437
|
+
this._state = { ...this.constructor.getMetadata().getInitialState() };
|
|
370
438
|
}
|
|
371
439
|
|
|
372
440
|
/**
|
|
441
|
+
* Returns a singleton event listener for the "change" event of a child in a given slot
|
|
442
|
+
*
|
|
443
|
+
* @param slotName the name of the slot, where the child is
|
|
444
|
+
* @returns {any}
|
|
373
445
|
* @private
|
|
374
446
|
*/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
slotName
|
|
378
|
-
childProperties = childMetadata.getProperties();
|
|
379
|
-
|
|
380
|
-
let observedProps = [],
|
|
381
|
-
notObservedProps = [];
|
|
382
|
-
|
|
383
|
-
if (Array.isArray(listenFor)) {
|
|
384
|
-
observedProps = listenFor;
|
|
385
|
-
} else {
|
|
386
|
-
observedProps = Array.isArray(listenFor.props) ? listenFor.props : Object.keys(childProperties);
|
|
387
|
-
notObservedProps = Array.isArray(listenFor.exclude) ? listenFor.exclude : [];
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (!this._monitoredChildProps.has(slotName)) {
|
|
391
|
-
this._monitoredChildProps.set(slotName, { observedProps, notObservedProps });
|
|
447
|
+
_getChildChangeListener(slotName) {
|
|
448
|
+
if (!this._childChangeListeners.has(slotName)) {
|
|
449
|
+
this._childChangeListeners.set(slotName, this._onChildChange.bind(this, slotName));
|
|
392
450
|
}
|
|
393
|
-
|
|
394
|
-
child.addEventListener("_property-change", this._invalidateParentOnPropertyUpdate);
|
|
395
|
-
child._firePropertyChange = true;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* @private
|
|
400
|
-
*/
|
|
401
|
-
_detachChildPropertyUpdated(child) {
|
|
402
|
-
child.removeEventListener("_property-change", this._invalidateParentOnPropertyUpdate);
|
|
403
|
-
child._firePropertyChange = false;
|
|
451
|
+
return this._childChangeListeners.get(slotName);
|
|
404
452
|
}
|
|
405
453
|
|
|
406
454
|
/**
|
|
455
|
+
* Returns a singleton slotchange event listener that invalidates the component due to changes in the given slot
|
|
456
|
+
*
|
|
457
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
458
|
+
* @returns {any}
|
|
407
459
|
* @private
|
|
408
460
|
*/
|
|
409
|
-
|
|
410
|
-
this.
|
|
411
|
-
|
|
412
|
-
if (this._firePropertyChange) {
|
|
413
|
-
this.dispatchEvent(new CustomEvent("_property-change", {
|
|
414
|
-
detail: { name, newValue: value },
|
|
415
|
-
composed: false,
|
|
416
|
-
bubbles: true,
|
|
417
|
-
}));
|
|
461
|
+
_getSlotChangeListener(slotName) {
|
|
462
|
+
if (!this._slotChangeListeners.has(slotName)) {
|
|
463
|
+
this._slotChangeListeners.set(slotName, this._onSlotChange.bind(this, slotName));
|
|
418
464
|
}
|
|
465
|
+
return this._slotChangeListeners.get(slotName);
|
|
419
466
|
}
|
|
420
467
|
|
|
421
468
|
/**
|
|
422
469
|
* @private
|
|
423
470
|
*/
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
const parentNode = this.parentNode;
|
|
427
|
-
if (!parentNode) {
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
const slotName = parentNode.constructor._getSlotName(this);
|
|
432
|
-
const propsMetadata = parentNode._monitoredChildProps.get(slotName);
|
|
433
|
-
|
|
434
|
-
if (!propsMetadata) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
const { observedProps, notObservedProps } = propsMetadata;
|
|
438
|
-
|
|
439
|
-
if (observedProps.includes(prop.detail.name) && !notObservedProps.includes(prop.detail.name)) {
|
|
440
|
-
parentNode._invalidate("_parent_", this);
|
|
441
|
-
}
|
|
471
|
+
_attachSlotChange(child, slotName) {
|
|
472
|
+
child.addEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
442
473
|
}
|
|
443
474
|
|
|
444
475
|
/**
|
|
445
476
|
* @private
|
|
446
477
|
*/
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
this._invalidateOnSlotChange = () => {
|
|
450
|
-
this._invalidate("slotchange");
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
child.addEventListener("slotchange", this._invalidateOnSlotChange);
|
|
478
|
+
_detachSlotChange(child, slotName) {
|
|
479
|
+
child.removeEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
454
480
|
}
|
|
455
481
|
|
|
456
482
|
/**
|
|
483
|
+
* Whenever a slot element is slotted inside a UI5 Web Component, its slotchange event invalidates the component
|
|
484
|
+
*
|
|
485
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
457
486
|
* @private
|
|
458
487
|
*/
|
|
459
|
-
|
|
460
|
-
|
|
488
|
+
_onSlotChange(slotName) {
|
|
489
|
+
_invalidate.call(this, {
|
|
490
|
+
type: "slot",
|
|
491
|
+
name: slotName,
|
|
492
|
+
reason: "slotchange",
|
|
493
|
+
});
|
|
461
494
|
}
|
|
462
495
|
|
|
463
496
|
/**
|
|
464
|
-
*
|
|
465
|
-
*
|
|
497
|
+
* A callback that is executed each time an already rendered component is invalidated (scheduled for re-rendering)
|
|
498
|
+
*
|
|
499
|
+
* @param changeInfo An object with information about the change that caused invalidation.
|
|
500
|
+
* The object can have the following properties:
|
|
501
|
+
* - type: (property|slot) tells what caused the invalidation
|
|
502
|
+
* 1) property: a property value was changed either directly or as a result of changing the corresponding attribute
|
|
503
|
+
* 2) slot: a slotted node(nodes) changed in one of several ways (see "reason")
|
|
504
|
+
*
|
|
505
|
+
* - name: the name of the property or slot that caused the invalidation
|
|
506
|
+
*
|
|
507
|
+
* - reason: (children|textcontent|childchange|slotchange) relevant only for type="slot" only and tells exactly what changed in the slot
|
|
508
|
+
* 1) children: immediate children (HTML elements or text nodes) were added, removed or reordered in the slot
|
|
509
|
+
* 2) textcontent: text nodes in the slot changed value (or nested text nodes were added or changed value). Can only trigger for slots of "type: Node"
|
|
510
|
+
* 3) slotchange: a slot element, slotted inside that slot had its "slotchange" event listener called. This practically means that transitively slotted children changed.
|
|
511
|
+
* Can only trigger if the child of a slot is a slot element itself.
|
|
512
|
+
* 4) childchange: indicates that a UI5Element child in that slot was invalidated and in turn invalidated the component.
|
|
513
|
+
* Can only trigger for slots with "invalidateOnChildChange" metadata descriptor
|
|
514
|
+
*
|
|
515
|
+
* - newValue: the new value of the property (for type="property" only)
|
|
516
|
+
*
|
|
517
|
+
* - oldValue: the old value of the property (for type="property" only)
|
|
518
|
+
*
|
|
519
|
+
* - child the child that was changed (for type="slot" and reason="childchange" only)
|
|
520
|
+
*
|
|
521
|
+
* @public
|
|
466
522
|
*/
|
|
467
|
-
|
|
468
|
-
if (!this._upToDate) {
|
|
469
|
-
// console.log("already invalidated", this, ...arguments);
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
if (this.getDomRef() && !this._suppressInvalidation) {
|
|
474
|
-
this._upToDate = false;
|
|
475
|
-
// console.log("INVAL", this, ...arguments);
|
|
476
|
-
RenderScheduler.renderDeferred(this);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
523
|
+
onInvalidation(changeInfo) {}
|
|
479
524
|
|
|
480
525
|
/**
|
|
481
|
-
* Do not call this method directly, only intended to be called by
|
|
526
|
+
* Do not call this method directly, only intended to be called by js
|
|
482
527
|
* @protected
|
|
483
528
|
*/
|
|
484
529
|
_render() {
|
|
@@ -497,15 +542,37 @@ class UI5Element extends HTMLElement {
|
|
|
497
542
|
}
|
|
498
543
|
|
|
499
544
|
// resume normal invalidation handling
|
|
500
|
-
|
|
545
|
+
this._suppressInvalidation = false;
|
|
501
546
|
|
|
502
547
|
// Update the shadow root with the render result
|
|
503
|
-
|
|
504
|
-
this.
|
|
505
|
-
|
|
548
|
+
/*
|
|
549
|
+
if (this._changedState.length) {
|
|
550
|
+
let element = this.localName;
|
|
551
|
+
if (this.id) {
|
|
552
|
+
element = `${element}#${this.id}`;
|
|
553
|
+
}
|
|
554
|
+
console.log("Re-rendering:", element, this._changedState.map(x => { // eslint-disable-line
|
|
555
|
+
let res = `${x.type}`;
|
|
556
|
+
if (x.reason) {
|
|
557
|
+
res = `${res}(${x.reason})`;
|
|
558
|
+
}
|
|
559
|
+
res = `${res}: ${x.name}`;
|
|
560
|
+
if (x.type === "property") {
|
|
561
|
+
res = `${res} ${x.oldValue} => ${x.newValue}`;
|
|
562
|
+
}
|
|
506
563
|
|
|
507
|
-
|
|
508
|
-
|
|
564
|
+
return res;
|
|
565
|
+
}));
|
|
566
|
+
}
|
|
567
|
+
*/
|
|
568
|
+
this._changedState = [];
|
|
569
|
+
|
|
570
|
+
// Update shadow root and static area item
|
|
571
|
+
if (this.constructor._needsShadowDOM()) {
|
|
572
|
+
updateShadowRoot(this);
|
|
573
|
+
}
|
|
574
|
+
if (this.staticAreaItem) {
|
|
575
|
+
this.staticAreaItem.update();
|
|
509
576
|
}
|
|
510
577
|
|
|
511
578
|
// Safari requires that children get the slot attribute only after the slot tags have been rendered in the shadow DOM
|
|
@@ -519,23 +586,6 @@ class UI5Element extends HTMLElement {
|
|
|
519
586
|
}
|
|
520
587
|
}
|
|
521
588
|
|
|
522
|
-
/**
|
|
523
|
-
* @private
|
|
524
|
-
*/
|
|
525
|
-
_updateShadowRoot() {
|
|
526
|
-
if (!this.constructor._needsShadowDOM()) {
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
let styleToPrepend;
|
|
531
|
-
const renderResult = this.constructor.template(this);
|
|
532
|
-
|
|
533
|
-
if (!document.adoptedStyleSheets && !window.ShadyDOM) {
|
|
534
|
-
styleToPrepend = getEffectiveStyle(this.constructor);
|
|
535
|
-
}
|
|
536
|
-
this.constructor.render(renderResult, this.shadowRoot, styleToPrepend, { eventContext: this });
|
|
537
|
-
}
|
|
538
|
-
|
|
539
589
|
/**
|
|
540
590
|
* @private
|
|
541
591
|
*/
|
|
@@ -558,16 +608,27 @@ class UI5Element extends HTMLElement {
|
|
|
558
608
|
|
|
559
609
|
/**
|
|
560
610
|
* Returns the DOM Element inside the Shadow Root that corresponds to the opening tag in the UI5 Web Component's template
|
|
611
|
+
* *Note:* For logical (abstract) elements (items, options, etc...), returns the part of the parent's DOM that represents this option
|
|
561
612
|
* Use this method instead of "this.shadowRoot" to read the Shadow DOM, if ever necessary
|
|
613
|
+
*
|
|
562
614
|
* @public
|
|
563
615
|
*/
|
|
564
616
|
getDomRef() {
|
|
617
|
+
// If a component set _getRealDomRef to its children, use the return value of this function
|
|
618
|
+
if (typeof this._getRealDomRef === "function") {
|
|
619
|
+
return this._getRealDomRef();
|
|
620
|
+
}
|
|
621
|
+
|
|
565
622
|
if (!this.shadowRoot || this.shadowRoot.children.length === 0) {
|
|
566
623
|
return;
|
|
567
624
|
}
|
|
568
625
|
|
|
569
|
-
|
|
570
|
-
|
|
626
|
+
const children = [...this.shadowRoot.children].filter(child => !["link", "style"].includes(child.localName));
|
|
627
|
+
if (children.length !== 1) {
|
|
628
|
+
console.warn(`The shadow DOM for ${this.constructor.getMetadata().getTag()} does not have a top level element, the getDomRef() method might not work as expected`); // eslint-disable-line
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return children[0];
|
|
571
632
|
}
|
|
572
633
|
|
|
573
634
|
/**
|
|
@@ -583,6 +644,16 @@ class UI5Element extends HTMLElement {
|
|
|
583
644
|
}
|
|
584
645
|
}
|
|
585
646
|
|
|
647
|
+
/**
|
|
648
|
+
* Waits for dom ref and then returns the DOM Element marked with "data-sap-focus-ref" inside the template.
|
|
649
|
+
* This is the element that will receive the focus by default.
|
|
650
|
+
* @public
|
|
651
|
+
*/
|
|
652
|
+
async getFocusDomRefAsync() {
|
|
653
|
+
await this._waitForDomRef();
|
|
654
|
+
return this.getFocusDomRef();
|
|
655
|
+
}
|
|
656
|
+
|
|
586
657
|
/**
|
|
587
658
|
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref")
|
|
588
659
|
* @public
|
|
@@ -603,10 +674,11 @@ class UI5Element extends HTMLElement {
|
|
|
603
674
|
* @param name - name of the event
|
|
604
675
|
* @param data - additional data for the event
|
|
605
676
|
* @param cancelable - true, if the user can call preventDefault on the event object
|
|
677
|
+
* @param bubbles - true, if the event bubbles
|
|
606
678
|
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise
|
|
607
679
|
*/
|
|
608
|
-
fireEvent(name, data, cancelable) {
|
|
609
|
-
const eventResult = this._fireEvent(name, data, cancelable);
|
|
680
|
+
fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
681
|
+
const eventResult = this._fireEvent(name, data, cancelable, bubbles);
|
|
610
682
|
const camelCaseEventName = kebabToCamelCase(name);
|
|
611
683
|
|
|
612
684
|
if (camelCaseEventName !== name) {
|
|
@@ -616,35 +688,33 @@ class UI5Element extends HTMLElement {
|
|
|
616
688
|
return eventResult;
|
|
617
689
|
}
|
|
618
690
|
|
|
619
|
-
_fireEvent(name, data, cancelable) {
|
|
620
|
-
let compatEventResult = true; // Initialized to true, because if the event is not fired at all, it should be considered "not-prevented"
|
|
621
|
-
|
|
691
|
+
_fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
622
692
|
const noConflictEvent = new CustomEvent(`ui5-${name}`, {
|
|
623
693
|
detail: data,
|
|
624
694
|
composed: false,
|
|
625
|
-
bubbles
|
|
695
|
+
bubbles,
|
|
626
696
|
cancelable,
|
|
627
697
|
});
|
|
628
698
|
|
|
629
|
-
// This will be false if the
|
|
630
|
-
|
|
699
|
+
// This will be false if the no-conflict event is prevented
|
|
700
|
+
const noConflictEventResult = this.dispatchEvent(noConflictEvent);
|
|
631
701
|
|
|
632
702
|
if (skipOriginalEvent(name)) {
|
|
633
|
-
return
|
|
703
|
+
return noConflictEventResult;
|
|
634
704
|
}
|
|
635
705
|
|
|
636
|
-
const
|
|
706
|
+
const normalEvent = new CustomEvent(name, {
|
|
637
707
|
detail: data,
|
|
638
708
|
composed: false,
|
|
639
|
-
bubbles
|
|
709
|
+
bubbles,
|
|
640
710
|
cancelable,
|
|
641
711
|
});
|
|
642
712
|
|
|
643
713
|
// This will be false if the normal event is prevented
|
|
644
|
-
const normalEventResult = this.dispatchEvent(
|
|
714
|
+
const normalEventResult = this.dispatchEvent(normalEvent);
|
|
645
715
|
|
|
646
716
|
// Return false if any of the two events was prevented (its result was false).
|
|
647
|
-
return normalEventResult &&
|
|
717
|
+
return normalEventResult && noConflictEventResult;
|
|
648
718
|
}
|
|
649
719
|
|
|
650
720
|
/**
|
|
@@ -653,18 +723,7 @@ class UI5Element extends HTMLElement {
|
|
|
653
723
|
* @public
|
|
654
724
|
*/
|
|
655
725
|
getSlottedNodes(slotName) {
|
|
656
|
-
|
|
657
|
-
if (!isSlot(curr)) {
|
|
658
|
-
return acc.concat([curr]);
|
|
659
|
-
}
|
|
660
|
-
return acc.concat(curr.assignedNodes({ flatten: true }).filter(item => item instanceof HTMLElement));
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
return this[slotName].reduce(reducer, []);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
get isCompact() {
|
|
667
|
-
return getComputedStyle(this).getPropertyValue(GLOBAL_CONTENT_DENSITY_CSS_VAR) === "compact";
|
|
726
|
+
return getSlottedElementsList(this[slotName]);
|
|
668
727
|
}
|
|
669
728
|
|
|
670
729
|
/**
|
|
@@ -676,33 +735,7 @@ class UI5Element extends HTMLElement {
|
|
|
676
735
|
*/
|
|
677
736
|
get effectiveDir() {
|
|
678
737
|
markAsRtlAware(this.constructor); // if a UI5 Element calls this method, it's considered to be rtl-aware
|
|
679
|
-
|
|
680
|
-
const doc = window.document;
|
|
681
|
-
const dirValues = ["ltr", "rtl"]; // exclude "auto" and "" from all calculations
|
|
682
|
-
const locallyAppliedDir = getComputedStyle(this).getPropertyValue(GLOBAL_DIR_CSS_VAR);
|
|
683
|
-
|
|
684
|
-
// In that order, inspect the CSS Var (for modern browsers), the element itself, html and body (for IE fallback)
|
|
685
|
-
if (dirValues.includes(locallyAppliedDir)) {
|
|
686
|
-
return locallyAppliedDir;
|
|
687
|
-
}
|
|
688
|
-
if (dirValues.includes(this.dir)) {
|
|
689
|
-
return this.dir;
|
|
690
|
-
}
|
|
691
|
-
if (dirValues.includes(doc.documentElement.dir)) {
|
|
692
|
-
return doc.documentElement.dir;
|
|
693
|
-
}
|
|
694
|
-
if (dirValues.includes(doc.body.dir)) {
|
|
695
|
-
return doc.body.dir;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// Finally, check the configuration for explicitly set RTL or language-implied RTL
|
|
699
|
-
return getRTL() ? "rtl" : undefined;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
updateStaticAreaItemContentDensity() {
|
|
703
|
-
if (this.staticAreaItem) {
|
|
704
|
-
this.staticAreaItem._updateContentDensity(this.isCompact);
|
|
705
|
-
}
|
|
738
|
+
return getEffectiveDir(this);
|
|
706
739
|
}
|
|
707
740
|
|
|
708
741
|
/**
|
|
@@ -722,26 +755,6 @@ class UI5Element extends HTMLElement {
|
|
|
722
755
|
return this.getMetadata().getAttributesList();
|
|
723
756
|
}
|
|
724
757
|
|
|
725
|
-
/**
|
|
726
|
-
* @private
|
|
727
|
-
*/
|
|
728
|
-
static _getSlotName(child) {
|
|
729
|
-
// Text nodes can only go to the default slot
|
|
730
|
-
if (!(child instanceof HTMLElement)) {
|
|
731
|
-
return "default";
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// Discover the slot based on the real slot name (f.e. footer => footer, or content-32 => content)
|
|
735
|
-
const slot = child.getAttribute("slot");
|
|
736
|
-
if (slot) {
|
|
737
|
-
const match = slot.match(/^(.+?)-\d+$/);
|
|
738
|
-
return match ? match[1] : slot;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// Use default slot as a fallback
|
|
742
|
-
return "default";
|
|
743
|
-
}
|
|
744
|
-
|
|
745
758
|
/**
|
|
746
759
|
* @private
|
|
747
760
|
*/
|
|
@@ -749,70 +762,30 @@ class UI5Element extends HTMLElement {
|
|
|
749
762
|
return !!this.template;
|
|
750
763
|
}
|
|
751
764
|
|
|
752
|
-
_shouldUpdateFragment() {
|
|
753
|
-
return this.constructor._needsStaticArea() && this.staticAreaItem.isRendered();
|
|
754
|
-
}
|
|
755
|
-
|
|
756
765
|
/**
|
|
757
766
|
* @private
|
|
758
767
|
*/
|
|
759
768
|
static _needsStaticArea() {
|
|
760
|
-
return
|
|
769
|
+
return !!this.staticAreaTemplate;
|
|
761
770
|
}
|
|
762
771
|
|
|
763
772
|
/**
|
|
764
773
|
* @public
|
|
765
774
|
*/
|
|
766
775
|
getStaticAreaItemDomRef() {
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* @private
|
|
772
|
-
*/
|
|
773
|
-
static _getDefaultState() {
|
|
774
|
-
if (this._defaultState) {
|
|
775
|
-
return this._defaultState;
|
|
776
|
+
if (!this.constructor._needsStaticArea()) {
|
|
777
|
+
throw new Error("This component does not use the static area");
|
|
776
778
|
}
|
|
777
779
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
// Initialize properties
|
|
783
|
-
const props = MetadataClass.getProperties();
|
|
784
|
-
for (const propName in props) { // eslint-disable-line
|
|
785
|
-
const propType = props[propName].type;
|
|
786
|
-
const propDefaultValue = props[propName].defaultValue;
|
|
787
|
-
|
|
788
|
-
if (propType === Boolean) {
|
|
789
|
-
defaultState[propName] = false;
|
|
790
|
-
|
|
791
|
-
if (propDefaultValue !== undefined) {
|
|
792
|
-
console.warn("The 'defaultValue' metadata key is ignored for all booleans properties, they would be initialized with 'false' by default"); // eslint-disable-line
|
|
793
|
-
}
|
|
794
|
-
} else if (props[propName].multiple) {
|
|
795
|
-
defaultState[propName] = [];
|
|
796
|
-
} else if (propType === Object) {
|
|
797
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : {};
|
|
798
|
-
} else if (propType === String) {
|
|
799
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : "";
|
|
800
|
-
} else {
|
|
801
|
-
defaultState[propName] = propDefaultValue;
|
|
802
|
-
}
|
|
780
|
+
if (!this.staticAreaItem) {
|
|
781
|
+
this.staticAreaItem = StaticAreaItem.createInstance();
|
|
782
|
+
this.staticAreaItem.setOwnerElement(this);
|
|
803
783
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (slotsAreManaged) {
|
|
807
|
-
const slots = MetadataClass.getSlots();
|
|
808
|
-
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
809
|
-
const propertyName = slotData.propertyName || slotName;
|
|
810
|
-
defaultState[propertyName] = [];
|
|
811
|
-
}
|
|
784
|
+
if (!this.staticAreaItem.parentElement) {
|
|
785
|
+
getSingletonElementInstance("ui5-static-area").appendChild(this.staticAreaItem);
|
|
812
786
|
}
|
|
813
787
|
|
|
814
|
-
this.
|
|
815
|
-
return defaultState;
|
|
788
|
+
return this.staticAreaItem.getDomRef();
|
|
816
789
|
}
|
|
817
790
|
|
|
818
791
|
/**
|
|
@@ -826,7 +799,7 @@ class UI5Element extends HTMLElement {
|
|
|
826
799
|
const properties = this.getMetadata().getProperties();
|
|
827
800
|
for (const [prop, propData] of Object.entries(properties)) { // eslint-disable-line
|
|
828
801
|
if (!isValidPropertyName(prop)) {
|
|
829
|
-
|
|
802
|
+
console.warn(`"${prop}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
830
803
|
}
|
|
831
804
|
|
|
832
805
|
if (propData.type === Boolean && propData.defaultValue) {
|
|
@@ -864,14 +837,27 @@ class UI5Element extends HTMLElement {
|
|
|
864
837
|
}
|
|
865
838
|
},
|
|
866
839
|
set(value) {
|
|
840
|
+
let isDifferent;
|
|
867
841
|
value = this.constructor.getMetadata().constructor.validatePropertyValue(value, propData);
|
|
868
842
|
|
|
869
843
|
const oldState = this._state[prop];
|
|
844
|
+
if (propData.multiple && propData.compareValues) {
|
|
845
|
+
isDifferent = !arraysAreEqual(oldState, value);
|
|
846
|
+
} else if (isDescendantOf(propData.type, DataType)) {
|
|
847
|
+
isDifferent = !propData.type.valuesAreEqual(oldState, value);
|
|
848
|
+
} else {
|
|
849
|
+
isDifferent = oldState !== value;
|
|
850
|
+
}
|
|
870
851
|
|
|
871
|
-
if (
|
|
852
|
+
if (isDifferent) {
|
|
872
853
|
this._state[prop] = value;
|
|
873
|
-
|
|
874
|
-
|
|
854
|
+
_invalidate.call(this, {
|
|
855
|
+
type: "property",
|
|
856
|
+
name: prop,
|
|
857
|
+
newValue: value,
|
|
858
|
+
oldValue: oldState,
|
|
859
|
+
});
|
|
860
|
+
this._updateAttribute(prop, value);
|
|
875
861
|
}
|
|
876
862
|
},
|
|
877
863
|
});
|
|
@@ -882,7 +868,7 @@ class UI5Element extends HTMLElement {
|
|
|
882
868
|
const slots = this.getMetadata().getSlots();
|
|
883
869
|
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
884
870
|
if (!isValidPropertyName(slotName)) {
|
|
885
|
-
|
|
871
|
+
console.warn(`"${slotName}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
886
872
|
}
|
|
887
873
|
|
|
888
874
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -894,7 +880,7 @@ class UI5Element extends HTMLElement {
|
|
|
894
880
|
return [];
|
|
895
881
|
},
|
|
896
882
|
set() {
|
|
897
|
-
throw new Error("Cannot set
|
|
883
|
+
throw new Error("Cannot set slot content directly, use the DOM APIs (appendChild, removeChild, etc...)");
|
|
898
884
|
},
|
|
899
885
|
});
|
|
900
886
|
}
|
|
@@ -906,7 +892,7 @@ class UI5Element extends HTMLElement {
|
|
|
906
892
|
* @protected
|
|
907
893
|
*/
|
|
908
894
|
static get metadata() {
|
|
909
|
-
return
|
|
895
|
+
return {};
|
|
910
896
|
}
|
|
911
897
|
|
|
912
898
|
/**
|
|
@@ -925,6 +911,50 @@ class UI5Element extends HTMLElement {
|
|
|
925
911
|
return "";
|
|
926
912
|
}
|
|
927
913
|
|
|
914
|
+
/**
|
|
915
|
+
* Returns an array with the dependencies for this UI5 Web Component, which could be:
|
|
916
|
+
* - composed components (used in its shadow root or static area item)
|
|
917
|
+
* - slotted components that the component may need to communicate with
|
|
918
|
+
*
|
|
919
|
+
* @protected
|
|
920
|
+
*/
|
|
921
|
+
static get dependencies() {
|
|
922
|
+
return [];
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Returns a list of the unique dependencies for this UI5 Web Component
|
|
927
|
+
*
|
|
928
|
+
* @public
|
|
929
|
+
*/
|
|
930
|
+
static getUniqueDependencies() {
|
|
931
|
+
if (!uniqueDependenciesCache.has(this)) {
|
|
932
|
+
const filtered = this.dependencies.filter((dep, index, deps) => deps.indexOf(dep) === index);
|
|
933
|
+
uniqueDependenciesCache.set(this, filtered);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
return uniqueDependenciesCache.get(this);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Returns a promise that resolves whenever all dependencies for this UI5 Web Component have resolved
|
|
941
|
+
*
|
|
942
|
+
* @returns {Promise<any[]>}
|
|
943
|
+
*/
|
|
944
|
+
static whenDependenciesDefined() {
|
|
945
|
+
return Promise.all(this.getUniqueDependencies().map(dep => dep.define()));
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Hook that will be called upon custom element definition
|
|
950
|
+
*
|
|
951
|
+
* @protected
|
|
952
|
+
* @returns {Promise<void>}
|
|
953
|
+
*/
|
|
954
|
+
static async onDefine() {
|
|
955
|
+
return Promise.resolve();
|
|
956
|
+
}
|
|
957
|
+
|
|
928
958
|
/**
|
|
929
959
|
* Registers a UI5 Web Component in the browser window object
|
|
930
960
|
* @public
|
|
@@ -933,11 +963,13 @@ class UI5Element extends HTMLElement {
|
|
|
933
963
|
static async define() {
|
|
934
964
|
await boot();
|
|
935
965
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
966
|
+
await Promise.all([
|
|
967
|
+
this.whenDependenciesDefined(),
|
|
968
|
+
this.onDefine(),
|
|
969
|
+
]);
|
|
939
970
|
|
|
940
971
|
const tag = this.getMetadata().getTag();
|
|
972
|
+
const altTag = this.getMetadata().getAltTag();
|
|
941
973
|
|
|
942
974
|
const definedLocally = isTagRegistered(tag);
|
|
943
975
|
const definedGlobally = customElements.get(tag);
|
|
@@ -948,6 +980,14 @@ class UI5Element extends HTMLElement {
|
|
|
948
980
|
this._generateAccessors();
|
|
949
981
|
registerTag(tag);
|
|
950
982
|
window.customElements.define(tag, this);
|
|
983
|
+
preloadLinks(this);
|
|
984
|
+
|
|
985
|
+
if (altTag && !customElements.get(altTag)) {
|
|
986
|
+
registerTag(altTag);
|
|
987
|
+
window.customElements.define(altTag, getClassCopy(this, () => {
|
|
988
|
+
console.log(`The ${altTag} tag is deprecated and will be removed in the next release, please use ${tag} instead.`); // eslint-disable-line
|
|
989
|
+
}));
|
|
990
|
+
}
|
|
951
991
|
}
|
|
952
992
|
return this;
|
|
953
993
|
}
|