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