@ui5/webcomponents-base 0.0.0-c6d8872f3 → 0.0.0-cf069fb29
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 +5 -0
- package/CHANGELOG.md +293 -0
- package/README.md +26 -2
- package/bundle.esm.js +17 -7
- package/dist/AssetRegistry.js +8 -6
- package/dist/Boot.js +61 -0
- package/dist/CSP.js +59 -0
- package/dist/CustomElementsRegistry.js +95 -0
- 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 +45 -9
- package/dist/Keys.js +112 -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 -145
- package/dist/Runtimes.js +107 -0
- package/dist/StaticArea.js +1 -39
- package/dist/StaticAreaItem.js +61 -50
- package/dist/SystemCSSVars.js +10 -0
- package/dist/Theming.js +2 -5
- package/dist/UI5Element.js +448 -297
- package/dist/UI5ElementMetadata.js +173 -19
- package/dist/asset-registries/Icons.js +129 -14
- package/dist/asset-registries/Illustrations.js +30 -0
- package/dist/asset-registries/LocaleData.js +100 -68
- package/dist/asset-registries/Themes.js +35 -32
- package/dist/asset-registries/i18n.js +76 -29
- 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 +101 -19
- package/dist/features/F6Navigation.js +106 -0
- package/dist/features/OpenUI5Support.js +56 -7
- package/dist/generated/AssetParameters.js +13 -0
- 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 +59 -8
- 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/locale/nextFallbackLocale.js +6 -4
- package/dist/locale/normalizeLocale.js +7 -1
- package/dist/renderer/LitRenderer.js +26 -7
- package/dist/renderer/directives/style-map.js +72 -0
- package/dist/renderer/executeTemplate.js +17 -0
- package/dist/resources/bundle.esm.js +20 -106
- 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 +77 -0
- package/dist/test-resources/pages/AllTestElements.html +5 -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 +78 -0
- 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 +69 -9
- 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 +87 -0
- 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 +58 -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/detectNavigatorLanguage.js +3 -1
- package/dist/util/escapeRegex.js +10 -0
- package/dist/util/findNodeOwner.js +35 -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/getFileExtension.js +21 -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 +11 -2
- package/dist/util/setToArray.js +10 -0
- package/hash.txt +1 -0
- package/index.js +1 -1
- package/lib/generate-asset-parameters/index.js +21 -0
- package/lib/generate-styles/index.js +18 -0
- package/lib/generate-version-info/index.js +27 -0
- package/package-scripts.js +43 -17
- package/package.json +19 -12
- package/src/AssetRegistry.js +8 -6
- package/src/Boot.js +61 -0
- package/src/CSP.js +59 -0
- package/src/CustomElementsRegistry.js +95 -0
- 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 +45 -9
- package/src/Keys.js +112 -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 -145
- package/src/Runtimes.js +107 -0
- package/src/StaticArea.js +1 -39
- package/src/StaticAreaItem.js +61 -50
- package/src/SystemCSSVars.js +10 -0
- package/src/Theming.js +2 -5
- package/src/UI5Element.js +448 -297
- package/src/UI5ElementMetadata.js +173 -19
- package/src/asset-registries/Icons.js +129 -14
- package/src/asset-registries/Illustrations.js +30 -0
- package/src/asset-registries/LocaleData.js +100 -68
- package/src/asset-registries/Themes.js +35 -32
- package/src/asset-registries/i18n.js +76 -29
- 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 +101 -19
- package/src/features/F6Navigation.js +106 -0
- package/src/features/OpenUI5Support.js +56 -7
- package/src/getSharedResource.js +30 -0
- package/src/i18nBundle.js +59 -8
- 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/locale/nextFallbackLocale.js +6 -4
- package/src/locale/normalizeLocale.js +7 -1
- package/src/renderer/LitRenderer.js +26 -7
- package/src/renderer/directives/style-map.js +72 -0
- package/src/renderer/executeTemplate.js +17 -0
- package/src/theming/CustomStyle.js +47 -6
- package/src/theming/ThemeLoaded.js +22 -0
- package/src/theming/applyTheme.js +69 -9
- 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 +87 -0
- 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 +58 -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/detectNavigatorLanguage.js +3 -1
- package/src/util/escapeRegex.js +10 -0
- package/src/util/findNodeOwner.js +35 -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/getFileExtension.js +21 -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 +11 -2
- 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/renderer/ifDefined.js +0 -21
- package/dist/resources/bundle.es5.js +0 -212
- package/dist/resources/bundle.es5.js.map +0 -1
- package/dist/test-resources/dev-helpers/ExternalThemePresent.js +0 -3
- package/dist/theming/CSSVarsPonyfill.js +0 -25
- package/dist/theming/ExternalThemePresent.js +0 -12
- package/dist/theming/adaptCSSForIE.js +0 -90
- package/dist/theming/createComponentStyleTag.js +0 -32
- package/dist/theming/createThemePropertiesStyleTag.js +0 -27
- 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/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/renderer/ifDefined.js +0 -21
- package/src/theming/CSSVarsPonyfill.js +0 -25
- package/src/theming/ExternalThemePresent.js +0 -12
- package/src/theming/adaptCSSForIE.js +0 -90
- package/src/theming/createComponentStyleTag.js +0 -32
- package/src/theming/createThemePropertiesStyleTag.js +0 -27
- 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/dist/UI5Element.js
CHANGED
|
@@ -1,29 +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 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";
|
|
7
11
|
import { skipOriginalEvent } from "./config/NoConflict.js";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import getEffectiveStyle from "./theming/getEffectiveStyle.js";
|
|
11
|
-
import Integer from "./types/Integer.js";
|
|
12
|
+
import getEffectiveDir from "./locale/getEffectiveDir.js";
|
|
13
|
+
import DataType from "./types/DataType.js";
|
|
12
14
|
import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js";
|
|
13
15
|
import isValidPropertyName from "./util/isValidPropertyName.js";
|
|
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";
|
|
14
22
|
|
|
15
|
-
const metadata = {
|
|
16
|
-
events: {
|
|
17
|
-
_propertyChange: {},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const DefinitionsSet = new Set();
|
|
22
23
|
let autoId = 0;
|
|
23
24
|
|
|
24
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
|
+
}
|
|
25
48
|
|
|
26
|
-
const GLOBAL_CONTENT_DENSITY_CSS_VAR = "--_ui5_content_density";
|
|
27
49
|
/**
|
|
28
50
|
* Base class for all UI5 Web Components
|
|
29
51
|
*
|
|
@@ -37,56 +59,40 @@ const GLOBAL_CONTENT_DENSITY_CSS_VAR = "--_ui5_content_density";
|
|
|
37
59
|
class UI5Element extends HTMLElement {
|
|
38
60
|
constructor() {
|
|
39
61
|
super();
|
|
40
|
-
this._generateId();
|
|
41
|
-
this._initializeState();
|
|
42
|
-
this._upgradeAllProperties();
|
|
43
|
-
this._initializeContainers();
|
|
44
|
-
this._upToDate = false;
|
|
45
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
|
|
46
70
|
let deferredResolve;
|
|
47
71
|
this._domRefReadyPromise = new Promise(resolve => {
|
|
48
72
|
deferredResolve = resolve;
|
|
49
73
|
});
|
|
50
74
|
this._domRefReadyPromise._deferredResolve = deferredResolve;
|
|
51
75
|
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
54
|
-
}
|
|
76
|
+
this._initializeState();
|
|
77
|
+
this._upgradeAllProperties();
|
|
55
78
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
_generateId() {
|
|
60
|
-
this._id = `ui5wc_${++autoId}`;
|
|
79
|
+
if (this.constructor._needsShadowDOM()) {
|
|
80
|
+
this.attachShadow({ mode: "open" });
|
|
81
|
+
}
|
|
61
82
|
}
|
|
62
83
|
|
|
63
84
|
/**
|
|
64
|
-
*
|
|
85
|
+
* Returns a unique ID for this UI5 Element
|
|
86
|
+
*
|
|
87
|
+
* @deprecated - This property is not guaranteed in future releases
|
|
88
|
+
* @protected
|
|
65
89
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Init Shadow Root
|
|
71
|
-
if (needsShadowDOM) {
|
|
72
|
-
this.attachShadow({ mode: "open" });
|
|
73
|
-
|
|
74
|
-
// IE11, Edge
|
|
75
|
-
if (window.ShadyDOM) {
|
|
76
|
-
createComponentStyleTag(this.constructor);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Chrome
|
|
80
|
-
if (document.adoptedStyleSheets) {
|
|
81
|
-
const style = getConstructableStyle(this.constructor);
|
|
82
|
-
this.shadowRoot.adoptedStyleSheets = [style];
|
|
83
|
-
}
|
|
90
|
+
get _id() {
|
|
91
|
+
if (!this.__id) {
|
|
92
|
+
this.__id = `ui5wc_${++autoId}`;
|
|
84
93
|
}
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
if (needsStaticArea) {
|
|
88
|
-
this.staticAreaItem = new StaticAreaItem(this);
|
|
89
|
-
}
|
|
95
|
+
return this.__id;
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
/**
|
|
@@ -94,28 +100,30 @@ class UI5Element extends HTMLElement {
|
|
|
94
100
|
* @private
|
|
95
101
|
*/
|
|
96
102
|
async connectedCallback() {
|
|
97
|
-
|
|
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
|
-
|
|
113
|
-
}
|
|
112
|
+
if (slotsAreManaged) {
|
|
113
|
+
// always register the observer before yielding control to the main thread (await)
|
|
114
|
+
this._startObservingDOMChildren();
|
|
115
|
+
await this._processChildren();
|
|
114
116
|
}
|
|
115
117
|
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
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();
|
|
119
127
|
}
|
|
120
128
|
}
|
|
121
129
|
|
|
@@ -124,23 +132,26 @@ class UI5Element extends HTMLElement {
|
|
|
124
132
|
* @private
|
|
125
133
|
*/
|
|
126
134
|
disconnectedCallback() {
|
|
127
|
-
const needsShadowDOM = this.constructor._needsShadowDOM();
|
|
128
|
-
const needsStaticArea = this.constructor._needsStaticArea();
|
|
129
135
|
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
if (slotsAreManaged) {
|
|
133
|
-
this._stopObservingDOMChildren();
|
|
134
|
-
}
|
|
137
|
+
this._inDOM = false;
|
|
135
138
|
|
|
139
|
+
if (slotsAreManaged) {
|
|
140
|
+
this._stopObservingDOMChildren();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (this._fullyConnected) {
|
|
136
144
|
if (typeof this.onExitDOM === "function") {
|
|
137
145
|
this.onExitDOM();
|
|
138
146
|
}
|
|
147
|
+
this._fullyConnected = false;
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
if (
|
|
142
|
-
this.staticAreaItem.
|
|
150
|
+
if (this.staticAreaItem && this.staticAreaItem.parentElement) {
|
|
151
|
+
this.staticAreaItem.parentElement.removeChild(this.staticAreaItem);
|
|
143
152
|
}
|
|
153
|
+
|
|
154
|
+
cancelRender(this);
|
|
144
155
|
}
|
|
145
156
|
|
|
146
157
|
/**
|
|
@@ -156,16 +167,16 @@ class UI5Element extends HTMLElement {
|
|
|
156
167
|
const mutationObserverOptions = {
|
|
157
168
|
childList: true,
|
|
158
169
|
subtree: canSlotText,
|
|
159
|
-
characterData:
|
|
170
|
+
characterData: canSlotText,
|
|
160
171
|
};
|
|
161
|
-
|
|
172
|
+
observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions);
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
/**
|
|
165
176
|
* @private
|
|
166
177
|
*/
|
|
167
178
|
_stopObservingDOMChildren() {
|
|
168
|
-
|
|
179
|
+
unobserveDOMNode(this);
|
|
169
180
|
}
|
|
170
181
|
|
|
171
182
|
/**
|
|
@@ -187,8 +198,14 @@ class UI5Element extends HTMLElement {
|
|
|
187
198
|
const canSlotText = this.constructor.getMetadata().canSlotText();
|
|
188
199
|
const domChildren = Array.from(canSlotText ? this.childNodes : this.children);
|
|
189
200
|
|
|
190
|
-
//
|
|
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
|
|
191
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]]);
|
|
192
209
|
this._clearSlot(slotName, slotData);
|
|
193
210
|
}
|
|
194
211
|
|
|
@@ -197,7 +214,7 @@ class UI5Element extends HTMLElement {
|
|
|
197
214
|
|
|
198
215
|
const allChildrenUpgraded = domChildren.map(async (child, idx) => {
|
|
199
216
|
// Determine the type of the child (mainly by the slot attribute)
|
|
200
|
-
const slotName =
|
|
217
|
+
const slotName = getSlotName(child);
|
|
201
218
|
const slotData = slotsMap[slotName];
|
|
202
219
|
|
|
203
220
|
// Check if the slotName is supported
|
|
@@ -235,8 +252,15 @@ class UI5Element extends HTMLElement {
|
|
|
235
252
|
|
|
236
253
|
child = this.constructor.getMetadata().constructor.validateSlotValue(child, slotData);
|
|
237
254
|
|
|
238
|
-
if (
|
|
239
|
-
|
|
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));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Listen for the slotchange event if the child is a slot itself
|
|
262
|
+
if (isSlot(child)) {
|
|
263
|
+
this._attachSlotChange(child, slotName);
|
|
240
264
|
}
|
|
241
265
|
|
|
242
266
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -252,10 +276,33 @@ class UI5Element extends HTMLElement {
|
|
|
252
276
|
|
|
253
277
|
// Distribute the child in the _state object, keeping the Light DOM order,
|
|
254
278
|
// not the order elements are defined.
|
|
255
|
-
slottedChildrenMap.forEach((children,
|
|
256
|
-
this._state[
|
|
279
|
+
slottedChildrenMap.forEach((children, propertyName) => {
|
|
280
|
+
this._state[propertyName] = children.sort((a, b) => a.idx - b.idx).map(_ => _.child);
|
|
257
281
|
});
|
|
258
|
-
|
|
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
|
+
}
|
|
259
306
|
}
|
|
260
307
|
|
|
261
308
|
/**
|
|
@@ -264,20 +311,62 @@ class UI5Element extends HTMLElement {
|
|
|
264
311
|
*/
|
|
265
312
|
_clearSlot(slotName, slotData) {
|
|
266
313
|
const propertyName = slotData.propertyName || slotName;
|
|
267
|
-
|
|
268
|
-
let children = this._state[propertyName];
|
|
269
|
-
if (!Array.isArray(children)) {
|
|
270
|
-
children = [children];
|
|
271
|
-
}
|
|
314
|
+
const children = this._state[propertyName];
|
|
272
315
|
|
|
273
316
|
children.forEach(child => {
|
|
274
317
|
if (child && child.isUI5Element) {
|
|
275
|
-
|
|
318
|
+
const method = (child.detachInvalidate || child._detachChange).bind(child);
|
|
319
|
+
method(this._getChildChangeListener(slotName));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (isSlot(child)) {
|
|
323
|
+
this._detachSlotChange(child, slotName);
|
|
276
324
|
}
|
|
277
325
|
});
|
|
278
326
|
|
|
279
327
|
this._state[propertyName] = [];
|
|
280
|
-
|
|
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
|
+
});
|
|
281
370
|
}
|
|
282
371
|
|
|
283
372
|
/**
|
|
@@ -292,9 +381,8 @@ class UI5Element extends HTMLElement {
|
|
|
292
381
|
const propertyTypeClass = properties[nameInCamelCase].type;
|
|
293
382
|
if (propertyTypeClass === Boolean) {
|
|
294
383
|
newValue = newValue !== null;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
newValue = parseInt(newValue);
|
|
384
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
385
|
+
newValue = propertyTypeClass.attributeToProperty(newValue);
|
|
298
386
|
}
|
|
299
387
|
this[nameInCamelCase] = newValue;
|
|
300
388
|
}
|
|
@@ -307,22 +395,24 @@ class UI5Element extends HTMLElement {
|
|
|
307
395
|
if (!this.constructor.getMetadata().hasAttribute(name)) {
|
|
308
396
|
return;
|
|
309
397
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
398
|
+
const properties = this.constructor.getMetadata().getProperties();
|
|
399
|
+
const propertyTypeClass = properties[name].type;
|
|
315
400
|
const attrName = camelToKebabCase(name);
|
|
316
401
|
const attrValue = this.getAttribute(attrName);
|
|
317
|
-
|
|
402
|
+
|
|
403
|
+
if (propertyTypeClass === Boolean) {
|
|
318
404
|
if (newValue === true && attrValue === null) {
|
|
319
405
|
this.setAttribute(attrName, "");
|
|
320
406
|
} else if (newValue === false && attrValue !== null) {
|
|
321
407
|
this.removeAttribute(attrName);
|
|
322
408
|
}
|
|
323
|
-
} else if (
|
|
324
|
-
this.setAttribute(attrName, newValue);
|
|
325
|
-
}
|
|
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
|
|
326
416
|
}
|
|
327
417
|
|
|
328
418
|
/**
|
|
@@ -348,101 +438,96 @@ class UI5Element extends HTMLElement {
|
|
|
348
438
|
* @private
|
|
349
439
|
*/
|
|
350
440
|
_initializeState() {
|
|
351
|
-
|
|
352
|
-
this._state = Object.assign({}, defaultState);
|
|
441
|
+
this._state = { ...this.constructor.getMetadata().getInitialState() };
|
|
353
442
|
}
|
|
354
443
|
|
|
355
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}
|
|
356
449
|
* @private
|
|
357
450
|
*/
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
slotName
|
|
361
|
-
childProperties = childMetadata.getProperties();
|
|
362
|
-
|
|
363
|
-
let observedProps = [],
|
|
364
|
-
notObservedProps = [];
|
|
365
|
-
|
|
366
|
-
if (Array.isArray(listenFor)) {
|
|
367
|
-
observedProps = listenFor;
|
|
368
|
-
} else {
|
|
369
|
-
observedProps = Array.isArray(listenFor.props) ? listenFor.props : Object.keys(childProperties);
|
|
370
|
-
notObservedProps = Array.isArray(listenFor.exclude) ? listenFor.exclude : [];
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
if (!this._monitoredChildProps.has(slotName)) {
|
|
374
|
-
this._monitoredChildProps.set(slotName, { observedProps, notObservedProps });
|
|
451
|
+
_getChildChangeListener(slotName) {
|
|
452
|
+
if (!this._childChangeListeners.has(slotName)) {
|
|
453
|
+
this._childChangeListeners.set(slotName, this._onChildChange.bind(this, slotName));
|
|
375
454
|
}
|
|
376
|
-
|
|
377
|
-
child.addEventListener("_propertyChange", this._invalidateParentOnPropertyUpdate);
|
|
378
|
-
child._firePropertyChange = true;
|
|
455
|
+
return this._childChangeListeners.get(slotName);
|
|
379
456
|
}
|
|
380
457
|
|
|
381
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}
|
|
382
463
|
* @private
|
|
383
464
|
*/
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
465
|
+
_getSlotChangeListener(slotName) {
|
|
466
|
+
if (!this._slotChangeListeners.has(slotName)) {
|
|
467
|
+
this._slotChangeListeners.set(slotName, this._onSlotChange.bind(this, slotName));
|
|
468
|
+
}
|
|
469
|
+
return this._slotChangeListeners.get(slotName);
|
|
387
470
|
}
|
|
388
471
|
|
|
389
472
|
/**
|
|
390
473
|
* @private
|
|
391
474
|
*/
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if (this._firePropertyChange) {
|
|
396
|
-
this.dispatchEvent(new CustomEvent("_propertyChange", {
|
|
397
|
-
detail: { name, newValue: value },
|
|
398
|
-
composed: false,
|
|
399
|
-
bubbles: true,
|
|
400
|
-
}));
|
|
401
|
-
}
|
|
475
|
+
_attachSlotChange(child, slotName) {
|
|
476
|
+
child.addEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
402
477
|
}
|
|
403
478
|
|
|
404
479
|
/**
|
|
405
480
|
* @private
|
|
406
481
|
*/
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const parentNode = this.parentNode;
|
|
410
|
-
if (!parentNode) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const slotName = parentNode.constructor._getSlotName(this);
|
|
415
|
-
const propsMetadata = parentNode._monitoredChildProps.get(slotName);
|
|
416
|
-
|
|
417
|
-
if (!propsMetadata) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
const { observedProps, notObservedProps } = propsMetadata;
|
|
421
|
-
|
|
422
|
-
if (observedProps.includes(prop.detail.name) && !notObservedProps.includes(prop.detail.name)) {
|
|
423
|
-
parentNode._invalidate("_parent_", this);
|
|
424
|
-
}
|
|
482
|
+
_detachSlotChange(child, slotName) {
|
|
483
|
+
child.removeEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
425
484
|
}
|
|
426
485
|
|
|
427
486
|
/**
|
|
428
|
-
*
|
|
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
|
|
429
490
|
* @private
|
|
430
491
|
*/
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (this.getDomRef() && !this._suppressInvalidation) {
|
|
438
|
-
this._upToDate = false;
|
|
439
|
-
// console.log("INVAL", this, ...arguments);
|
|
440
|
-
RenderScheduler.renderDeferred(this);
|
|
441
|
-
}
|
|
492
|
+
_onSlotChange(slotName) {
|
|
493
|
+
_invalidate.call(this, {
|
|
494
|
+
type: "slot",
|
|
495
|
+
name: slotName,
|
|
496
|
+
reason: "slotchange",
|
|
497
|
+
});
|
|
442
498
|
}
|
|
443
499
|
|
|
444
500
|
/**
|
|
445
|
-
*
|
|
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
|
|
526
|
+
*/
|
|
527
|
+
onInvalidation(changeInfo) {}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Do not call this method directly, only intended to be called by js
|
|
446
531
|
* @protected
|
|
447
532
|
*/
|
|
448
533
|
_render() {
|
|
@@ -461,15 +546,37 @@ class UI5Element extends HTMLElement {
|
|
|
461
546
|
}
|
|
462
547
|
|
|
463
548
|
// resume normal invalidation handling
|
|
464
|
-
|
|
549
|
+
this._suppressInvalidation = false;
|
|
465
550
|
|
|
466
551
|
// Update the shadow root with the render result
|
|
467
|
-
|
|
468
|
-
this.
|
|
469
|
-
|
|
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
|
+
}
|
|
470
567
|
|
|
471
|
-
|
|
472
|
-
|
|
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();
|
|
473
580
|
}
|
|
474
581
|
|
|
475
582
|
// Safari requires that children get the slot attribute only after the slot tags have been rendered in the shadow DOM
|
|
@@ -483,19 +590,6 @@ class UI5Element extends HTMLElement {
|
|
|
483
590
|
}
|
|
484
591
|
}
|
|
485
592
|
|
|
486
|
-
/**
|
|
487
|
-
* @private
|
|
488
|
-
*/
|
|
489
|
-
_updateShadowRoot() {
|
|
490
|
-
let styleToPrepend;
|
|
491
|
-
const renderResult = this.constructor.template(this);
|
|
492
|
-
|
|
493
|
-
if (!document.adoptedStyleSheets && !window.ShadyDOM) {
|
|
494
|
-
styleToPrepend = getEffectiveStyle(this.constructor);
|
|
495
|
-
}
|
|
496
|
-
this.constructor.render(renderResult, this.shadowRoot, styleToPrepend, { eventContext: this });
|
|
497
|
-
}
|
|
498
|
-
|
|
499
593
|
/**
|
|
500
594
|
* @private
|
|
501
595
|
*/
|
|
@@ -518,16 +612,27 @@ class UI5Element extends HTMLElement {
|
|
|
518
612
|
|
|
519
613
|
/**
|
|
520
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
|
|
521
616
|
* Use this method instead of "this.shadowRoot" to read the Shadow DOM, if ever necessary
|
|
617
|
+
*
|
|
522
618
|
* @public
|
|
523
619
|
*/
|
|
524
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
|
+
|
|
525
626
|
if (!this.shadowRoot || this.shadowRoot.children.length === 0) {
|
|
526
627
|
return;
|
|
527
628
|
}
|
|
528
629
|
|
|
529
|
-
|
|
530
|
-
|
|
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];
|
|
531
636
|
}
|
|
532
637
|
|
|
533
638
|
/**
|
|
@@ -543,6 +648,16 @@ class UI5Element extends HTMLElement {
|
|
|
543
648
|
}
|
|
544
649
|
}
|
|
545
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
|
+
|
|
546
661
|
/**
|
|
547
662
|
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref")
|
|
548
663
|
* @public
|
|
@@ -563,37 +678,47 @@ class UI5Element extends HTMLElement {
|
|
|
563
678
|
* @param name - name of the event
|
|
564
679
|
* @param data - additional data for the event
|
|
565
680
|
* @param cancelable - true, if the user can call preventDefault on the event object
|
|
681
|
+
* @param bubbles - true, if the event bubbles
|
|
566
682
|
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise
|
|
567
683
|
*/
|
|
568
|
-
fireEvent(name, data, cancelable) {
|
|
569
|
-
|
|
684
|
+
fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
685
|
+
const eventResult = this._fireEvent(name, data, cancelable, bubbles);
|
|
686
|
+
const camelCaseEventName = kebabToCamelCase(name);
|
|
687
|
+
|
|
688
|
+
if (camelCaseEventName !== name) {
|
|
689
|
+
return eventResult && this._fireEvent(camelCaseEventName, data, cancelable);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return eventResult;
|
|
693
|
+
}
|
|
570
694
|
|
|
695
|
+
_fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
571
696
|
const noConflictEvent = new CustomEvent(`ui5-${name}`, {
|
|
572
697
|
detail: data,
|
|
573
698
|
composed: false,
|
|
574
|
-
bubbles
|
|
699
|
+
bubbles,
|
|
575
700
|
cancelable,
|
|
576
701
|
});
|
|
577
702
|
|
|
578
|
-
// This will be false if the
|
|
579
|
-
|
|
703
|
+
// This will be false if the no-conflict event is prevented
|
|
704
|
+
const noConflictEventResult = this.dispatchEvent(noConflictEvent);
|
|
580
705
|
|
|
581
706
|
if (skipOriginalEvent(name)) {
|
|
582
|
-
return
|
|
707
|
+
return noConflictEventResult;
|
|
583
708
|
}
|
|
584
709
|
|
|
585
|
-
const
|
|
710
|
+
const normalEvent = new CustomEvent(name, {
|
|
586
711
|
detail: data,
|
|
587
712
|
composed: false,
|
|
588
|
-
bubbles
|
|
713
|
+
bubbles,
|
|
589
714
|
cancelable,
|
|
590
715
|
});
|
|
591
716
|
|
|
592
717
|
// This will be false if the normal event is prevented
|
|
593
|
-
const normalEventResult = this.dispatchEvent(
|
|
718
|
+
const normalEventResult = this.dispatchEvent(normalEvent);
|
|
594
719
|
|
|
595
720
|
// Return false if any of the two events was prevented (its result was false).
|
|
596
|
-
return normalEventResult &&
|
|
721
|
+
return normalEventResult && noConflictEventResult;
|
|
597
722
|
}
|
|
598
723
|
|
|
599
724
|
/**
|
|
@@ -602,24 +727,19 @@ class UI5Element extends HTMLElement {
|
|
|
602
727
|
* @public
|
|
603
728
|
*/
|
|
604
729
|
getSlottedNodes(slotName) {
|
|
605
|
-
|
|
606
|
-
if (curr.localName !== "slot") {
|
|
607
|
-
return acc.concat([curr]);
|
|
608
|
-
}
|
|
609
|
-
return acc.concat(curr.assignedNodes({ flatten: true }).filter(item => item instanceof HTMLElement));
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
return this[slotName].reduce(reducer, []);
|
|
730
|
+
return getSlottedElementsList(this[slotName]);
|
|
613
731
|
}
|
|
614
732
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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);
|
|
623
743
|
}
|
|
624
744
|
|
|
625
745
|
/**
|
|
@@ -639,26 +759,6 @@ class UI5Element extends HTMLElement {
|
|
|
639
759
|
return this.getMetadata().getAttributesList();
|
|
640
760
|
}
|
|
641
761
|
|
|
642
|
-
/**
|
|
643
|
-
* @private
|
|
644
|
-
*/
|
|
645
|
-
static _getSlotName(child) {
|
|
646
|
-
// Text nodes can only go to the default slot
|
|
647
|
-
if (!(child instanceof HTMLElement)) {
|
|
648
|
-
return "default";
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// Discover the slot based on the real slot name (f.e. footer => footer, or content-32 => content)
|
|
652
|
-
const slot = child.getAttribute("slot");
|
|
653
|
-
if (slot) {
|
|
654
|
-
const match = slot.match(/^(.+?)-\d+$/);
|
|
655
|
-
return match ? match[1] : slot;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// Use default slot as a fallback
|
|
659
|
-
return "default";
|
|
660
|
-
}
|
|
661
|
-
|
|
662
762
|
/**
|
|
663
763
|
* @private
|
|
664
764
|
*/
|
|
@@ -670,62 +770,26 @@ class UI5Element extends HTMLElement {
|
|
|
670
770
|
* @private
|
|
671
771
|
*/
|
|
672
772
|
static _needsStaticArea() {
|
|
673
|
-
return
|
|
773
|
+
return !!this.staticAreaTemplate;
|
|
674
774
|
}
|
|
675
775
|
|
|
676
776
|
/**
|
|
677
777
|
* @public
|
|
678
778
|
*/
|
|
679
779
|
getStaticAreaItemDomRef() {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* @private
|
|
685
|
-
*/
|
|
686
|
-
static _getDefaultState() {
|
|
687
|
-
if (this._defaultState) {
|
|
688
|
-
return this._defaultState;
|
|
780
|
+
if (!this.constructor._needsStaticArea()) {
|
|
781
|
+
throw new Error("This component does not use the static area");
|
|
689
782
|
}
|
|
690
783
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
// Initialize properties
|
|
696
|
-
const props = MetadataClass.getProperties();
|
|
697
|
-
for (const propName in props) { // eslint-disable-line
|
|
698
|
-
const propType = props[propName].type;
|
|
699
|
-
const propDefaultValue = props[propName].defaultValue;
|
|
700
|
-
|
|
701
|
-
if (propType === Boolean) {
|
|
702
|
-
defaultState[propName] = false;
|
|
703
|
-
|
|
704
|
-
if (propDefaultValue !== undefined) {
|
|
705
|
-
console.warn("The 'defaultValue' metadata key is ignored for all booleans properties, they would be initialized with 'false' by default"); // eslint-disable-line
|
|
706
|
-
}
|
|
707
|
-
} else if (props[propName].multiple) {
|
|
708
|
-
defaultState[propName] = [];
|
|
709
|
-
} else if (propType === Object) {
|
|
710
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : {};
|
|
711
|
-
} else if (propType === String) {
|
|
712
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : "";
|
|
713
|
-
} else {
|
|
714
|
-
defaultState[propName] = propDefaultValue;
|
|
715
|
-
}
|
|
784
|
+
if (!this.staticAreaItem) {
|
|
785
|
+
this.staticAreaItem = StaticAreaItem.createInstance();
|
|
786
|
+
this.staticAreaItem.setOwnerElement(this);
|
|
716
787
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
if (slotsAreManaged) {
|
|
720
|
-
const slots = MetadataClass.getSlots();
|
|
721
|
-
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
722
|
-
const propertyName = slotData.propertyName || slotName;
|
|
723
|
-
defaultState[propertyName] = [];
|
|
724
|
-
}
|
|
788
|
+
if (!this.staticAreaItem.parentElement) {
|
|
789
|
+
getSingletonElementInstance("ui5-static-area").appendChild(this.staticAreaItem);
|
|
725
790
|
}
|
|
726
791
|
|
|
727
|
-
this.
|
|
728
|
-
return defaultState;
|
|
792
|
+
return this.staticAreaItem.getDomRef();
|
|
729
793
|
}
|
|
730
794
|
|
|
731
795
|
/**
|
|
@@ -739,13 +803,25 @@ class UI5Element extends HTMLElement {
|
|
|
739
803
|
const properties = this.getMetadata().getProperties();
|
|
740
804
|
for (const [prop, propData] of Object.entries(properties)) { // eslint-disable-line
|
|
741
805
|
if (!isValidPropertyName(prop)) {
|
|
742
|
-
|
|
806
|
+
console.warn(`"${prop}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
743
807
|
}
|
|
744
808
|
|
|
745
|
-
if (propData.type ===
|
|
809
|
+
if (propData.type === Boolean && propData.defaultValue) {
|
|
746
810
|
throw new Error(`Cannot set a default value for property "${prop}". All booleans are false by default.`);
|
|
747
811
|
}
|
|
748
812
|
|
|
813
|
+
if (propData.type === Array) {
|
|
814
|
+
throw new Error(`Wrong type for property "${prop}". Properties cannot be of type Array - use "multiple: true" and set "type" to the single value type, such as "String", "Object", etc...`);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
if (propData.type === Object && propData.defaultValue) {
|
|
818
|
+
throw new Error(`Cannot set a default value for property "${prop}". All properties of type "Object" are empty objects by default.`);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (propData.multiple && propData.defaultValue) {
|
|
822
|
+
throw new Error(`Cannot set a default value for property "${prop}". All multiple properties are empty arrays by default.`);
|
|
823
|
+
}
|
|
824
|
+
|
|
749
825
|
Object.defineProperty(proto, prop, {
|
|
750
826
|
get() {
|
|
751
827
|
if (this._state[prop] !== undefined) {
|
|
@@ -765,14 +841,27 @@ class UI5Element extends HTMLElement {
|
|
|
765
841
|
}
|
|
766
842
|
},
|
|
767
843
|
set(value) {
|
|
844
|
+
let isDifferent;
|
|
768
845
|
value = this.constructor.getMetadata().constructor.validatePropertyValue(value, propData);
|
|
769
846
|
|
|
770
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
|
+
}
|
|
771
855
|
|
|
772
|
-
if (
|
|
856
|
+
if (isDifferent) {
|
|
773
857
|
this._state[prop] = value;
|
|
774
|
-
|
|
775
|
-
|
|
858
|
+
_invalidate.call(this, {
|
|
859
|
+
type: "property",
|
|
860
|
+
name: prop,
|
|
861
|
+
newValue: value,
|
|
862
|
+
oldValue: oldState,
|
|
863
|
+
});
|
|
864
|
+
this._updateAttribute(prop, value);
|
|
776
865
|
}
|
|
777
866
|
},
|
|
778
867
|
});
|
|
@@ -783,7 +872,7 @@ class UI5Element extends HTMLElement {
|
|
|
783
872
|
const slots = this.getMetadata().getSlots();
|
|
784
873
|
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
785
874
|
if (!isValidPropertyName(slotName)) {
|
|
786
|
-
|
|
875
|
+
console.warn(`"${slotName}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
787
876
|
}
|
|
788
877
|
|
|
789
878
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -795,7 +884,7 @@ class UI5Element extends HTMLElement {
|
|
|
795
884
|
return [];
|
|
796
885
|
},
|
|
797
886
|
set() {
|
|
798
|
-
throw new Error("Cannot set
|
|
887
|
+
throw new Error("Cannot set slot content directly, use the DOM APIs (appendChild, removeChild, etc...)");
|
|
799
888
|
},
|
|
800
889
|
});
|
|
801
890
|
}
|
|
@@ -807,7 +896,7 @@ class UI5Element extends HTMLElement {
|
|
|
807
896
|
* @protected
|
|
808
897
|
*/
|
|
809
898
|
static get metadata() {
|
|
810
|
-
return
|
|
899
|
+
return {};
|
|
811
900
|
}
|
|
812
901
|
|
|
813
902
|
/**
|
|
@@ -818,6 +907,58 @@ class UI5Element extends HTMLElement {
|
|
|
818
907
|
return "";
|
|
819
908
|
}
|
|
820
909
|
|
|
910
|
+
/**
|
|
911
|
+
* Returns the Static Area CSS for this UI5 Web Component Class
|
|
912
|
+
* @protected
|
|
913
|
+
*/
|
|
914
|
+
static get staticAreaStyles() {
|
|
915
|
+
return "";
|
|
916
|
+
}
|
|
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
|
+
|
|
821
962
|
/**
|
|
822
963
|
* Registers a UI5 Web Component in the browser window object
|
|
823
964
|
* @public
|
|
@@ -826,21 +967,31 @@ class UI5Element extends HTMLElement {
|
|
|
826
967
|
static async define() {
|
|
827
968
|
await boot();
|
|
828
969
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
970
|
+
await Promise.all([
|
|
971
|
+
this.whenDependenciesDefined(),
|
|
972
|
+
this.onDefine(),
|
|
973
|
+
]);
|
|
832
974
|
|
|
833
975
|
const tag = this.getMetadata().getTag();
|
|
976
|
+
const altTag = this.getMetadata().getAltTag();
|
|
834
977
|
|
|
835
|
-
const definedLocally =
|
|
978
|
+
const definedLocally = isTagRegistered(tag);
|
|
836
979
|
const definedGlobally = customElements.get(tag);
|
|
837
980
|
|
|
838
981
|
if (definedGlobally && !definedLocally) {
|
|
839
|
-
|
|
982
|
+
recordTagRegistrationFailure(tag);
|
|
840
983
|
} else if (!definedGlobally) {
|
|
841
984
|
this._generateAccessors();
|
|
842
|
-
|
|
985
|
+
registerTag(tag);
|
|
843
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
|
+
}
|
|
844
995
|
}
|
|
845
996
|
return this;
|
|
846
997
|
}
|