@ui5/webcomponents-base 0.0.0-185851a98 → 0.0.0-1929d08ff

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.
Files changed (345) hide show
  1. package/.eslintignore +4 -0
  2. package/CHANGELOG.md +255 -0
  3. package/README.md +26 -2
  4. package/bundle.esm.js +16 -7
  5. package/dist/AssetRegistry.js +8 -6
  6. package/dist/Boot.js +59 -0
  7. package/dist/CSP.js +59 -0
  8. package/dist/CustomElementsRegistry.js +95 -0
  9. package/dist/CustomElementsScope.js +108 -0
  10. package/dist/DOMObserver.js +65 -0
  11. package/dist/Device.js +69 -776
  12. package/dist/EventProvider.js +38 -26
  13. package/dist/FeaturesRegistry.js +4 -1
  14. package/dist/FontFace.js +19 -62
  15. package/dist/InitialConfiguration.js +43 -8
  16. package/dist/Keys.js +121 -2
  17. package/dist/ManagedStyles.js +83 -0
  18. package/dist/MediaRange.js +109 -0
  19. package/dist/PropertiesFileFormat.js +95 -0
  20. package/dist/Render.js +175 -0
  21. package/dist/RenderQueue.js +41 -17
  22. package/dist/RenderScheduler.js +24 -145
  23. package/dist/Runtimes.js +107 -0
  24. package/dist/StaticArea.js +1 -39
  25. package/dist/StaticAreaItem.js +58 -62
  26. package/dist/SystemCSSVars.js +10 -0
  27. package/dist/Theming.js +2 -5
  28. package/dist/UI5Element.js +428 -303
  29. package/dist/UI5ElementMetadata.js +173 -19
  30. package/dist/asset-registries/Icons.js +129 -14
  31. package/dist/asset-registries/Illustrations.js +30 -0
  32. package/dist/asset-registries/LocaleData.js +100 -67
  33. package/dist/asset-registries/Themes.js +29 -33
  34. package/dist/asset-registries/i18n.js +72 -30
  35. package/dist/assets-meta/IconCollectionsAlias.js +18 -0
  36. package/dist/config/AnimationMode.js +11 -1
  37. package/dist/config/Language.js +58 -2
  38. package/dist/config/Theme.js +14 -0
  39. package/dist/css/FontFace.css +45 -0
  40. package/dist/css/OverrideFontFace.css +32 -0
  41. package/dist/css/SystemCSSVars.css +17 -0
  42. package/dist/delegate/ItemNavigation.js +244 -171
  43. package/dist/delegate/ResizeHandler.js +78 -38
  44. package/dist/delegate/ScrollEnablement.js +80 -21
  45. package/dist/features/F6Navigation.js +106 -0
  46. package/dist/features/OpenUI5Support.js +56 -7
  47. package/dist/generated/AssetParameters.js +1 -1
  48. package/dist/generated/VersionInfo.js +10 -0
  49. package/dist/generated/css/FontFace.css.js +5 -0
  50. package/dist/generated/css/OverrideFontFace.css.js +5 -0
  51. package/dist/generated/css/SystemCSSVars.css.js +5 -0
  52. package/dist/getSharedResource.js +30 -0
  53. package/dist/i18nBundle.js +58 -5
  54. package/dist/isLegacyBrowser.js +3 -0
  55. package/dist/locale/RTLAwareRegistry.js +14 -0
  56. package/dist/locale/applyDirection.js +17 -0
  57. package/dist/locale/directionChange.js +32 -0
  58. package/dist/locale/getEffectiveDir.js +28 -0
  59. package/dist/locale/getLocale.js +12 -2
  60. package/dist/locale/languageChange.js +22 -0
  61. package/dist/renderer/LitRenderer.js +26 -7
  62. package/dist/renderer/directives/style-map.js +72 -0
  63. package/dist/renderer/executeTemplate.js +17 -0
  64. package/dist/resources/bundle.esm.js +17 -109
  65. package/dist/resources/bundle.esm.js.map +1 -1
  66. package/dist/sap/base/Log.js +241 -0
  67. package/dist/sap/base/assert.js +8 -0
  68. package/dist/sap/base/security/URLListValidator.js +148 -0
  69. package/dist/sap/base/security/encodeCSS.js +14 -0
  70. package/dist/sap/base/security/encodeXML.js +23 -0
  71. package/dist/sap/base/security/sanitizeHTML.js +16 -0
  72. package/dist/sap/base/strings/toHex.js +8 -0
  73. package/dist/sap/base/util/now.js +7 -0
  74. package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +3585 -0
  75. package/dist/test-resources/assets/Themes.js +10 -6
  76. package/dist/test-resources/elements/Parent.js +6 -2
  77. package/dist/test-resources/elements/WithStaticArea.js +2 -1
  78. package/dist/test-resources/pages/AllTestElements.html +3 -3
  79. package/dist/test-resources/pages/Configuration.html +0 -2
  80. package/dist/test-resources/pages/ConfigurationScript.html +1 -3
  81. package/dist/test-resources/pages/assets/messagebundle_de.properties +1 -0
  82. package/dist/test-resources/pages/assets/messagebundle_en.properties +1 -0
  83. package/dist/test-resources/pages/assets/messagebundle_es.properties +1 -0
  84. package/dist/test-resources/pages/assets/messagebundle_fr.properties +1 -0
  85. package/dist/test-resources/pages/i18n.html +33 -0
  86. package/dist/test-resources/specs/ConfigurationChange.spec.js +11 -9
  87. package/dist/test-resources/specs/ConfigurationScript.spec.js +25 -23
  88. package/dist/test-resources/specs/ConfigurationURL.spec.js +65 -17
  89. package/dist/test-resources/specs/CustomTheme.spec.js +9 -7
  90. package/dist/test-resources/specs/EventProvider.spec.js +63 -0
  91. package/dist/test-resources/specs/StaticArea.spec.js +56 -12
  92. package/dist/test-resources/specs/Theming.spec.js +12 -10
  93. package/dist/test-resources/specs/UI5ElementInvalidation.js +54 -70
  94. package/dist/test-resources/specs/UI5ElementLifecycle.js +19 -14
  95. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +25 -51
  96. package/dist/test-resources/specs/UI5ElementMetadataExt.js +9 -7
  97. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +7 -5
  98. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +37 -35
  99. package/dist/test-resources/specs/UI5ElementShadowDOM.js +10 -8
  100. package/dist/test-resources/specs/UI5ElementSlots.js +10 -8
  101. package/dist/theming/CustomStyle.js +47 -6
  102. package/dist/theming/ThemeLoaded.js +22 -0
  103. package/dist/theming/applyTheme.js +69 -9
  104. package/dist/theming/getConstructableStyle.js +15 -10
  105. package/dist/theming/getEffectiveLinksHrefs.js +20 -0
  106. package/dist/theming/getEffectiveStyle.js +23 -8
  107. package/dist/theming/getStylesString.js +15 -0
  108. package/dist/theming/getThemeDesignerTheme.js +87 -0
  109. package/dist/theming/preloadLinks.js +23 -0
  110. package/dist/types/CSSColor.js +9 -0
  111. package/dist/types/CalendarType.js +1 -1
  112. package/dist/types/DataType.js +13 -1
  113. package/dist/types/Float.js +14 -0
  114. package/dist/types/Integer.js +4 -0
  115. package/dist/types/InvisibleMessageMode.js +30 -0
  116. package/dist/types/ItemNavigationBehavior.js +2 -7
  117. package/dist/types/NavigationMode.js +1 -0
  118. package/dist/types/PopupState.js +1 -1
  119. package/dist/types/ValueState.js +1 -1
  120. package/dist/updateShadowRoot.js +30 -0
  121. package/dist/util/AriaLabelHelper.js +41 -0
  122. package/dist/util/Caret.js +45 -0
  123. package/dist/util/ColorConversion.js +370 -0
  124. package/dist/util/FocusableElements.js +30 -11
  125. package/dist/util/HTMLSanitizer.js +7 -0
  126. package/dist/util/InvisibleMessage.js +60 -0
  127. package/dist/util/PopupUtils.js +93 -0
  128. package/dist/util/SlotsHelper.js +43 -0
  129. package/dist/util/TabbableElements.js +9 -1
  130. package/dist/util/arraysAreEqual.js +15 -0
  131. package/dist/util/clamp.js +12 -0
  132. package/dist/util/createLinkInHead.js +19 -0
  133. package/dist/util/debounce.js +17 -0
  134. package/dist/util/escapeRegex.js +10 -0
  135. package/dist/util/generateHighlightedMarkup.js +42 -0
  136. package/dist/util/getActiveElement.js +11 -0
  137. package/dist/util/getClassCopy.js +10 -0
  138. package/dist/util/getEffectiveContentDensity.js +5 -0
  139. package/dist/util/getSingletonElementInstance.js +13 -0
  140. package/dist/util/isElementInView.js +15 -0
  141. package/dist/util/isNodeHidden.js +1 -5
  142. package/dist/util/isNodeTabbable.js +4 -4
  143. package/dist/util/isValidPropertyName.js +11 -2
  144. package/dist/util/setToArray.js +10 -0
  145. package/hash.txt +1 -0
  146. package/index.js +1 -1
  147. package/lib/generate-asset-parameters/index.js +0 -1
  148. package/lib/generate-styles/index.js +18 -0
  149. package/lib/generate-version-info/index.js +27 -0
  150. package/package-scripts.js +39 -19
  151. package/package.json +19 -12
  152. package/src/AssetRegistry.js +8 -6
  153. package/src/Boot.js +59 -0
  154. package/src/CSP.js +59 -0
  155. package/src/CustomElementsRegistry.js +95 -0
  156. package/src/CustomElementsScope.js +108 -0
  157. package/src/DOMObserver.js +65 -0
  158. package/src/Device.js +69 -776
  159. package/src/EventProvider.js +38 -26
  160. package/src/FeaturesRegistry.js +4 -1
  161. package/src/FontFace.js +19 -62
  162. package/src/InitialConfiguration.js +43 -8
  163. package/src/Keys.js +121 -2
  164. package/src/ManagedStyles.js +83 -0
  165. package/src/MediaRange.js +109 -0
  166. package/src/PropertiesFileFormat.js +95 -0
  167. package/src/Render.js +175 -0
  168. package/src/RenderQueue.js +41 -17
  169. package/src/RenderScheduler.js +24 -145
  170. package/src/Runtimes.js +107 -0
  171. package/src/StaticArea.js +1 -39
  172. package/src/StaticAreaItem.js +58 -62
  173. package/src/SystemCSSVars.js +10 -0
  174. package/src/Theming.js +2 -5
  175. package/src/UI5Element.js +428 -303
  176. package/src/UI5ElementMetadata.js +173 -19
  177. package/src/asset-registries/Icons.js +129 -14
  178. package/src/asset-registries/Illustrations.js +30 -0
  179. package/src/asset-registries/LocaleData.js +100 -67
  180. package/src/asset-registries/Themes.js +29 -33
  181. package/src/asset-registries/i18n.js +72 -30
  182. package/src/assets-meta/IconCollectionsAlias.js +18 -0
  183. package/src/config/AnimationMode.js +11 -1
  184. package/src/config/Language.js +58 -2
  185. package/src/config/Theme.js +14 -0
  186. package/src/css/FontFace.css +45 -0
  187. package/src/css/OverrideFontFace.css +32 -0
  188. package/src/css/SystemCSSVars.css +17 -0
  189. package/src/delegate/ItemNavigation.js +244 -171
  190. package/src/delegate/ResizeHandler.js +78 -38
  191. package/src/delegate/ScrollEnablement.js +80 -21
  192. package/src/features/F6Navigation.js +106 -0
  193. package/src/features/OpenUI5Support.js +56 -7
  194. package/src/getSharedResource.js +30 -0
  195. package/src/i18nBundle.js +58 -5
  196. package/src/isLegacyBrowser.js +3 -0
  197. package/src/locale/RTLAwareRegistry.js +14 -0
  198. package/src/locale/applyDirection.js +17 -0
  199. package/src/locale/directionChange.js +32 -0
  200. package/src/locale/getEffectiveDir.js +28 -0
  201. package/src/locale/getLocale.js +12 -2
  202. package/src/locale/languageChange.js +22 -0
  203. package/src/renderer/LitRenderer.js +26 -7
  204. package/src/renderer/directives/style-map.js +72 -0
  205. package/src/renderer/executeTemplate.js +17 -0
  206. package/src/theming/CustomStyle.js +47 -6
  207. package/src/theming/ThemeLoaded.js +22 -0
  208. package/src/theming/applyTheme.js +69 -9
  209. package/src/theming/getConstructableStyle.js +15 -10
  210. package/src/theming/getEffectiveLinksHrefs.js +20 -0
  211. package/src/theming/getEffectiveStyle.js +23 -8
  212. package/src/theming/getStylesString.js +15 -0
  213. package/src/theming/getThemeDesignerTheme.js +87 -0
  214. package/src/theming/preloadLinks.js +23 -0
  215. package/src/types/CSSColor.js +9 -0
  216. package/src/types/CalendarType.js +1 -1
  217. package/src/types/DataType.js +13 -1
  218. package/src/types/Float.js +14 -0
  219. package/src/types/Integer.js +4 -0
  220. package/src/types/InvisibleMessageMode.js +30 -0
  221. package/src/types/ItemNavigationBehavior.js +2 -7
  222. package/src/types/NavigationMode.js +1 -0
  223. package/src/types/PopupState.js +1 -1
  224. package/src/types/ValueState.js +1 -1
  225. package/src/updateShadowRoot.js +30 -0
  226. package/src/util/AriaLabelHelper.js +41 -0
  227. package/src/util/Caret.js +45 -0
  228. package/src/util/ColorConversion.js +370 -0
  229. package/src/util/FocusableElements.js +30 -11
  230. package/src/util/HTMLSanitizer.js +7 -0
  231. package/src/util/InvisibleMessage.js +60 -0
  232. package/src/util/PopupUtils.js +93 -0
  233. package/src/util/SlotsHelper.js +43 -0
  234. package/src/util/TabbableElements.js +9 -1
  235. package/src/util/arraysAreEqual.js +15 -0
  236. package/src/util/clamp.js +12 -0
  237. package/src/util/createLinkInHead.js +19 -0
  238. package/src/util/debounce.js +17 -0
  239. package/src/util/escapeRegex.js +10 -0
  240. package/src/util/generateHighlightedMarkup.js +42 -0
  241. package/src/util/getActiveElement.js +11 -0
  242. package/src/util/getClassCopy.js +10 -0
  243. package/src/util/getEffectiveContentDensity.js +5 -0
  244. package/src/util/getSingletonElementInstance.js +13 -0
  245. package/src/util/isElementInView.js +15 -0
  246. package/src/util/isNodeHidden.js +1 -5
  247. package/src/util/isNodeTabbable.js +4 -4
  248. package/src/util/isValidPropertyName.js +11 -2
  249. package/src/util/setToArray.js +10 -0
  250. package/used-modules.txt +10 -0
  251. package/bundle.es5.js +0 -28
  252. package/dist/SVGIconRegistry.js +0 -60
  253. package/dist/boot.js +0 -32
  254. package/dist/compatibility/DOMObserver.js +0 -62
  255. package/dist/compatibility/patchNodeValue.js +0 -24
  256. package/dist/compatibility/whenPolyfillLoaded.js +0 -26
  257. package/dist/delegate/CustomResize.js +0 -78
  258. package/dist/delegate/NativeResize.js +0 -44
  259. package/dist/features/browsersupport/Edge.js +0 -6
  260. package/dist/features/browsersupport/IE11.js +0 -41
  261. package/dist/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
  262. package/dist/renderer/ifDefined.js +0 -21
  263. package/dist/resources/bundle.es5.js +0 -212
  264. package/dist/resources/bundle.es5.js.map +0 -1
  265. package/dist/test-resources/dev-helpers/ExternalThemePresent.js +0 -3
  266. package/dist/theming/CSSVarsPonyfill.js +0 -25
  267. package/dist/theming/ExternalThemePresent.js +0 -12
  268. package/dist/theming/adaptCSSForIE.js +0 -90
  269. package/dist/theming/createComponentStyleTag.js +0 -49
  270. package/dist/theming/createThemePropertiesStyleTag.js +0 -27
  271. package/dist/thirdparty/Array.from.js +0 -16
  272. package/dist/thirdparty/Array.prototype.fill.js +0 -44
  273. package/dist/thirdparty/Array.prototype.find.js +0 -46
  274. package/dist/thirdparty/Array.prototype.includes.js +0 -51
  275. package/dist/thirdparty/Element.prototype.closest.js +0 -11
  276. package/dist/thirdparty/Element.prototype.matches.js +0 -6
  277. package/dist/thirdparty/Map.prototype.keys.js +0 -9
  278. package/dist/thirdparty/Number.isInteger.js +0 -5
  279. package/dist/thirdparty/Number.isNaN.js +0 -1
  280. package/dist/thirdparty/Number.parseInt.js +0 -1
  281. package/dist/thirdparty/Object.assign.js +0 -31
  282. package/dist/thirdparty/Object.entries.js +0 -11
  283. package/dist/thirdparty/Symbol.js +0 -2
  284. package/dist/thirdparty/WeakSet.js +0 -27
  285. package/dist/thirdparty/es6-string-methods.js +0 -182
  286. package/dist/thirdparty/events-polyfills.js +0 -89
  287. package/dist/thirdparty/fetch.js +0 -1
  288. package/dist/thirdparty/template.js +0 -600
  289. package/dist/thirdparty/webcomponents-sd-ce-pf.js +0 -318
  290. package/dist/webcomponentsjs/LICENSE.md +0 -19
  291. package/dist/webcomponentsjs/README.md +0 -229
  292. package/dist/webcomponentsjs/bundles/webcomponents-ce.js +0 -63
  293. package/dist/webcomponentsjs/bundles/webcomponents-ce.js.map +0 -1
  294. package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js +0 -297
  295. package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js.map +0 -1
  296. package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js +0 -208
  297. package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js.map +0 -1
  298. package/dist/webcomponentsjs/bundles/webcomponents-sd.js +0 -166
  299. package/dist/webcomponentsjs/bundles/webcomponents-sd.js.map +0 -1
  300. package/dist/webcomponentsjs/custom-elements-es5-adapter.js +0 -15
  301. package/dist/webcomponentsjs/package.json +0 -46
  302. package/dist/webcomponentsjs/src/entrypoints/custom-elements-es5-adapter-index.js +0 -16
  303. package/dist/webcomponentsjs/src/entrypoints/webcomponents-bundle-index.js +0 -53
  304. package/dist/webcomponentsjs/src/entrypoints/webcomponents-ce-index.js +0 -17
  305. package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-index.js +0 -19
  306. package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-pf-index.js +0 -28
  307. package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-index.js +0 -18
  308. package/dist/webcomponentsjs/webcomponents-bundle.js +0 -298
  309. package/dist/webcomponentsjs/webcomponents-bundle.js.map +0 -1
  310. package/dist/webcomponentsjs/webcomponents-loader.js +0 -185
  311. package/src/SVGIconRegistry.js +0 -60
  312. package/src/boot.js +0 -32
  313. package/src/compatibility/DOMObserver.js +0 -62
  314. package/src/compatibility/patchNodeValue.js +0 -24
  315. package/src/compatibility/whenPolyfillLoaded.js +0 -26
  316. package/src/delegate/CustomResize.js +0 -78
  317. package/src/delegate/NativeResize.js +0 -44
  318. package/src/features/browsersupport/Edge.js +0 -6
  319. package/src/features/browsersupport/IE11.js +0 -41
  320. package/src/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
  321. package/src/renderer/ifDefined.js +0 -21
  322. package/src/theming/CSSVarsPonyfill.js +0 -25
  323. package/src/theming/ExternalThemePresent.js +0 -12
  324. package/src/theming/adaptCSSForIE.js +0 -90
  325. package/src/theming/createComponentStyleTag.js +0 -49
  326. package/src/theming/createThemePropertiesStyleTag.js +0 -27
  327. package/src/thirdparty/Array.from.js +0 -16
  328. package/src/thirdparty/Array.prototype.fill.js +0 -44
  329. package/src/thirdparty/Array.prototype.find.js +0 -46
  330. package/src/thirdparty/Array.prototype.includes.js +0 -51
  331. package/src/thirdparty/Element.prototype.closest.js +0 -11
  332. package/src/thirdparty/Element.prototype.matches.js +0 -6
  333. package/src/thirdparty/Map.prototype.keys.js +0 -9
  334. package/src/thirdparty/Number.isInteger.js +0 -5
  335. package/src/thirdparty/Number.isNaN.js +0 -1
  336. package/src/thirdparty/Number.parseInt.js +0 -1
  337. package/src/thirdparty/Object.assign.js +0 -31
  338. package/src/thirdparty/Object.entries.js +0 -11
  339. package/src/thirdparty/Symbol.js +0 -2
  340. package/src/thirdparty/WeakSet.js +0 -27
  341. package/src/thirdparty/es6-string-methods.js +0 -182
  342. package/src/thirdparty/events-polyfills.js +0 -89
  343. package/src/thirdparty/fetch.js +0 -1
  344. package/src/thirdparty/template.js +0 -600
  345. package/src/thirdparty/webcomponents-sd-ce-pf.js +0 -318
