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