@ui5/webcomponents-base 0.0.0-323968e1b → 0.0.0-4180fe799
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +4 -0
- package/CHANGELOG.md +196 -0
- package/README.md +26 -2
- package/bundle.esm.js +18 -12
- package/dist/AssetRegistry.js +8 -6
- package/dist/Boot.js +43 -0
- package/dist/CSP.js +59 -0
- package/dist/CustomElementsRegistry.js +39 -0
- package/dist/CustomElementsScope.js +108 -0
- package/dist/DOMObserver.js +65 -0
- package/dist/Device.js +62 -778
- package/dist/EventProvider.js +38 -26
- package/dist/FontFace.js +20 -56
- package/dist/InitialConfiguration.js +64 -17
- package/dist/Keys.js +248 -0
- 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/StaticArea.js +1 -39
- package/dist/StaticAreaItem.js +65 -40
- package/dist/SystemCSSVars.js +10 -0
- package/dist/Theming.js +3 -44
- package/dist/UI5Element.js +483 -307
- package/dist/UI5ElementMetadata.js +190 -19
- package/dist/asset-registries/Icons.js +129 -14
- package/dist/asset-registries/Illustrations.js +30 -0
- package/dist/asset-registries/LocaleData.js +108 -50
- package/dist/asset-registries/Themes.js +35 -32
- package/dist/asset-registries/i18n.js +80 -34
- package/dist/assets-meta/IconCollectionsAlias.js +18 -0
- package/dist/config/AnimationMode.js +16 -2
- package/dist/config/CalendarType.js +7 -7
- package/dist/config/FormatSettings.js +5 -1
- package/dist/config/Language.js +62 -3
- package/dist/config/NoConflict.js +10 -3
- package/dist/config/Theme.js +21 -3
- 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 +245 -172
- package/dist/delegate/ResizeHandler.js +78 -38
- package/dist/delegate/ScrollEnablement.js +122 -14
- package/dist/features/OpenUI5Support.js +125 -0
- package/dist/generated/AssetParameters.js +13 -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 +62 -11
- package/dist/isLegacyBrowser.js +3 -0
- package/dist/{Locale.js → locale/Locale.js} +0 -10
- 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 +41 -0
- package/dist/locale/languageChange.js +22 -0
- package/dist/locale/nextFallbackLocale.js +28 -0
- package/{src/util → dist/locale}/normalizeLocale.js +8 -31
- 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/sanitizeHTML.js +16 -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 +11 -5
- package/dist/test-resources/elements/Generic.js +1 -0
- package/dist/test-resources/elements/Parent.js +7 -2
- package/dist/test-resources/elements/WithStaticArea.js +77 -0
- package/dist/test-resources/pages/AllTestElements.html +5 -5
- 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 +28 -7
- package/dist/theming/ThemeLoaded.js +22 -0
- package/dist/theming/applyTheme.js +75 -0
- package/dist/theming/getConstructableStyle.js +30 -0
- package/dist/theming/getEffectiveLinksHrefs.js +20 -0
- package/dist/theming/getEffectiveStyle.js +30 -0
- package/dist/theming/getStylesString.js +15 -0
- package/dist/theming/getThemeDesignerTheme.js +68 -0
- package/dist/theming/preloadLinks.js +23 -0
- package/dist/thirdparty/_merge.js +32 -0
- package/dist/thirdparty/isPlainObject.js +18 -0
- package/dist/thirdparty/merge.js +10 -0
- package/dist/types/CSSColor.js +9 -0
- package/{src/dates → dist/types}/CalendarType.js +2 -2
- 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 +2 -1
- package/dist/updateShadowRoot.js +30 -0
- package/dist/util/AriaLabelHelper.js +41 -0
- package/dist/util/Caret.js +45 -0
- package/dist/util/ColorConversion.js +370 -0
- package/dist/util/FocusableElements.js +25 -8
- 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/StringHelper.js +17 -2
- package/dist/util/TabbableElements.js +5 -2
- 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/encodeCSS.js +24 -0
- package/dist/util/findNodeOwner.js +35 -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/package-scripts.js +41 -18
- package/package.json +19 -14
- package/src/AssetRegistry.js +8 -6
- package/src/Boot.js +43 -0
- package/src/CSP.js +59 -0
- package/src/CustomElementsRegistry.js +39 -0
- package/src/CustomElementsScope.js +108 -0
- package/src/DOMObserver.js +65 -0
- package/src/Device.js +62 -778
- package/src/EventProvider.js +38 -26
- package/src/FontFace.js +20 -56
- package/src/InitialConfiguration.js +64 -17
- package/src/Keys.js +248 -0
- 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/StaticArea.js +1 -39
- package/src/StaticAreaItem.js +65 -40
- package/src/SystemCSSVars.js +10 -0
- package/src/Theming.js +3 -44
- package/src/UI5Element.js +483 -307
- package/src/UI5ElementMetadata.js +190 -19
- package/src/asset-registries/Icons.js +129 -14
- package/src/asset-registries/Illustrations.js +30 -0
- package/src/asset-registries/LocaleData.js +108 -50
- package/src/asset-registries/Themes.js +35 -32
- package/src/asset-registries/i18n.js +80 -34
- package/src/assets-meta/IconCollectionsAlias.js +18 -0
- package/src/config/AnimationMode.js +16 -2
- package/src/config/CalendarType.js +7 -7
- package/src/config/FormatSettings.js +5 -1
- package/src/config/Language.js +62 -3
- package/src/config/NoConflict.js +10 -3
- package/src/config/Theme.js +21 -3
- 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 +245 -172
- package/src/delegate/ResizeHandler.js +78 -38
- package/src/delegate/ScrollEnablement.js +122 -14
- package/src/features/OpenUI5Support.js +125 -0
- package/src/getSharedResource.js +30 -0
- package/src/i18nBundle.js +62 -11
- package/src/isLegacyBrowser.js +3 -0
- package/src/{Locale.js → locale/Locale.js} +0 -10
- 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 +41 -0
- package/src/locale/languageChange.js +22 -0
- package/src/locale/nextFallbackLocale.js +28 -0
- package/{dist/util → src/locale}/normalizeLocale.js +8 -31
- 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 +28 -7
- package/src/theming/ThemeLoaded.js +22 -0
- package/src/theming/applyTheme.js +75 -0
- package/src/theming/getConstructableStyle.js +30 -0
- package/src/theming/getEffectiveLinksHrefs.js +20 -0
- package/src/theming/getEffectiveStyle.js +30 -0
- package/src/theming/getStylesString.js +15 -0
- package/src/theming/getThemeDesignerTheme.js +68 -0
- package/src/theming/preloadLinks.js +23 -0
- package/src/thirdparty/_merge.js +32 -0
- package/src/thirdparty/isPlainObject.js +18 -0
- package/src/thirdparty/merge.js +10 -0
- package/src/types/CSSColor.js +9 -0
- package/{dist/dates → src/types}/CalendarType.js +2 -2
- 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 +2 -1
- package/src/updateShadowRoot.js +30 -0
- package/src/util/AriaLabelHelper.js +41 -0
- package/src/util/Caret.js +45 -0
- package/src/util/ColorConversion.js +370 -0
- package/src/util/FocusableElements.js +25 -8
- 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/StringHelper.js +17 -2
- package/src/util/TabbableElements.js +5 -2
- 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/encodeCSS.js +24 -0
- package/src/util/findNodeOwner.js +35 -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 +7 -0
- package/bundle.es5.js +0 -28
- package/dist/Assets.js +0 -2
- package/dist/CSS.js +0 -48
- package/dist/FormatSettings.js +0 -31
- package/dist/LocaleProvider.js +0 -34
- package/dist/ResourceLoaderOverrides.js +0 -38
- package/dist/SVGIconRegistry.js +0 -54
- package/dist/boot.js +0 -25
- package/dist/compatibility/DOMObserver.js +0 -62
- package/dist/compatibility/patchNodeValue.js +0 -24
- package/dist/compatibility/whenPolyfillLoaded.js +0 -26
- package/dist/dates/CalendarDate.js +0 -203
- package/dist/dates/CalendarUtils.js +0 -99
- package/dist/delegate/CustomResize.js +0 -78
- package/dist/delegate/NativeResize.js +0 -44
- package/dist/events/PseudoEvents.js +0 -58
- package/dist/features/browsersupport/Edge.js +0 -6
- package/dist/features/browsersupport/IE11.js +0 -41
- package/dist/features/calendar/Buddhist.js +0 -1
- package/dist/features/calendar/Islamic.js +0 -1
- package/dist/features/calendar/Japanese.js +0 -1
- package/dist/features/calendar/Persian.js +0 -1
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ar.json +0 -5598
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ar_EG.json +0 -5598
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ar_SA.json +0 -5598
- package/dist/generated/assets/cldr/sap/ui/core/cldr/bg.json +0 -4789
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ca.json +0 -4801
- package/dist/generated/assets/cldr/sap/ui/core/cldr/cs.json +0 -5245
- package/dist/generated/assets/cldr/sap/ui/core/cldr/da.json +0 -4696
- package/dist/generated/assets/cldr/sap/ui/core/cldr/de.json +0 -4797
- package/dist/generated/assets/cldr/sap/ui/core/cldr/de_AT.json +0 -4798
- package/dist/generated/assets/cldr/sap/ui/core/cldr/de_CH.json +0 -4796
- package/dist/generated/assets/cldr/sap/ui/core/cldr/el.json +0 -4694
- package/dist/generated/assets/cldr/sap/ui/core/cldr/el_CY.json +0 -4694
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en.json +0 -4777
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_AU.json +0 -4769
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_GB.json +0 -4778
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_HK.json +0 -4784
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_IE.json +0 -4778
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_IN.json +0 -4779
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_NZ.json +0 -4778
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_PG.json +0 -4779
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_SG.json +0 -4780
- package/dist/generated/assets/cldr/sap/ui/core/cldr/en_ZA.json +0 -4779
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es.json +0 -4719
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_AR.json +0 -4721
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_BO.json +0 -4720
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_CL.json +0 -4721
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_CO.json +0 -4721
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_MX.json +0 -4722
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_PE.json +0 -4720
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_UY.json +0 -4722
- package/dist/generated/assets/cldr/sap/ui/core/cldr/es_VE.json +0 -4721
- package/dist/generated/assets/cldr/sap/ui/core/cldr/et.json +0 -4776
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fa.json +0 -4704
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fi.json +0 -4816
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fr.json +0 -4788
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fr_BE.json +0 -4788
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fr_CA.json +0 -4782
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fr_CH.json +0 -4806
- package/dist/generated/assets/cldr/sap/ui/core/cldr/fr_LU.json +0 -4788
- package/dist/generated/assets/cldr/sap/ui/core/cldr/he.json +0 -5133
- package/dist/generated/assets/cldr/sap/ui/core/cldr/hi.json +0 -4680
- package/dist/generated/assets/cldr/sap/ui/core/cldr/hr.json +0 -4910
- package/dist/generated/assets/cldr/sap/ui/core/cldr/hu.json +0 -4664
- package/dist/generated/assets/cldr/sap/ui/core/cldr/id.json +0 -4500
- package/dist/generated/assets/cldr/sap/ui/core/cldr/it.json +0 -4757
- package/dist/generated/assets/cldr/sap/ui/core/cldr/it_CH.json +0 -4757
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ja.json +0 -4599
- package/dist/generated/assets/cldr/sap/ui/core/cldr/kk.json +0 -4537
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ko.json +0 -4574
- package/dist/generated/assets/cldr/sap/ui/core/cldr/lt.json +0 -5234
- package/dist/generated/assets/cldr/sap/ui/core/cldr/lv.json +0 -4902
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ms.json +0 -4352
- package/dist/generated/assets/cldr/sap/ui/core/cldr/nb.json +0 -4784
- package/dist/generated/assets/cldr/sap/ui/core/cldr/nl.json +0 -4790
- package/dist/generated/assets/cldr/sap/ui/core/cldr/nl_BE.json +0 -4790
- package/dist/generated/assets/cldr/sap/ui/core/cldr/pl.json +0 -5223
- package/dist/generated/assets/cldr/sap/ui/core/cldr/pt.json +0 -4703
- package/dist/generated/assets/cldr/sap/ui/core/cldr/pt_PT.json +0 -4753
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ro.json +0 -4881
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ru.json +0 -5157
- package/dist/generated/assets/cldr/sap/ui/core/cldr/ru_UA.json +0 -5157
- package/dist/generated/assets/cldr/sap/ui/core/cldr/sk.json +0 -5125
- package/dist/generated/assets/cldr/sap/ui/core/cldr/sl.json +0 -5105
- package/dist/generated/assets/cldr/sap/ui/core/cldr/sr.json +0 -4908
- package/dist/generated/assets/cldr/sap/ui/core/cldr/sv.json +0 -4818
- package/dist/generated/assets/cldr/sap/ui/core/cldr/th.json +0 -4633
- package/dist/generated/assets/cldr/sap/ui/core/cldr/tr.json +0 -4791
- package/dist/generated/assets/cldr/sap/ui/core/cldr/uk.json +0 -5126
- package/dist/generated/assets/cldr/sap/ui/core/cldr/vi.json +0 -4510
- package/dist/generated/assets/cldr/sap/ui/core/cldr/zh_CN.json +0 -4469
- package/dist/generated/assets/cldr/sap/ui/core/cldr/zh_HK.json +0 -4479
- package/dist/generated/assets/cldr/sap/ui/core/cldr/zh_SG.json +0 -4479
- package/dist/generated/assets/cldr/sap/ui/core/cldr/zh_TW.json +0 -4565
- package/dist/json-imports/LocaleData.js +0 -171
- 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/shims/Core-shim.js +0 -52
- package/dist/shims/jquery-shim.js +0 -89
- package/dist/theming/StyleInjection.js +0 -67
- 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/events-polyfills.js +0 -89
- package/dist/thirdparty/fetch.js +0 -1
- package/dist/thirdparty/template.js +0 -600
- package/dist/util/CSSTransformUtils.js +0 -90
- 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/Assets.js +0 -2
- package/src/CSS.js +0 -48
- package/src/FormatSettings.js +0 -31
- package/src/LocaleProvider.js +0 -34
- package/src/ResourceLoaderOverrides.js +0 -38
- package/src/SVGIconRegistry.js +0 -54
- package/src/boot.js +0 -25
- package/src/compatibility/DOMObserver.js +0 -62
- package/src/compatibility/patchNodeValue.js +0 -24
- package/src/compatibility/whenPolyfillLoaded.js +0 -26
- package/src/dates/CalendarDate.js +0 -203
- package/src/dates/CalendarUtils.js +0 -99
- package/src/delegate/CustomResize.js +0 -78
- package/src/delegate/NativeResize.js +0 -44
- package/src/events/PseudoEvents.js +0 -58
- package/src/features/browsersupport/Edge.js +0 -6
- package/src/features/browsersupport/IE11.js +0 -41
- package/src/features/calendar/Buddhist.js +0 -1
- package/src/features/calendar/Islamic.js +0 -1
- package/src/features/calendar/Japanese.js +0 -1
- package/src/features/calendar/Persian.js +0 -1
- package/src/json-imports/LocaleData.js +0 -171
- package/src/renderer/ifDefined.js +0 -21
- package/src/shims/Core-shim.js +0 -52
- package/src/shims/jquery-shim.js +0 -89
- package/src/theming/StyleInjection.js +0 -67
- 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/events-polyfills.js +0 -89
- package/src/thirdparty/fetch.js +0 -1
- package/src/thirdparty/template.js +0 -600
- package/src/util/CSSTransformUtils.js +0 -90
package/dist/UI5Element.js
CHANGED
|
@@ -1,26 +1,50 @@
|
|
|
1
|
-
import merge from "
|
|
2
|
-
import boot from "./
|
|
3
|
-
import { skipOriginalEvent } from "./config/NoConflict.js";
|
|
4
|
-
import DOMObserver from "./compatibility/DOMObserver.js";
|
|
1
|
+
import merge from "./thirdparty/merge.js";
|
|
2
|
+
import { boot } from "./Boot.js";
|
|
5
3
|
import UI5ElementMetadata from "./UI5ElementMetadata.js";
|
|
4
|
+
import EventProvider from "./EventProvider.js";
|
|
5
|
+
import getSingletonElementInstance from "./util/getSingletonElementInstance.js";
|
|
6
6
|
import StaticAreaItem from "./StaticAreaItem.js";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
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";
|
|
11
|
+
import { skipOriginalEvent } from "./config/NoConflict.js";
|
|
12
|
+
import getEffectiveDir from "./locale/getEffectiveDir.js";
|
|
13
|
+
import DataType from "./types/DataType.js";
|
|
11
14
|
import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js";
|
|
12
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";
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
events: {
|
|
16
|
-
_propertyChange: {},
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const DefinitionsSet = new Set();
|
|
21
|
-
const IDMap = new Map();
|
|
23
|
+
let autoId = 0;
|
|
22
24
|
|
|
23
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
|
+
}
|
|
24
48
|
|
|
25
49
|
/**
|
|
26
50
|
* Base class for all UI5 Web Components
|
|
@@ -35,51 +59,40 @@ const elementTimeouts = new Map();
|
|
|
35
59
|
class UI5Element extends HTMLElement {
|
|
36
60
|
constructor() {
|
|
37
61
|
super();
|
|
38
|
-
this._generateId();
|
|
39
|
-
this._initializeState();
|
|
40
|
-
this._upgradeAllProperties();
|
|
41
|
-
this._initializeContainers();
|
|
42
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
|
|
43
70
|
let deferredResolve;
|
|
44
71
|
this._domRefReadyPromise = new Promise(resolve => {
|
|
45
72
|
deferredResolve = resolve;
|
|
46
73
|
});
|
|
47
74
|
this._domRefReadyPromise._deferredResolve = deferredResolve;
|
|
48
75
|
|
|
49
|
-
this.
|
|
50
|
-
|
|
76
|
+
this._initializeState();
|
|
77
|
+
this._upgradeAllProperties();
|
|
51
78
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
_generateId() {
|
|
56
|
-
this._id = this.constructor._nextID();
|
|
79
|
+
if (this.constructor._needsShadowDOM()) {
|
|
80
|
+
this.attachShadow({ mode: "open" });
|
|
81
|
+
}
|
|
57
82
|
}
|
|
58
83
|
|
|
59
84
|
/**
|
|
60
|
-
*
|
|
85
|
+
* Returns a unique ID for this UI5 Element
|
|
86
|
+
*
|
|
87
|
+
* @deprecated - This property is not guaranteed in future releases
|
|
88
|
+
* @protected
|
|
61
89
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.attachShadow({ mode: "open" });
|
|
66
|
-
|
|
67
|
-
// IE11, Edge
|
|
68
|
-
if (window.ShadyDOM) {
|
|
69
|
-
createHeadStyle(this.constructor);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Chrome
|
|
73
|
-
if (document.adoptedStyleSheets) {
|
|
74
|
-
const style = getConstructableStyle(this.constructor);
|
|
75
|
-
this.shadowRoot.adoptedStyleSheets = [style];
|
|
76
|
-
}
|
|
90
|
+
get _id() {
|
|
91
|
+
if (!this.__id) {
|
|
92
|
+
this.__id = `ui5wc_${++autoId}`;
|
|
77
93
|
}
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
if (this.constructor._needsStaticArea()) {
|
|
81
|
-
this.staticAreaItem = new StaticAreaItem(this);
|
|
82
|
-
}
|
|
95
|
+
return this.__id;
|
|
83
96
|
}
|
|
84
97
|
|
|
85
98
|
/**
|
|
@@ -87,22 +100,27 @@ class UI5Element extends HTMLElement {
|
|
|
87
100
|
* @private
|
|
88
101
|
*/
|
|
89
102
|
async connectedCallback() {
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
this.setAttribute(this.constructor.getMetadata().getPureTag(), "");
|
|
104
|
+
|
|
105
|
+
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
106
|
+
|
|
107
|
+
this._inDOM = true;
|
|
108
|
+
|
|
109
|
+
if (slotsAreManaged) {
|
|
92
110
|
// always register the observer before yielding control to the main thread (await)
|
|
93
111
|
this._startObservingDOMChildren();
|
|
94
|
-
|
|
95
112
|
await this._processChildren();
|
|
96
|
-
await RenderScheduler.renderImmediately(this);
|
|
97
|
-
this._domRefReadyPromise._deferredResolve();
|
|
98
|
-
if (typeof this.onEnterDOM === "function") {
|
|
99
|
-
this.onEnterDOM();
|
|
100
|
-
}
|
|
101
113
|
}
|
|
102
114
|
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
if (!this._inDOM) { // Component removed from DOM while _processChildren was running
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
renderImmediately(this);
|
|
120
|
+
this._domRefReadyPromise._deferredResolve();
|
|
121
|
+
this._fullyConnected = true;
|
|
122
|
+
if (typeof this.onEnterDOM === "function") {
|
|
123
|
+
this.onEnterDOM();
|
|
106
124
|
}
|
|
107
125
|
}
|
|
108
126
|
|
|
@@ -111,16 +129,26 @@ class UI5Element extends HTMLElement {
|
|
|
111
129
|
* @private
|
|
112
130
|
*/
|
|
113
131
|
disconnectedCallback() {
|
|
114
|
-
|
|
132
|
+
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
133
|
+
|
|
134
|
+
this._inDOM = false;
|
|
135
|
+
|
|
136
|
+
if (slotsAreManaged) {
|
|
115
137
|
this._stopObservingDOMChildren();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (this._fullyConnected) {
|
|
116
141
|
if (typeof this.onExitDOM === "function") {
|
|
117
142
|
this.onExitDOM();
|
|
118
143
|
}
|
|
144
|
+
this._fullyConnected = false;
|
|
119
145
|
}
|
|
120
146
|
|
|
121
|
-
if (this.
|
|
122
|
-
this.staticAreaItem.
|
|
147
|
+
if (this.staticAreaItem && this.staticAreaItem.parentElement) {
|
|
148
|
+
this.staticAreaItem.parentElement.removeChild(this.staticAreaItem);
|
|
123
149
|
}
|
|
150
|
+
|
|
151
|
+
cancelRender(this);
|
|
124
152
|
}
|
|
125
153
|
|
|
126
154
|
/**
|
|
@@ -131,19 +159,21 @@ class UI5Element extends HTMLElement {
|
|
|
131
159
|
if (!shouldObserveChildren) {
|
|
132
160
|
return;
|
|
133
161
|
}
|
|
162
|
+
|
|
163
|
+
const canSlotText = this.constructor.getMetadata().canSlotText();
|
|
134
164
|
const mutationObserverOptions = {
|
|
135
165
|
childList: true,
|
|
136
|
-
subtree:
|
|
137
|
-
characterData:
|
|
166
|
+
subtree: canSlotText,
|
|
167
|
+
characterData: canSlotText,
|
|
138
168
|
};
|
|
139
|
-
|
|
169
|
+
observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions);
|
|
140
170
|
}
|
|
141
171
|
|
|
142
172
|
/**
|
|
143
173
|
* @private
|
|
144
174
|
*/
|
|
145
175
|
_stopObservingDOMChildren() {
|
|
146
|
-
|
|
176
|
+
unobserveDOMNode(this);
|
|
147
177
|
}
|
|
148
178
|
|
|
149
179
|
/**
|
|
@@ -162,12 +192,18 @@ class UI5Element extends HTMLElement {
|
|
|
162
192
|
*/
|
|
163
193
|
async _updateSlots() {
|
|
164
194
|
const slotsMap = this.constructor.getMetadata().getSlots();
|
|
165
|
-
const canSlotText =
|
|
195
|
+
const canSlotText = this.constructor.getMetadata().canSlotText();
|
|
166
196
|
const domChildren = Array.from(canSlotText ? this.childNodes : this.children);
|
|
167
197
|
|
|
168
|
-
//
|
|
198
|
+
const slotsCachedContentMap = new Map(); // Store here the content of each slot before the mutation occurred
|
|
199
|
+
const propertyNameToSlotMap = new Map(); // Used for reverse lookup to determine to which slot the property name corresponds
|
|
200
|
+
|
|
201
|
+
// Init the _state object based on the supported slots and store the previous values
|
|
169
202
|
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
170
|
-
|
|
203
|
+
const propertyName = slotData.propertyName || slotName;
|
|
204
|
+
propertyNameToSlotMap.set(propertyName, slotName);
|
|
205
|
+
slotsCachedContentMap.set(propertyName, [...this._state[propertyName]]);
|
|
206
|
+
this._clearSlot(slotName, slotData);
|
|
171
207
|
}
|
|
172
208
|
|
|
173
209
|
const autoIncrementMap = new Map();
|
|
@@ -175,7 +211,7 @@ class UI5Element extends HTMLElement {
|
|
|
175
211
|
|
|
176
212
|
const allChildrenUpgraded = domChildren.map(async (child, idx) => {
|
|
177
213
|
// Determine the type of the child (mainly by the slot attribute)
|
|
178
|
-
const slotName =
|
|
214
|
+
const slotName = getSlotName(child);
|
|
179
215
|
const slotData = slotsMap[slotName];
|
|
180
216
|
|
|
181
217
|
// Check if the slotName is supported
|
|
@@ -187,9 +223,9 @@ class UI5Element extends HTMLElement {
|
|
|
187
223
|
|
|
188
224
|
// For children that need individual slots, calculate them
|
|
189
225
|
if (slotData.individualSlots) {
|
|
190
|
-
const
|
|
191
|
-
autoIncrementMap.set(slotName,
|
|
192
|
-
child._individualSlot = `${slotName}-${
|
|
226
|
+
const nextIndex = (autoIncrementMap.get(slotName) || 0) + 1;
|
|
227
|
+
autoIncrementMap.set(slotName, nextIndex);
|
|
228
|
+
child._individualSlot = `${slotName}-${nextIndex}`;
|
|
193
229
|
}
|
|
194
230
|
|
|
195
231
|
// Await for not-yet-defined custom elements
|
|
@@ -213,8 +249,14 @@ class UI5Element extends HTMLElement {
|
|
|
213
249
|
|
|
214
250
|
child = this.constructor.getMetadata().constructor.validateSlotValue(child, slotData);
|
|
215
251
|
|
|
216
|
-
if (
|
|
217
|
-
|
|
252
|
+
// Listen for any invalidation on the child if invalidateOnChildChange is true or an object (ignore when false or not set)
|
|
253
|
+
if (child.isUI5Element && slotData.invalidateOnChildChange) {
|
|
254
|
+
child.attachInvalidate(this._getChildChangeListener(slotName));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Listen for the slotchange event if the child is a slot itself
|
|
258
|
+
if (isSlot(child)) {
|
|
259
|
+
this._attachSlotChange(child, slotName);
|
|
218
260
|
}
|
|
219
261
|
|
|
220
262
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -230,33 +272,96 @@ class UI5Element extends HTMLElement {
|
|
|
230
272
|
|
|
231
273
|
// Distribute the child in the _state object, keeping the Light DOM order,
|
|
232
274
|
// not the order elements are defined.
|
|
233
|
-
slottedChildrenMap.forEach((children,
|
|
234
|
-
this._state[
|
|
275
|
+
slottedChildrenMap.forEach((children, propertyName) => {
|
|
276
|
+
this._state[propertyName] = children.sort((a, b) => a.idx - b.idx).map(_ => _.child);
|
|
235
277
|
});
|
|
236
|
-
|
|
278
|
+
|
|
279
|
+
// Compare the content of each slot with the cached values and invalidate for the ones that changed
|
|
280
|
+
let invalidated = false;
|
|
281
|
+
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
282
|
+
const propertyName = slotData.propertyName || slotName;
|
|
283
|
+
if (!arraysAreEqual(slotsCachedContentMap.get(propertyName), this._state[propertyName])) {
|
|
284
|
+
_invalidate.call(this, {
|
|
285
|
+
type: "slot",
|
|
286
|
+
name: propertyNameToSlotMap.get(propertyName),
|
|
287
|
+
reason: "children",
|
|
288
|
+
});
|
|
289
|
+
invalidated = true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// If none of the slots had an invalidation due to changes to immediate children,
|
|
294
|
+
// the change is considered to be text content of the default slot
|
|
295
|
+
if (!invalidated) {
|
|
296
|
+
_invalidate.call(this, {
|
|
297
|
+
type: "slot",
|
|
298
|
+
name: "default",
|
|
299
|
+
reason: "textcontent",
|
|
300
|
+
});
|
|
301
|
+
}
|
|
237
302
|
}
|
|
238
303
|
|
|
239
304
|
/**
|
|
240
305
|
* Removes all children from the slot and detaches listeners, if any
|
|
241
306
|
* @private
|
|
242
307
|
*/
|
|
243
|
-
_clearSlot(slotName) {
|
|
244
|
-
const slotData = this.constructor.getMetadata().getSlots()[slotName];
|
|
308
|
+
_clearSlot(slotName, slotData) {
|
|
245
309
|
const propertyName = slotData.propertyName || slotName;
|
|
246
|
-
|
|
247
|
-
let children = this._state[propertyName];
|
|
248
|
-
if (!Array.isArray(children)) {
|
|
249
|
-
children = [children];
|
|
250
|
-
}
|
|
310
|
+
const children = this._state[propertyName];
|
|
251
311
|
|
|
252
312
|
children.forEach(child => {
|
|
253
313
|
if (child && child.isUI5Element) {
|
|
254
|
-
this.
|
|
314
|
+
child.detachInvalidate(this._getChildChangeListener(slotName));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (isSlot(child)) {
|
|
318
|
+
this._detachSlotChange(child, slotName);
|
|
255
319
|
}
|
|
256
320
|
});
|
|
257
321
|
|
|
258
322
|
this._state[propertyName] = [];
|
|
259
|
-
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Attach a callback that will be executed whenever the component is invalidated
|
|
327
|
+
*
|
|
328
|
+
* @param callback
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
331
|
+
attachInvalidate(callback) {
|
|
332
|
+
this._eventProvider.attachEvent("invalidate", callback);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Detach the callback that is executed whenever the component is invalidated
|
|
337
|
+
*
|
|
338
|
+
* @param callback
|
|
339
|
+
* @public
|
|
340
|
+
*/
|
|
341
|
+
detachInvalidate(callback) {
|
|
342
|
+
this._eventProvider.detachEvent("invalidate", callback);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Callback that is executed whenever a monitored child changes its state
|
|
347
|
+
*
|
|
348
|
+
* @param slotName the slot in which a child was invalidated
|
|
349
|
+
* @param childChangeInfo the changeInfo object for the child in the given slot
|
|
350
|
+
* @private
|
|
351
|
+
*/
|
|
352
|
+
_onChildChange(slotName, childChangeInfo) {
|
|
353
|
+
if (!this.constructor.getMetadata().shouldInvalidateOnChildChange(slotName, childChangeInfo.type, childChangeInfo.name)) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// The component should be invalidated as this type of change on the child is listened for
|
|
358
|
+
// However, no matter what changed on the child (property/slot), the invalidation is registered as "type=slot" for the component itself
|
|
359
|
+
_invalidate.call(this, {
|
|
360
|
+
type: "slot",
|
|
361
|
+
name: slotName,
|
|
362
|
+
reason: "childchange",
|
|
363
|
+
child: childChangeInfo.target,
|
|
364
|
+
});
|
|
260
365
|
}
|
|
261
366
|
|
|
262
367
|
/**
|
|
@@ -271,9 +376,8 @@ class UI5Element extends HTMLElement {
|
|
|
271
376
|
const propertyTypeClass = properties[nameInCamelCase].type;
|
|
272
377
|
if (propertyTypeClass === Boolean) {
|
|
273
378
|
newValue = newValue !== null;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
newValue = parseInt(newValue);
|
|
379
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
380
|
+
newValue = propertyTypeClass.attributeToProperty(newValue);
|
|
277
381
|
}
|
|
278
382
|
this[nameInCamelCase] = newValue;
|
|
279
383
|
}
|
|
@@ -286,22 +390,24 @@ class UI5Element extends HTMLElement {
|
|
|
286
390
|
if (!this.constructor.getMetadata().hasAttribute(name)) {
|
|
287
391
|
return;
|
|
288
392
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
|
|
393
|
+
const properties = this.constructor.getMetadata().getProperties();
|
|
394
|
+
const propertyTypeClass = properties[name].type;
|
|
294
395
|
const attrName = camelToKebabCase(name);
|
|
295
396
|
const attrValue = this.getAttribute(attrName);
|
|
296
|
-
|
|
397
|
+
|
|
398
|
+
if (propertyTypeClass === Boolean) {
|
|
297
399
|
if (newValue === true && attrValue === null) {
|
|
298
400
|
this.setAttribute(attrName, "");
|
|
299
401
|
} else if (newValue === false && attrValue !== null) {
|
|
300
402
|
this.removeAttribute(attrName);
|
|
301
403
|
}
|
|
302
|
-
} else if (
|
|
303
|
-
this.setAttribute(attrName, newValue);
|
|
304
|
-
}
|
|
404
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
405
|
+
this.setAttribute(attrName, propertyTypeClass.propertyToAttribute(newValue));
|
|
406
|
+
} else if (typeof newValue !== "object") {
|
|
407
|
+
if (attrValue !== newValue) {
|
|
408
|
+
this.setAttribute(attrName, newValue);
|
|
409
|
+
}
|
|
410
|
+
} // else { return; } // old object handling
|
|
305
411
|
}
|
|
306
412
|
|
|
307
413
|
/**
|
|
@@ -327,107 +433,101 @@ class UI5Element extends HTMLElement {
|
|
|
327
433
|
* @private
|
|
328
434
|
*/
|
|
329
435
|
_initializeState() {
|
|
330
|
-
|
|
331
|
-
this._state = Object.assign({}, defaultState);
|
|
436
|
+
this._state = { ...this.constructor.getMetadata().getInitialState() };
|
|
332
437
|
}
|
|
333
438
|
|
|
334
439
|
/**
|
|
440
|
+
* Returns a singleton event listener for the "change" event of a child in a given slot
|
|
441
|
+
*
|
|
442
|
+
* @param slotName the name of the slot, where the child is
|
|
443
|
+
* @returns {any}
|
|
335
444
|
* @private
|
|
336
445
|
*/
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
slotName = this.constructor._getSlotName(child), // all slotted children have the same configuration
|
|
341
|
-
childProperties = childMetadata.getProperties();
|
|
342
|
-
|
|
343
|
-
let observedProps = [],
|
|
344
|
-
notObservedProps = [];
|
|
345
|
-
|
|
346
|
-
if (!listenFor) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (Array.isArray(listenFor)) {
|
|
351
|
-
observedProps = listenFor;
|
|
352
|
-
} else {
|
|
353
|
-
observedProps = Array.isArray(listenFor.props) ? listenFor.props : Object.keys(childProperties);
|
|
354
|
-
notObservedProps = Array.isArray(listenFor.exclude) ? listenFor.exclude : [];
|
|
446
|
+
_getChildChangeListener(slotName) {
|
|
447
|
+
if (!this._childChangeListeners.has(slotName)) {
|
|
448
|
+
this._childChangeListeners.set(slotName, this._onChildChange.bind(this, slotName));
|
|
355
449
|
}
|
|
356
|
-
|
|
357
|
-
if (!this._monitoredChildProps.has(slotName)) {
|
|
358
|
-
this._monitoredChildProps.set(slotName, { observedProps, notObservedProps });
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
child.addEventListener("_propertyChange", this._invalidateParentOnPropertyUpdate);
|
|
450
|
+
return this._childChangeListeners.get(slotName);
|
|
362
451
|
}
|
|
363
452
|
|
|
364
453
|
/**
|
|
454
|
+
* Returns a singleton slotchange event listener that invalidates the component due to changes in the given slot
|
|
455
|
+
*
|
|
456
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
457
|
+
* @returns {any}
|
|
365
458
|
* @private
|
|
366
459
|
*/
|
|
367
|
-
|
|
368
|
-
|
|
460
|
+
_getSlotChangeListener(slotName) {
|
|
461
|
+
if (!this._slotChangeListeners.has(slotName)) {
|
|
462
|
+
this._slotChangeListeners.set(slotName, this._onSlotChange.bind(this, slotName));
|
|
463
|
+
}
|
|
464
|
+
return this._slotChangeListeners.get(slotName);
|
|
369
465
|
}
|
|
370
466
|
|
|
371
467
|
/**
|
|
372
468
|
* @private
|
|
373
469
|
*/
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const customEvent = new CustomEvent("_propertyChange", {
|
|
378
|
-
detail: { name, newValue: value },
|
|
379
|
-
composed: false,
|
|
380
|
-
bubbles: true,
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
this.dispatchEvent(customEvent);
|
|
470
|
+
_attachSlotChange(child, slotName) {
|
|
471
|
+
child.addEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
384
472
|
}
|
|
385
473
|
|
|
386
474
|
/**
|
|
387
475
|
* @private
|
|
388
476
|
*/
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const parentNode = this.parentNode;
|
|
392
|
-
if (!parentNode) {
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const slotName = parentNode.constructor._getSlotName(this);
|
|
397
|
-
const propsMetadata = parentNode._monitoredChildProps.get(slotName);
|
|
398
|
-
|
|
399
|
-
if (!propsMetadata) {
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
const { observedProps, notObservedProps } = propsMetadata;
|
|
403
|
-
|
|
404
|
-
if (observedProps.includes(prop.detail.name) && !notObservedProps.includes(prop.detail.name)) {
|
|
405
|
-
parentNode._invalidate("_parent_", this);
|
|
406
|
-
}
|
|
477
|
+
_detachSlotChange(child, slotName) {
|
|
478
|
+
child.removeEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
407
479
|
}
|
|
408
480
|
|
|
409
481
|
/**
|
|
410
|
-
*
|
|
482
|
+
* Whenever a slot element is slotted inside a UI5 Web Component, its slotchange event invalidates the component
|
|
483
|
+
*
|
|
484
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
411
485
|
* @private
|
|
412
486
|
*/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (this.getDomRef() && !this._suppressInvalidation) {
|
|
420
|
-
this._invalidated = true;
|
|
421
|
-
// console.log("INVAL", this, ...arguments);
|
|
422
|
-
RenderScheduler.renderDeferred(this);
|
|
423
|
-
}
|
|
487
|
+
_onSlotChange(slotName) {
|
|
488
|
+
_invalidate.call(this, {
|
|
489
|
+
type: "slot",
|
|
490
|
+
name: slotName,
|
|
491
|
+
reason: "slotchange",
|
|
492
|
+
});
|
|
424
493
|
}
|
|
425
494
|
|
|
426
495
|
/**
|
|
427
|
-
*
|
|
496
|
+
* A callback that is executed each time an already rendered component is invalidated (scheduled for re-rendering)
|
|
497
|
+
*
|
|
498
|
+
* @param changeInfo An object with information about the change that caused invalidation.
|
|
499
|
+
* The object can have the following properties:
|
|
500
|
+
* - type: (property|slot) tells what caused the invalidation
|
|
501
|
+
* 1) property: a property value was changed either directly or as a result of changing the corresponding attribute
|
|
502
|
+
* 2) slot: a slotted node(nodes) changed in one of several ways (see "reason")
|
|
503
|
+
*
|
|
504
|
+
* - name: the name of the property or slot that caused the invalidation
|
|
505
|
+
*
|
|
506
|
+
* - reason: (children|textcontent|childchange|slotchange) relevant only for type="slot" only and tells exactly what changed in the slot
|
|
507
|
+
* 1) children: immediate children (HTML elements or text nodes) were added, removed or reordered in the slot
|
|
508
|
+
* 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"
|
|
509
|
+
* 3) slotchange: a slot element, slotted inside that slot had its "slotchange" event listener called. This practically means that transitively slotted children changed.
|
|
510
|
+
* Can only trigger if the child of a slot is a slot element itself.
|
|
511
|
+
* 4) childchange: indicates that a UI5Element child in that slot was invalidated and in turn invalidated the component.
|
|
512
|
+
* Can only trigger for slots with "invalidateOnChildChange" metadata descriptor
|
|
513
|
+
*
|
|
514
|
+
* - newValue: the new value of the property (for type="property" only)
|
|
515
|
+
*
|
|
516
|
+
* - oldValue: the old value of the property (for type="property" only)
|
|
517
|
+
*
|
|
518
|
+
* - child the child that was changed (for type="slot" and reason="childchange" only)
|
|
519
|
+
*
|
|
520
|
+
* @public
|
|
521
|
+
*/
|
|
522
|
+
onInvalidation(changeInfo) {}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Do not call this method directly, only intended to be called by js
|
|
428
526
|
* @protected
|
|
429
527
|
*/
|
|
430
528
|
_render() {
|
|
529
|
+
const hasIndividualSlots = this.constructor.getMetadata().hasIndividualSlots();
|
|
530
|
+
|
|
431
531
|
// suppress invalidation to prevent state changes scheduling another rendering
|
|
432
532
|
this._suppressInvalidation = true;
|
|
433
533
|
|
|
@@ -441,19 +541,43 @@ class UI5Element extends HTMLElement {
|
|
|
441
541
|
}
|
|
442
542
|
|
|
443
543
|
// resume normal invalidation handling
|
|
444
|
-
|
|
544
|
+
this._suppressInvalidation = false;
|
|
445
545
|
|
|
446
546
|
// Update the shadow root with the render result
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
547
|
+
/*
|
|
548
|
+
if (this._changedState.length) {
|
|
549
|
+
let element = this.localName;
|
|
550
|
+
if (this.id) {
|
|
551
|
+
element = `${element}#${this.id}`;
|
|
552
|
+
}
|
|
553
|
+
console.log("Re-rendering:", element, this._changedState.map(x => { // eslint-disable-line
|
|
554
|
+
let res = `${x.type}`;
|
|
555
|
+
if (x.reason) {
|
|
556
|
+
res = `${res}(${x.reason})`;
|
|
557
|
+
}
|
|
558
|
+
res = `${res}: ${x.name}`;
|
|
559
|
+
if (x.type === "property") {
|
|
560
|
+
res = `${res} ${x.oldValue} => ${x.newValue}`;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return res;
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
*/
|
|
567
|
+
this._changedState = [];
|
|
450
568
|
|
|
451
|
-
|
|
452
|
-
|
|
569
|
+
// Update shadow root and static area item
|
|
570
|
+
if (this.constructor._needsShadowDOM()) {
|
|
571
|
+
updateShadowRoot(this);
|
|
572
|
+
}
|
|
573
|
+
if (this.staticAreaItem) {
|
|
574
|
+
this.staticAreaItem.update();
|
|
453
575
|
}
|
|
454
576
|
|
|
455
577
|
// Safari requires that children get the slot attribute only after the slot tags have been rendered in the shadow DOM
|
|
456
|
-
|
|
578
|
+
if (hasIndividualSlots) {
|
|
579
|
+
this._assignIndividualSlotsToChildren();
|
|
580
|
+
}
|
|
457
581
|
|
|
458
582
|
// Call the onAfterRendering hook
|
|
459
583
|
if (typeof this.onAfterRendering === "function") {
|
|
@@ -461,19 +585,6 @@ class UI5Element extends HTMLElement {
|
|
|
461
585
|
}
|
|
462
586
|
}
|
|
463
587
|
|
|
464
|
-
/**
|
|
465
|
-
* @private
|
|
466
|
-
*/
|
|
467
|
-
_updateShadowRoot() {
|
|
468
|
-
let styleToPrepend;
|
|
469
|
-
const renderResult = this.constructor.template(this);
|
|
470
|
-
|
|
471
|
-
if (!document.adoptedStyleSheets && !window.ShadyDOM) {
|
|
472
|
-
styleToPrepend = getEffectiveStyle(this.constructor);
|
|
473
|
-
}
|
|
474
|
-
this.constructor.render(renderResult, this.shadowRoot, styleToPrepend, { eventContext: this });
|
|
475
|
-
}
|
|
476
|
-
|
|
477
588
|
/**
|
|
478
589
|
* @private
|
|
479
590
|
*/
|
|
@@ -496,16 +607,27 @@ class UI5Element extends HTMLElement {
|
|
|
496
607
|
|
|
497
608
|
/**
|
|
498
609
|
* Returns the DOM Element inside the Shadow Root that corresponds to the opening tag in the UI5 Web Component's template
|
|
610
|
+
* *Note:* For logical (abstract) elements (items, options, etc...), returns the part of the parent's DOM that represents this option
|
|
499
611
|
* Use this method instead of "this.shadowRoot" to read the Shadow DOM, if ever necessary
|
|
612
|
+
*
|
|
500
613
|
* @public
|
|
501
614
|
*/
|
|
502
615
|
getDomRef() {
|
|
616
|
+
// If a component set _getRealDomRef to its children, use the return value of this function
|
|
617
|
+
if (typeof this._getRealDomRef === "function") {
|
|
618
|
+
return this._getRealDomRef();
|
|
619
|
+
}
|
|
620
|
+
|
|
503
621
|
if (!this.shadowRoot || this.shadowRoot.children.length === 0) {
|
|
504
622
|
return;
|
|
505
623
|
}
|
|
506
624
|
|
|
507
|
-
|
|
508
|
-
|
|
625
|
+
const children = [...this.shadowRoot.children].filter(child => !["link", "style"].includes(child.localName));
|
|
626
|
+
if (children.length !== 1) {
|
|
627
|
+
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
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return children[0];
|
|
509
631
|
}
|
|
510
632
|
|
|
511
633
|
/**
|
|
@@ -521,6 +643,16 @@ class UI5Element extends HTMLElement {
|
|
|
521
643
|
}
|
|
522
644
|
}
|
|
523
645
|
|
|
646
|
+
/**
|
|
647
|
+
* Waits for dom ref and then returns the DOM Element marked with "data-sap-focus-ref" inside the template.
|
|
648
|
+
* This is the element that will receive the focus by default.
|
|
649
|
+
* @public
|
|
650
|
+
*/
|
|
651
|
+
async getFocusDomRefAsync() {
|
|
652
|
+
await this._waitForDomRef();
|
|
653
|
+
return this.getFocusDomRef();
|
|
654
|
+
}
|
|
655
|
+
|
|
524
656
|
/**
|
|
525
657
|
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref")
|
|
526
658
|
* @public
|
|
@@ -541,37 +673,47 @@ class UI5Element extends HTMLElement {
|
|
|
541
673
|
* @param name - name of the event
|
|
542
674
|
* @param data - additional data for the event
|
|
543
675
|
* @param cancelable - true, if the user can call preventDefault on the event object
|
|
676
|
+
* @param bubbles - true, if the event bubbles
|
|
544
677
|
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise
|
|
545
678
|
*/
|
|
546
|
-
fireEvent(name, data, cancelable) {
|
|
547
|
-
|
|
679
|
+
fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
680
|
+
const eventResult = this._fireEvent(name, data, cancelable, bubbles);
|
|
681
|
+
const camelCaseEventName = kebabToCamelCase(name);
|
|
682
|
+
|
|
683
|
+
if (camelCaseEventName !== name) {
|
|
684
|
+
return eventResult && this._fireEvent(camelCaseEventName, data, cancelable);
|
|
685
|
+
}
|
|
548
686
|
|
|
687
|
+
return eventResult;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
_fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
549
691
|
const noConflictEvent = new CustomEvent(`ui5-${name}`, {
|
|
550
692
|
detail: data,
|
|
551
693
|
composed: false,
|
|
552
|
-
bubbles
|
|
694
|
+
bubbles,
|
|
553
695
|
cancelable,
|
|
554
696
|
});
|
|
555
697
|
|
|
556
|
-
// This will be false if the
|
|
557
|
-
|
|
698
|
+
// This will be false if the no-conflict event is prevented
|
|
699
|
+
const noConflictEventResult = this.dispatchEvent(noConflictEvent);
|
|
558
700
|
|
|
559
701
|
if (skipOriginalEvent(name)) {
|
|
560
|
-
return
|
|
702
|
+
return noConflictEventResult;
|
|
561
703
|
}
|
|
562
704
|
|
|
563
|
-
const
|
|
705
|
+
const normalEvent = new CustomEvent(name, {
|
|
564
706
|
detail: data,
|
|
565
707
|
composed: false,
|
|
566
|
-
bubbles
|
|
708
|
+
bubbles,
|
|
567
709
|
cancelable,
|
|
568
710
|
});
|
|
569
711
|
|
|
570
712
|
// This will be false if the normal event is prevented
|
|
571
|
-
const normalEventResult = this.dispatchEvent(
|
|
713
|
+
const normalEventResult = this.dispatchEvent(normalEvent);
|
|
572
714
|
|
|
573
715
|
// Return false if any of the two events was prevented (its result was false).
|
|
574
|
-
return normalEventResult &&
|
|
716
|
+
return normalEventResult && noConflictEventResult;
|
|
575
717
|
}
|
|
576
718
|
|
|
577
719
|
/**
|
|
@@ -580,14 +722,19 @@ class UI5Element extends HTMLElement {
|
|
|
580
722
|
* @public
|
|
581
723
|
*/
|
|
582
724
|
getSlottedNodes(slotName) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
return acc.concat([curr]);
|
|
586
|
-
}
|
|
587
|
-
return acc.concat(curr.assignedNodes({ flatten: true }).filter(item => item instanceof HTMLElement));
|
|
588
|
-
};
|
|
725
|
+
return getSlottedElementsList(this[slotName]);
|
|
726
|
+
}
|
|
589
727
|
|
|
590
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Determines whether the component should be rendered in RTL mode or not.
|
|
730
|
+
* Returns: "rtl", "ltr" or undefined
|
|
731
|
+
*
|
|
732
|
+
* @public
|
|
733
|
+
* @returns {String|undefined}
|
|
734
|
+
*/
|
|
735
|
+
get effectiveDir() {
|
|
736
|
+
markAsRtlAware(this.constructor); // if a UI5 Element calls this method, it's considered to be rtl-aware
|
|
737
|
+
return getEffectiveDir(this);
|
|
591
738
|
}
|
|
592
739
|
|
|
593
740
|
/**
|
|
@@ -607,39 +754,6 @@ class UI5Element extends HTMLElement {
|
|
|
607
754
|
return this.getMetadata().getAttributesList();
|
|
608
755
|
}
|
|
609
756
|
|
|
610
|
-
/**
|
|
611
|
-
* Used to generate the next auto-increment id for the current class
|
|
612
|
-
* @returns {string}
|
|
613
|
-
* @private
|
|
614
|
-
*/
|
|
615
|
-
static _nextID() {
|
|
616
|
-
const className = kebabToCamelCase(this.getMetadata().getTag());
|
|
617
|
-
const lastNumber = IDMap.get(className);
|
|
618
|
-
const nextNumber = lastNumber !== undefined ? lastNumber + 1 : 1;
|
|
619
|
-
IDMap.set(className, nextNumber);
|
|
620
|
-
return `__${className}${nextNumber}`;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* @private
|
|
625
|
-
*/
|
|
626
|
-
static _getSlotName(child) {
|
|
627
|
-
// Text nodes can only go to the default slot
|
|
628
|
-
if (!(child instanceof HTMLElement)) {
|
|
629
|
-
return "default";
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Discover the slot based on the real slot name (f.e. footer => footer, or content-32 => content)
|
|
633
|
-
const slot = child.getAttribute("slot");
|
|
634
|
-
if (slot) {
|
|
635
|
-
const match = slot.match(/^(.+?)-\d+$/);
|
|
636
|
-
return match ? match[1] : slot;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Use default slot as a fallback
|
|
640
|
-
return "default";
|
|
641
|
-
}
|
|
642
|
-
|
|
643
757
|
/**
|
|
644
758
|
* @private
|
|
645
759
|
*/
|
|
@@ -651,59 +765,26 @@ class UI5Element extends HTMLElement {
|
|
|
651
765
|
* @private
|
|
652
766
|
*/
|
|
653
767
|
static _needsStaticArea() {
|
|
654
|
-
return
|
|
768
|
+
return !!this.staticAreaTemplate;
|
|
655
769
|
}
|
|
656
770
|
|
|
657
771
|
/**
|
|
658
772
|
* @public
|
|
659
773
|
*/
|
|
660
774
|
getStaticAreaItemDomRef() {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
/**
|
|
665
|
-
* @private
|
|
666
|
-
*/
|
|
667
|
-
static _getDefaultState() {
|
|
668
|
-
if (this._defaultState) {
|
|
669
|
-
return this._defaultState;
|
|
775
|
+
if (!this.constructor._needsStaticArea()) {
|
|
776
|
+
throw new Error("This component does not use the static area");
|
|
670
777
|
}
|
|
671
778
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
// Initialize properties
|
|
676
|
-
const props = MetadataClass.getProperties();
|
|
677
|
-
for (const propName in props) { // eslint-disable-line
|
|
678
|
-
const propType = props[propName].type;
|
|
679
|
-
const propDefaultValue = props[propName].defaultValue;
|
|
680
|
-
|
|
681
|
-
if (propType === Boolean) {
|
|
682
|
-
defaultState[propName] = false;
|
|
683
|
-
|
|
684
|
-
if (propDefaultValue !== undefined) {
|
|
685
|
-
console.warn("The 'defaultValue' metadata key is ignored for all booleans properties, they would be initialized with 'false' by default"); // eslint-disable-line
|
|
686
|
-
}
|
|
687
|
-
} else if (props[propName].multiple) {
|
|
688
|
-
defaultState[propName] = [];
|
|
689
|
-
} else if (propType === Object) {
|
|
690
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : {};
|
|
691
|
-
} else if (propType === String) {
|
|
692
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : "";
|
|
693
|
-
} else {
|
|
694
|
-
defaultState[propName] = propDefaultValue;
|
|
695
|
-
}
|
|
779
|
+
if (!this.staticAreaItem) {
|
|
780
|
+
this.staticAreaItem = StaticAreaItem.createInstance();
|
|
781
|
+
this.staticAreaItem.setOwnerElement(this);
|
|
696
782
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const slots = MetadataClass.getSlots();
|
|
700
|
-
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
701
|
-
const propertyName = slotData.propertyName || slotName;
|
|
702
|
-
defaultState[propertyName] = [];
|
|
783
|
+
if (!this.staticAreaItem.parentElement) {
|
|
784
|
+
getSingletonElementInstance("ui5-static-area").appendChild(this.staticAreaItem);
|
|
703
785
|
}
|
|
704
786
|
|
|
705
|
-
this.
|
|
706
|
-
return defaultState;
|
|
787
|
+
return this.staticAreaItem.getDomRef();
|
|
707
788
|
}
|
|
708
789
|
|
|
709
790
|
/**
|
|
@@ -711,18 +792,31 @@ class UI5Element extends HTMLElement {
|
|
|
711
792
|
*/
|
|
712
793
|
static _generateAccessors() {
|
|
713
794
|
const proto = this.prototype;
|
|
795
|
+
const slotsAreManaged = this.getMetadata().slotsAreManaged();
|
|
714
796
|
|
|
715
797
|
// Properties
|
|
716
798
|
const properties = this.getMetadata().getProperties();
|
|
717
799
|
for (const [prop, propData] of Object.entries(properties)) { // eslint-disable-line
|
|
718
800
|
if (!isValidPropertyName(prop)) {
|
|
719
|
-
|
|
801
|
+
console.warn(`"${prop}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
720
802
|
}
|
|
721
803
|
|
|
722
|
-
if (propData.type ===
|
|
804
|
+
if (propData.type === Boolean && propData.defaultValue) {
|
|
723
805
|
throw new Error(`Cannot set a default value for property "${prop}". All booleans are false by default.`);
|
|
724
806
|
}
|
|
725
807
|
|
|
808
|
+
if (propData.type === Array) {
|
|
809
|
+
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...`);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if (propData.type === Object && propData.defaultValue) {
|
|
813
|
+
throw new Error(`Cannot set a default value for property "${prop}". All properties of type "Object" are empty objects by default.`);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (propData.multiple && propData.defaultValue) {
|
|
817
|
+
throw new Error(`Cannot set a default value for property "${prop}". All multiple properties are empty arrays by default.`);
|
|
818
|
+
}
|
|
819
|
+
|
|
726
820
|
Object.defineProperty(proto, prop, {
|
|
727
821
|
get() {
|
|
728
822
|
if (this._state[prop] !== undefined) {
|
|
@@ -742,38 +836,53 @@ class UI5Element extends HTMLElement {
|
|
|
742
836
|
}
|
|
743
837
|
},
|
|
744
838
|
set(value) {
|
|
839
|
+
let isDifferent;
|
|
745
840
|
value = this.constructor.getMetadata().constructor.validatePropertyValue(value, propData);
|
|
746
841
|
|
|
747
842
|
const oldState = this._state[prop];
|
|
843
|
+
if (propData.multiple && propData.compareValues) {
|
|
844
|
+
isDifferent = !arraysAreEqual(oldState, value);
|
|
845
|
+
} else if (isDescendantOf(propData.type, DataType)) {
|
|
846
|
+
isDifferent = !propData.type.valuesAreEqual(oldState, value);
|
|
847
|
+
} else {
|
|
848
|
+
isDifferent = oldState !== value;
|
|
849
|
+
}
|
|
748
850
|
|
|
749
|
-
if (
|
|
851
|
+
if (isDifferent) {
|
|
750
852
|
this._state[prop] = value;
|
|
751
|
-
|
|
752
|
-
|
|
853
|
+
_invalidate.call(this, {
|
|
854
|
+
type: "property",
|
|
855
|
+
name: prop,
|
|
856
|
+
newValue: value,
|
|
857
|
+
oldValue: oldState,
|
|
858
|
+
});
|
|
859
|
+
this._updateAttribute(prop, value);
|
|
753
860
|
}
|
|
754
861
|
},
|
|
755
862
|
});
|
|
756
863
|
}
|
|
757
864
|
|
|
758
865
|
// Slots
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
866
|
+
if (slotsAreManaged) {
|
|
867
|
+
const slots = this.getMetadata().getSlots();
|
|
868
|
+
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
869
|
+
if (!isValidPropertyName(slotName)) {
|
|
870
|
+
console.warn(`"${slotName}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
871
|
+
}
|
|
764
872
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
873
|
+
const propertyName = slotData.propertyName || slotName;
|
|
874
|
+
Object.defineProperty(proto, propertyName, {
|
|
875
|
+
get() {
|
|
876
|
+
if (this._state[propertyName] !== undefined) {
|
|
877
|
+
return this._state[propertyName];
|
|
878
|
+
}
|
|
879
|
+
return [];
|
|
880
|
+
},
|
|
881
|
+
set() {
|
|
882
|
+
throw new Error("Cannot set slot content directly, use the DOM APIs (appendChild, removeChild, etc...)");
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
}
|
|
777
886
|
}
|
|
778
887
|
}
|
|
779
888
|
|
|
@@ -782,7 +891,7 @@ class UI5Element extends HTMLElement {
|
|
|
782
891
|
* @protected
|
|
783
892
|
*/
|
|
784
893
|
static get metadata() {
|
|
785
|
-
return
|
|
894
|
+
return {};
|
|
786
895
|
}
|
|
787
896
|
|
|
788
897
|
/**
|
|
@@ -793,6 +902,58 @@ class UI5Element extends HTMLElement {
|
|
|
793
902
|
return "";
|
|
794
903
|
}
|
|
795
904
|
|
|
905
|
+
/**
|
|
906
|
+
* Returns the Static Area CSS for this UI5 Web Component Class
|
|
907
|
+
* @protected
|
|
908
|
+
*/
|
|
909
|
+
static get staticAreaStyles() {
|
|
910
|
+
return "";
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Returns an array with the dependencies for this UI5 Web Component, which could be:
|
|
915
|
+
* - composed components (used in its shadow root or static area item)
|
|
916
|
+
* - slotted components that the component may need to communicate with
|
|
917
|
+
*
|
|
918
|
+
* @protected
|
|
919
|
+
*/
|
|
920
|
+
static get dependencies() {
|
|
921
|
+
return [];
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Returns a list of the unique dependencies for this UI5 Web Component
|
|
926
|
+
*
|
|
927
|
+
* @public
|
|
928
|
+
*/
|
|
929
|
+
static getUniqueDependencies() {
|
|
930
|
+
if (!uniqueDependenciesCache.has(this)) {
|
|
931
|
+
const filtered = this.dependencies.filter((dep, index, deps) => deps.indexOf(dep) === index);
|
|
932
|
+
uniqueDependenciesCache.set(this, filtered);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return uniqueDependenciesCache.get(this);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Returns a promise that resolves whenever all dependencies for this UI5 Web Component have resolved
|
|
940
|
+
*
|
|
941
|
+
* @returns {Promise<any[]>}
|
|
942
|
+
*/
|
|
943
|
+
static whenDependenciesDefined() {
|
|
944
|
+
return Promise.all(this.getUniqueDependencies().map(dep => dep.define()));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Hook that will be called upon custom element definition
|
|
949
|
+
*
|
|
950
|
+
* @protected
|
|
951
|
+
* @returns {Promise<void>}
|
|
952
|
+
*/
|
|
953
|
+
static async onDefine() {
|
|
954
|
+
return Promise.resolve();
|
|
955
|
+
}
|
|
956
|
+
|
|
796
957
|
/**
|
|
797
958
|
* Registers a UI5 Web Component in the browser window object
|
|
798
959
|
* @public
|
|
@@ -800,17 +961,32 @@ class UI5Element extends HTMLElement {
|
|
|
800
961
|
*/
|
|
801
962
|
static async define() {
|
|
802
963
|
await boot();
|
|
964
|
+
|
|
965
|
+
await Promise.all([
|
|
966
|
+
this.whenDependenciesDefined(),
|
|
967
|
+
this.onDefine(),
|
|
968
|
+
]);
|
|
969
|
+
|
|
803
970
|
const tag = this.getMetadata().getTag();
|
|
971
|
+
const altTag = this.getMetadata().getAltTag();
|
|
804
972
|
|
|
805
|
-
const definedLocally =
|
|
973
|
+
const definedLocally = isTagRegistered(tag);
|
|
806
974
|
const definedGlobally = customElements.get(tag);
|
|
807
975
|
|
|
808
976
|
if (definedGlobally && !definedLocally) {
|
|
809
|
-
|
|
977
|
+
recordTagRegistrationFailure(tag);
|
|
810
978
|
} else if (!definedGlobally) {
|
|
811
979
|
this._generateAccessors();
|
|
812
|
-
|
|
980
|
+
registerTag(tag);
|
|
813
981
|
window.customElements.define(tag, this);
|
|
982
|
+
preloadLinks(this);
|
|
983
|
+
|
|
984
|
+
if (altTag && !customElements.get(altTag)) {
|
|
985
|
+
registerTag(altTag);
|
|
986
|
+
window.customElements.define(altTag, getClassCopy(this, () => {
|
|
987
|
+
console.log(`The ${altTag} tag is deprecated and will be removed in the next release, please use ${tag} instead.`); // eslint-disable-line
|
|
988
|
+
}));
|
|
989
|
+
}
|
|
814
990
|
}
|
|
815
991
|
return this;
|
|
816
992
|
}
|