@@ -1,9 +1,9 @@
1
- import { isPhone } from "../Device.js";
1
+ import { supportsTouch } from "../Device.js";
2
2
  import EventProvider from "../EventProvider.js";
3
3
  import scroll from "../animations/scroll.js";
4
4
 
5
5
  const scrollEventName = "scroll";
6
- const touchEndEventName = isPhone() ? "touchend" : "mouseup";
6
+ const touchEndEventName = supportsTouch() ? "touchend" : "mouseup";
7
7
 
8
8
  class ScrollEnablement extends EventProvider {
9
9
  constructor(containerComponent) {
@@ -13,9 +13,19 @@ class ScrollEnablement extends EventProvider {
13
13
  this.mouseUp = this.ontouchend.bind(this);
14
14
  this.touchStart = this.ontouchstart.bind(this);
15
15
 
16
- this.isPhone = isPhone();
16
+ this.supportsTouch = supportsTouch();
17
17
 
18
- if (this.isPhone) {
18
+ // On Android devices touchmove is thrown one more time than neccessary (together with touchend)
19
+ // so we have to cache the previus coordinates in order to provide correct parameters in the
20
+ // event for Android
21
+ this.cachedValue = {};
22
+
23
+ // In components like Carousel you need to know if the user has clicked on something or swiped
24
+ // in order to throw the needed event or not
25
+ this.startX = 0;
26
+ this.startY = 0;
27
+
28
+ if (this.supportsTouch) {
19
29
  containerComponent.addEventListener("touchstart", this.touchStart, { passive: true });
20
30
  containerComponent.addEventListener("touchmove", this.mouseMove, { passive: true });
21
31
  containerComponent.addEventListener("touchend", this.mouseUp, { passive: true });
@@ -32,12 +42,41 @@ class ScrollEnablement extends EventProvider {
32
42
  return this._container;
33
43
  }
34
44
 
35
- scrollTo(left, top) {
45
+ /**
46
+ * Scrolls the container to the left/top position, retrying retryCount times, if the container is not yet painted
47
+ *
48
+ * @param left
49
+ * @param top
50
+ * @param retryCount
51
+ * @param retryInterval
52
+ * @returns {Promise<void>} resolved when scrolled successfully
53
+ */
54
+ async scrollTo(left, top, retryCount = 0, retryInterval = 0) {
55
+ let containerPainted = this.scrollContainer.clientHeight > 0 && this.scrollContainer.clientWidth > 0;
56
+
57
+ /* eslint-disable no-loop-func, no-await-in-loop */
58
+ while (!containerPainted && retryCount > 0) {
59
+ await new Promise(resolve => {
60
+ setTimeout(() => {
61
+ containerPainted = this.scrollContainer.clientHeight > 0 && this.scrollContainer.clientWidth > 0;
62
+ retryCount--;
63
+ resolve();
64
+ }, retryInterval);
65
+ });
66
+ }
67
+ /* eslint-disable no-loop-func, no-await-in-loop */
68
+
36
69
  this._container.scrollLeft = left;
37
70
  this._container.scrollTop = top;
38
71
  }
39
72
 
40
- move(dx, dy) {
73
+ move(dx, dy, disableAnimation) {
74
+ if (disableAnimation) {
75
+ this._container.scrollLeft += dx;
76
+ this._container.scrollTop += dy;
77
+ return;
78
+ }
79
+
41
80
  return scroll({
42
81
  element: this._container,
43
82
  dx,
@@ -55,25 +94,29 @@ class ScrollEnablement extends EventProvider {
55
94
 
56
95
  _isTouchInside(touch) {
57
96
  const rect = this._container.getBoundingClientRect();
58
- const x = this.isPhone ? touch.clientX : touch.x;
59
- const y = this.isPhone ? touch.clientY : touch.y;
97
+ const x = this.supportsTouch ? touch.clientX : touch.x;
98
+ const y = this.supportsTouch ? touch.clientY : touch.y;
60
99
 
61
100
  return x >= rect.left && x <= rect.right
62
101
  && y >= rect.top && y <= rect.bottom;
63
102
  }
64
103
 
65
104
  ontouchstart(event) {
66
- const touch = this.isPhone ? event.touches[0] : null;
105
+ const touch = this.supportsTouch ? event.touches[0] : null;
67
106
 
68
- if (!this.isPhone) {
107
+ if (!this.supportsTouch) {
69
108
  document.addEventListener("mouseup", this.mouseUp, { passive: true });
70
109
  document.addEventListener("mousemove", this.mouseMove, { passive: true });
110
+ } else {
111
+ // Needed only on mobile
112
+ this.startX = touch.pageX;
113
+ this.startY = touch.pageY;
71
114
  }
72
115
 
73
- this._prevDragX = this.isPhone ? touch.pageX : event.x;
74
- this._prevDragY = this.isPhone ? touch.pageY : event.y;
116
+ this._prevDragX = this.supportsTouch ? touch.pageX : event.x;
117
+ this._prevDragY = this.supportsTouch ? touch.pageY : event.y;
75
118
 
76
- this._canScroll = this._isTouchInside(this.isPhone ? touch : event);
119
+ this._canScroll = this._isTouchInside(this.supportsTouch ? touch : event);
77
120
  }
78
121
 
79
122
  ontouchmove(event) {
@@ -82,10 +125,10 @@ class ScrollEnablement extends EventProvider {
82
125
  }
83
126
 
84
127
  const container = this._container;
85
- const touch = this.isPhone ? event.touches[0] : null;
128
+ const touch = this.supportsTouch ? event.touches[0] : null;
86
129
 
87
- const dragX = this.isPhone ? touch.pageX : event.x;
88
- const dragY = this.isPhone ? touch.pageY : event.y;
130
+ const dragX = this.supportsTouch ? touch.pageX : event.x;
131
+ const dragY = this.supportsTouch ? touch.pageY : event.y;
89
132
 
90
133
  container.scrollLeft += this._prevDragX - dragX;
91
134
  container.scrollTop += this._prevDragY - dragY;
@@ -95,31 +138,47 @@ class ScrollEnablement extends EventProvider {
95
138
  isRight: dragX < this._prevDragX,
96
139
  });
97
140
 
141
+ this.cachedValue.dragX = this._prevDragX;
142
+ this.cachedValue.dragY = this._prevDragY;
143
+
98
144
  this._prevDragX = dragX;
99
145
  this._prevDragY = dragY;
100
146
  }
101
147
 
102
148
  ontouchend(event) {
149
+ if (this.supportsTouch) {
150
+ const deltaX = Math.abs(event.changedTouches[0].pageX - this.startX);
151
+ const deltaY = Math.abs(event.changedTouches[0].pageY - this.startY);
152
+
153
+ if (deltaX < 10 && deltaY < 10) {
154
+ return;
155
+ }
156
+ }
157
+
103
158
  if (!this._canScroll) {
104
159
  return;
105
160
  }
106
161
 
107
162
  const container = this._container;
108
- const dragX = this.isPhone ? event.pageX : event.x;
109
- const dragY = this.isPhone ? event.pageY : event.y;
163
+ const dragX = this.supportsTouch ? event.changedTouches[0].pageX : event.x;
164
+ const dragY = this.supportsTouch ? event.changedTouches[0].pageY : event.y;
110
165
 
111
166
  container.scrollLeft += this._prevDragX - dragX;
112
167
  container.scrollTop += this._prevDragY - dragY;
113
168
 
169
+ const useCachedValues = dragX === this._prevDragX;
170
+ const _dragX = useCachedValues ? this.cachedValue.dragX : dragX;
171
+ // const _dragY = useCachedValues ? this.cachedValue.dragY : dragY; add if needed
172
+
114
173
  this.fireEvent(touchEndEventName, {
115
- isLeft: dragX > this._prevDragX,
116
- isRight: dragX < this._prevDragX,
174
+ isLeft: _dragX < this._prevDragX,
175
+ isRight: _dragX > this._prevDragX,
117
176
  });
118
177
 
119
178
  this._prevDragX = dragX;
120
179
  this._prevDragY = dragY;
121
180
 
122
- if (!this.isPhone) {
181
+ if (!this.supportsTouch) {
123
182
  document.removeEventListener("mousemove", this.mouseMove, { passive: true });
124
183
  document.removeEventListener("mouseup", this.mouseUp);
125
184
  }
@@ -0,0 +1,106 @@
1
+ import { registerFeature } from "../FeaturesRegistry.js";
2
+ import { isF6Next, isF6Previous } from "../Keys.js";
3
+ import { getFirstFocusableElement } from "../util/FocusableElements.js";
4
+
5
+ class F6Navigation {
6
+ init() {
7
+ this.keydownHandler = this._keydownHandler.bind(this);
8
+ this.attachEventListeners();
9
+ this.selectedGroup = null;
10
+ this.groups = [];
11
+ }
12
+
13
+ attachEventListeners() {
14
+ document.addEventListener("keydown", this.keydownHandler);
15
+ }
16
+
17
+ async _keydownHandler(event) {
18
+ if (isF6Next(event)) {
19
+ this.updateGroups();
20
+ if (this.groups.length < 1) {
21
+ return;
22
+ }
23
+
24
+ const nextIndex = this.groups.indexOf(this.selectedGroup);
25
+ let nextElement = null;
26
+
27
+ if (nextIndex > -1) {
28
+ if (nextIndex + 1 >= this.groups.length) {
29
+ nextElement = this.groups[0];
30
+ } else {
31
+ nextElement = this.groups[nextIndex + 1];
32
+ }
33
+ } else {
34
+ nextElement = this.groups[0];
35
+ }
36
+
37
+ const elementToFocus = await getFirstFocusableElement(nextElement.isUI5Element ? nextElement.getDomRef() : nextElement, true);
38
+ elementToFocus.focus();
39
+ }
40
+
41
+ if (isF6Previous(event)) {
42
+ this.updateGroups();
43
+ if (this.groups.length < 1) {
44
+ return;
45
+ }
46
+
47
+ const nextIndex = this.groups.indexOf(this.selectedGroup);
48
+ let nextElement = null;
49
+
50
+ if (nextIndex > -1) {
51
+ if (nextIndex - 1 < 0) {
52
+ nextElement = this.groups[this.groups.length - 1];
53
+ } else {
54
+ // Handle the situation where the first focusable element of two neighbor groups is the same
55
+ // For example:
56
+ // <ui5-flexible-column-layout>
57
+ // <ui5-list>
58
+ // <ui5-li>List Item</ui5-li>
59
+ // </ui5-list>
60
+ // </ui5-flexible-column-layout>
61
+ // Here for both FCL & List the firstFoccusableElement is the same (the ui5-li)
62
+
63
+ const firstFocusable = await getFirstFocusableElement(this.groups[nextIndex - 1], true);
64
+ const shouldSkipParent = firstFocusable === await getFirstFocusableElement(this.groups[nextIndex], true);
65
+
66
+ nextElement = this.groups[shouldSkipParent ? nextIndex - 2 : nextIndex - 1];
67
+ }
68
+ } else {
69
+ nextElement = this.groups[this.groups.length - 1];
70
+ }
71
+
72
+ const elementToFocus = await getFirstFocusableElement(nextElement.isUI5Element ? nextElement.getDomRef() : nextElement, true);
73
+ elementToFocus.focus();
74
+ }
75
+ }
76
+
77
+ removeEventListeners() {
78
+ document.removeEventListener("keydown", this.keydownHandler);
79
+ }
80
+
81
+ updateGroups() {
82
+ this.setSelectedGroup(document.activeElement);
83
+ this.setGroups();
84
+ }
85
+
86
+ setGroups() {
87
+ this.groups = Array.from(document.querySelectorAll("[data-sap-ui-fastnavgroup='true']")).filter(group => group.clientWidth && window.getComputedStyle(group).visibility !== "hidden");
88
+ }
89
+
90
+ setSelectedGroup(element) {
91
+ while (element && element.getAttribute("data-sap-ui-fastnavgroup") !== "true" && element !== document.querySelector("html")) {
92
+ element = element.parentElement ? element.parentNode : element.parentNode.host;
93
+ }
94
+
95
+ this.selectedGroup = element;
96
+ }
97
+
98
+ destroy() {
99
+ this.removeEventListeners();
100
+ }
101
+ }
102
+
103
+ const F6HelperInstance = new F6Navigation();
104
+ registerFeature("F6Navigation", F6HelperInstance);
105
+
106
+ export default F6Navigation;
@@ -1,32 +1,41 @@
1
1
  import { registerFeature } from "../FeaturesRegistry.js";
2
2
  import { setTheme } from "../config/Theme.js";
3
+ import { getCurrentZIndex } from "../util/PopupUtils.js";
3
4
 
4
- const sap = window.sap;
5
- const core = sap && sap.ui && typeof sap.ui.getCore === "function" && sap.ui.getCore();
5
+ const getCore = () => {
6
+ const sap = window.sap;
7
+ const core = sap && sap.ui && typeof sap.ui.getCore === "function" && sap.ui.getCore();
8
+ return core;
9
+ };
6
10
 
7
11
  const isLoaded = () => {
8
- return !!core;
12
+ return !!getCore();
9
13
  };
10
14
 
11
15
  const init = () => {
16
+ const core = getCore();
12
17
  if (!core) {
13
18
  return Promise.resolve();
14
19
  }
15
20
 
16
21
  return new Promise(resolve => {
17
22
  core.attachInit(() => {
18
- sap.ui.require(["sap/ui/core/LocaleData"], resolve);
23
+ window.sap.ui.require(["sap/ui/core/LocaleData", "sap/ui/core/Popup"], (LocaleData, Popup) => {
24
+ Popup.setInitialZIndex(getCurrentZIndex());
25
+ resolve();
26
+ });
19
27
  });
20
28
  });
21
29
  };
22
30
 
23
31
  const getConfigurationSettingsObject = () => {
32
+ const core = getCore();
24
33
  if (!core) {
25
34
  return;
26
35
  }
27
36
 
28
37
  const config = core.getConfiguration();
29
- const LocaleData = sap.ui.require("sap/ui/core/LocaleData");
38
+ const LocaleData = window.sap.ui.require("sap/ui/core/LocaleData");
30
39
 
31
40
  return {
32
41
  animationMode: config.getAnimationMode(),
@@ -35,22 +44,24 @@ const getConfigurationSettingsObject = () => {
35
44
  rtl: config.getRTL(),
36
45
  calendarType: config.getCalendarType(),
37
46
  formatSettings: {
38
- firstDayOfWeek: LocaleData.getInstance(config.getLocale()).getFirstDayOfWeek(),
47
+ firstDayOfWeek: LocaleData ? LocaleData.getInstance(config.getLocale()).getFirstDayOfWeek() : undefined,
39
48
  },
40
49
  };
41
50
  };
42
51
 
43
52
  const getLocaleDataObject = () => {
53
+ const core = getCore();
44
54
  if (!core) {
45
55
  return;
46
56
  }
47
57
 
48
58
  const config = core.getConfiguration();
49
- const LocaleData = sap.ui.require("sap/ui/core/LocaleData");
59
+ const LocaleData = window.sap.ui.require("sap/ui/core/LocaleData");
50
60
  return LocaleData.getInstance(config.getLocale())._get();
51
61
  };
52
62
 
53
63
  const listenForThemeChange = () => {
64
+ const core = getCore();
54
65
  const config = core.getConfiguration();
55
66
  core.attachThemeChanged(async () => {
56
67
  await setTheme(config.getTheme());
@@ -58,6 +69,7 @@ const listenForThemeChange = () => {
58
69
  };
59
70
 
60
71
  const attachListeners = () => {
72
+ const core = getCore();
61
73
  if (!core) {
62
74
  return;
63
75
  }
@@ -65,12 +77,49 @@ const attachListeners = () => {
65
77
  listenForThemeChange();
66
78
  };
67
79
 
80
+ const cssVariablesLoaded = () => {
81
+ const core = getCore();
82
+ if (!core) {
83
+ return;
84
+ }
85
+
86
+ const link = [...document.head.children].find(el => el.id === "sap-ui-theme-sap.ui.core"); // more reliable than querySelector early
87
+ if (!link) {
88
+ return;
89
+ }
90
+
91
+ return !!link.href.match(/\/css(-|_)variables\.css/);
92
+ };
93
+
94
+ const getNextZIndex = () => {
95
+ const core = getCore();
96
+ if (!core) {
97
+ return;
98
+ }
99
+
100
+ const Popup = window.sap.ui.require("sap/ui/core/Popup");
101
+ return Popup.getNextZIndex();
102
+ };
103
+
104
+ const setInitialZIndex = () => {
105
+ const core = getCore();
106
+ if (!core) {
107
+ return;
108
+ }
109
+
110
+ const Popup = window.sap.ui.require("sap/ui/core/Popup");
111
+ Popup.setInitialZIndex(getCurrentZIndex());
112
+ };
113
+
68
114
  const OpenUI5Support = {
69
115
  isLoaded,
70
116
  init,
71
117
  getConfigurationSettingsObject,
72
118
  getLocaleDataObject,
73
119
  attachListeners,
120
+ cssVariablesLoaded,
121
+ getNextZIndex,
122
+ setInitialZIndex,
74
123
  };
75
124
 
76
125
  registerFeature("OpenUI5Support", OpenUI5Support);
@@ -0,0 +1,30 @@
1
+ import getSingletonElementInstance from "./util/getSingletonElementInstance.js";
2
+
3
+ const getSharedResourcesInstance = () => getSingletonElementInstance("ui5-shared-resources", document.head);
4
+
5
+ /**
6
+ * Use this method to initialize/get resources that you would like to be shared among UI5 Web Components runtime instances.
7
+ * The data will be accessed via a singleton "ui5-shared-resources" HTML element in the "head" element of the page.
8
+ *
9
+ * @public
10
+ * @param namespace Unique ID of the resource, may contain "." to denote hierarchy
11
+ * @param initialValue Object or primitive that will be used as an initial value if the resource does not exist
12
+ * @returns {*}
13
+ */
14
+ const getSharedResource = (namespace, initialValue) => {
15
+ const parts = namespace.split(".");
16
+ let current = getSharedResourcesInstance();
17
+
18
+ for (let i = 0; i < parts.length; i++) {
19
+ const part = parts[i];
20
+ const lastPart = i === parts.length - 1;
21
+ if (!Object.prototype.hasOwnProperty.call(current, part)) {
22
+ current[part] = lastPart ? initialValue : {};
23
+ }
24
+ current = current[part];
25
+ }
26
+
27
+ return current;
28
+ };
29
+
30
+ export default getSharedResource;
package/src/i18nBundle.js CHANGED
@@ -1,26 +1,47 @@
1
- import { fetchI18nBundle, getI18nBundleData } from "./asset-registries/i18n.js";
1
+ import { registerI18nLoader, fetchI18nBundle, getI18nBundleData } from "./asset-registries/i18n.js";
2
2
  import formatMessage from "./util/formatMessage.js";
3
3
 
4
4
  const I18nBundleInstances = new Map();
5
5
 
6
+ let customGetI18nBundle;
7
+
8
+ /**
9
+ * @class
10
+ * @public
11
+ */
6
12
  class I18nBundle {
7
13
  constructor(packageName) {
8
14
  this.packageName = packageName;
9
15
  }
10
16
 
17
+ /**
18
+ * Returns a text in the currently loaded language
19
+ *
20
+ * @public
21
+ * @param {Object|String} textObj key/defaultText pair or just the key
22
+ * @param params Values for the placeholders
23
+ * @returns {*}
24
+ */
11
25
  getText(textObj, ...params) {
12
- if (!textObj || !textObj.key || !textObj.defaultText) {
26
+ if (typeof textObj === "string") {
27
+ textObj = { key: textObj, defaultText: textObj };
28
+ }
29
+
30
+ if (!textObj || !textObj.key) {
13
31
  return "";
14
32
  }
15
33
 
16
34
  const bundle = getI18nBundleData(this.packageName);
17
- const messageText = bundle && bundle[textObj.key] ? bundle[textObj.key] : textObj.defaultText;
35
+ if (bundle && !bundle[textObj.key]) {
36
+ console.warn(`Key ${textObj.key} not found in the i18n bundle, the default text will be used`); // eslint-disable-line
37
+ }
38
+ const messageText = bundle && bundle[textObj.key] ? bundle[textObj.key] : (textObj.defaultText || textObj.key);
18
39
 
19
40
  return formatMessage(messageText, params);
20
41
  }
21
42
  }
22
43
 
23
- const getI18nBundle = packageName => {
44
+ const getI18nBundleSync = packageName => {
24
45
  if (I18nBundleInstances.has(packageName)) {
25
46
  return I18nBundleInstances.get(packageName);
26
47
  }
@@ -30,4 +51,36 @@ const getI18nBundle = packageName => {
30
51
  return i18nBundle;
31
52
  };
32
53
 
33
- export { fetchI18nBundle, getI18nBundle };
54
+ /**
55
+ * Allows developers to provide a custom getI18nBundle implementation
56
+ * If this function is called, the custom implementation will be used for all components and will completely
57
+ * replace the default implementation.
58
+ *
59
+ * @public
60
+ * @param customGet the function to use instead of the standard getI18nBundle implementation
61
+ */
62
+ const registerCustomI18nBundleGetter = customGet => {
63
+ customGetI18nBundle = customGet;
64
+ };
65
+
66
+ /**
67
+ * Fetches and returns the I18nBundle instance for the given package
68
+ *
69
+ * @public
70
+ * @param packageName
71
+ * @returns {Promise<I18nBundle>}
72
+ */
73
+ const getI18nBundle = async packageName => {
74
+ if (customGetI18nBundle) {
75
+ return customGetI18nBundle(packageName);
76
+ }
77
+
78
+ await fetchI18nBundle(packageName);
79
+ return getI18nBundleSync(packageName);
80
+ };
81
+
82
+ export {
83
+ registerI18nLoader,
84
+ getI18nBundle,
85
+ registerCustomI18nBundleGetter,
86
+ };
@@ -0,0 +1,3 @@
1
+ const isLegacyBrowser = () => !!window.ShadyDOM;
2
+
3
+ export default isLegacyBrowser;
@@ -0,0 +1,14 @@
1
+ const rtlAwareSet = new Set();
2
+
3
+ const markAsRtlAware = klass => {
4
+ rtlAwareSet.add(klass);
5
+ };
6
+
7
+ const isRtlAware = klass => {
8
+ return rtlAwareSet.has(klass);
9
+ };
10
+
11
+ export {
12
+ markAsRtlAware,
13
+ isRtlAware,
14
+ };
@@ -0,0 +1,17 @@
1
+ import { reRenderAllUI5Elements } from "../Render.js";
2
+ import { fireDirectionChange } from "./directionChange.js";
3
+
4
+ /**
5
+ * Re-renders all RTL-aware UI5 Elements.
6
+ * Call this method whenever you change the "dir" property anywhere in your HTML page
7
+ * Example: document.body.dir = "rtl"; applyDirection();
8
+ *
9
+ * @returns {Promise<void>}
10
+ */
11
+ const applyDirection = async () => {
12
+ const listenersResults = fireDirectionChange();
13
+ await Promise.all(listenersResults);
14
+ await reRenderAllUI5Elements({ rtlAware: true });
15
+ };
16
+
17
+ export default applyDirection;
@@ -0,0 +1,32 @@
1
+ import EventProvider from "../EventProvider.js";
2
+
3
+ const eventProvider = new EventProvider();
4
+ const DIR_CHANGE = "directionChange";
5
+
6
+ /**
7
+ * Attach a callback that will be executed whenever the application calls the "applyDirection" function
8
+ * @public
9
+ * @param listener
10
+ */
11
+ const attachDirectionChange = listener => {
12
+ eventProvider.attachEvent(DIR_CHANGE, listener);
13
+ };
14
+
15
+ /**
16
+ * Detach a callback that was passed with "attachDirectionChange"
17
+ * @public
18
+ * @param listener
19
+ */
20
+ const detachDirectionChange = listener => {
21
+ eventProvider.detachEvent(DIR_CHANGE, listener);
22
+ };
23
+
24
+ const fireDirectionChange = () => {
25
+ return eventProvider.fireEvent(DIR_CHANGE);
26
+ };
27
+
28
+ export {
29
+ attachDirectionChange,
30
+ detachDirectionChange,
31
+ fireDirectionChange,
32
+ };
@@ -0,0 +1,28 @@
1
+ import { getRTL } from "../config/RTL.js";
2
+
3
+ const GLOBAL_DIR_CSS_VAR = "--_ui5_dir";
4
+
5
+ const getEffectiveDir = element => {
6
+ const doc = window.document;
7
+ const dirValues = ["ltr", "rtl"]; // exclude "auto" and "" from all calculations
8
+ const locallyAppliedDir = getComputedStyle(element).getPropertyValue(GLOBAL_DIR_CSS_VAR);
9
+
10
+ // In that order, inspect the CSS Var (for modern browsers), the element itself, html and body (for IE fallback)
11
+ if (dirValues.includes(locallyAppliedDir)) {
12
+ return locallyAppliedDir;
13
+ }
14
+ if (dirValues.includes(element.dir)) {
15
+ return element.dir;
16
+ }
17
+ if (dirValues.includes(doc.documentElement.dir)) {
18
+ return doc.documentElement.dir;
19
+ }
20
+ if (dirValues.includes(doc.body.dir)) {
21
+ return doc.body.dir;
22
+ }
23
+
24
+ // Finally, check the configuration for explicitly set RTL or language-implied RTL
25
+ return getRTL() ? "rtl" : undefined;
26
+ };
27
+
28
+ export default getEffectiveDir;
@@ -2,10 +2,20 @@ import detectNavigatorLanguage from "../util/detectNavigatorLanguage.js";
2
2
  import { getLanguage as getConfigLanguage } from "../config/Language.js";
3
3
  import Locale from "./Locale.js";
4
4
 
5
+ const cache = new Map();
6
+
7
+ const getLocaleInstance = lang => {
8
+ if (!cache.has(lang)) {
9
+ cache.set(lang, new Locale(lang));
10
+ }
11
+
12
+ return cache.get(lang);
13
+ };
14
+
5
15
  const convertToLocaleOrNull = lang => {
6
16
  try {
7
17
  if (lang && typeof lang === "string") {
8
- return new Locale(lang);
18
+ return getLocaleInstance(lang);
9
19
  }
10
20
  } catch (e) {
11
21
  // ignore
@@ -22,7 +32,7 @@ const getLocale = lang => {
22
32
  }
23
33
 
24
34
  if (getConfigLanguage()) {
25
- return new Locale(getConfigLanguage());
35
+ return getLocaleInstance(getConfigLanguage());
26
36
  }
27
37
 
28
38
  return convertToLocaleOrNull(detectNavigatorLanguage());
@@ -0,0 +1,22 @@
1
+ import EventProvider from "../EventProvider.js";
2
+
3
+ const eventProvider = new EventProvider();
4
+ const LANG_CHANGE = "languageChange";
5
+
6
+ const attachLanguageChange = listener => {
7
+ eventProvider.attachEvent(LANG_CHANGE, listener);
8
+ };
9
+
10
+ const detachLanguageChange = listener => {
11
+ eventProvider.detachEvent(LANG_CHANGE, listener);
12
+ };
13
+
14
+ const fireLanguageChange = lang => {
15
+ return eventProvider.fireEventAsync(LANG_CHANGE, lang);
16
+ };
17
+
18
+ export {
19
+ attachLanguageChange,
20
+ detachLanguageChange,
21
+ fireLanguageChange,
22
+ };