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