@ui5/webcomponents-base 0.0.0-6895c16dd → 0.0.0-6cb3eb0db

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 (107) hide show
  1. package/.eslintignore +2 -0
  2. package/CHANGELOG.md +39 -0
  3. package/README.md +26 -1
  4. package/bundle.esm.js +5 -0
  5. package/dist/Boot.js +15 -20
  6. package/dist/Device.js +2 -0
  7. package/dist/EventProvider.js +19 -25
  8. package/dist/InitialConfiguration.js +20 -15
  9. package/dist/Keys.js +15 -0
  10. package/dist/MediaRange.js +0 -1
  11. package/dist/Render.js +0 -1
  12. package/dist/StaticArea.js +3 -0
  13. package/dist/StaticAreaItem.js +30 -3
  14. package/dist/UI5Element.js +37 -43
  15. package/dist/UI5ElementMetadata.js +1 -1
  16. package/dist/asset-registries/Icons.js +10 -0
  17. package/dist/asset-registries/Illustrations.js +30 -0
  18. package/dist/delegate/ItemNavigation.js +66 -0
  19. package/dist/delegate/ScrollEnablement.js +7 -1
  20. package/dist/features/OpenUI5Support.js +41 -6
  21. package/dist/generated/AssetParameters.js +1 -1
  22. package/dist/i18nBundle.js +4 -0
  23. package/dist/renderer/LitRenderer.js +19 -18
  24. package/dist/resources/bundle.esm.js +17 -101
  25. package/dist/resources/bundle.esm.js.map +1 -1
  26. package/dist/sap/base/Log.js +241 -0
  27. package/dist/sap/base/assert.js +8 -0
  28. package/dist/sap/base/security/URLListValidator.js +148 -0
  29. package/dist/sap/base/security/sanitizeHTML.js +16 -0
  30. package/dist/sap/base/util/now.js +7 -0
  31. package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +3585 -0
  32. package/dist/test-resources/elements/WithStaticArea.js +2 -1
  33. package/dist/test-resources/pages/AllTestElements.html +3 -0
  34. package/dist/test-resources/specs/ConfigurationChange.spec.js +10 -8
  35. package/dist/test-resources/specs/ConfigurationScript.spec.js +25 -23
  36. package/dist/test-resources/specs/ConfigurationURL.spec.js +65 -17
  37. package/dist/test-resources/specs/CustomTheme.spec.js +6 -4
  38. package/dist/test-resources/specs/EventProvider.spec.js +63 -0
  39. package/dist/test-resources/specs/StaticArea.spec.js +56 -12
  40. package/dist/test-resources/specs/Theming.spec.js +9 -7
  41. package/dist/test-resources/specs/UI5ElementInvalidation.js +30 -28
  42. package/dist/test-resources/specs/UI5ElementLifecycle.js +12 -10
  43. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +12 -10
  44. package/dist/test-resources/specs/UI5ElementMetadataExt.js +9 -7
  45. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +7 -5
  46. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +37 -35
  47. package/dist/test-resources/specs/UI5ElementShadowDOM.js +10 -8
  48. package/dist/test-resources/specs/UI5ElementSlots.js +10 -8
  49. package/dist/types/DataType.js +12 -0
  50. package/dist/types/Float.js +4 -0
  51. package/dist/types/Integer.js +4 -0
  52. package/dist/types/InvisibleMessageMode.js +30 -0
  53. package/dist/updateShadowRoot.js +1 -1
  54. package/dist/util/AriaLabelHelper.js +4 -4
  55. package/dist/util/FocusableElements.js +5 -1
  56. package/dist/util/HTMLSanitizer.js +7 -0
  57. package/dist/util/InvisibleMessage.js +58 -0
  58. package/dist/util/PopupUtils.js +93 -0
  59. package/dist/util/TabbableElements.js +1 -1
  60. package/dist/util/clamp.js +12 -0
  61. package/dist/util/getClassCopy.js +10 -0
  62. package/dist/util/isElementInView.js +15 -0
  63. package/dist/util/isNodeTabbable.js +4 -4
  64. package/hash.txt +1 -0
  65. package/index.js +1 -1
  66. package/package-scripts.js +30 -14
  67. package/package.json +20 -9
  68. package/src/Boot.js +15 -20
  69. package/src/Device.js +2 -0
  70. package/src/EventProvider.js +19 -25
  71. package/src/InitialConfiguration.js +20 -15
  72. package/src/Keys.js +15 -0
  73. package/src/MediaRange.js +0 -1
  74. package/src/Render.js +0 -1
  75. package/src/StaticArea.js +3 -0
  76. package/src/StaticAreaItem.js +30 -3
  77. package/src/UI5Element.js +37 -43
  78. package/src/UI5ElementMetadata.js +1 -1
  79. package/src/asset-registries/Icons.js +10 -0
  80. package/src/asset-registries/Illustrations.js +30 -0
  81. package/src/delegate/ItemNavigation.js +66 -0
  82. package/src/delegate/ScrollEnablement.js +7 -1
  83. package/src/features/OpenUI5Support.js +41 -6
  84. package/src/i18nBundle.js +4 -0
  85. package/src/renderer/LitRenderer.js +19 -18
  86. package/src/types/DataType.js +12 -0
  87. package/src/types/Float.js +4 -0
  88. package/src/types/Integer.js +4 -0
  89. package/src/types/InvisibleMessageMode.js +30 -0
  90. package/src/updateShadowRoot.js +1 -1
  91. package/src/util/AriaLabelHelper.js +4 -4
  92. package/src/util/FocusableElements.js +5 -1
  93. package/src/util/HTMLSanitizer.js +7 -0
  94. package/src/util/InvisibleMessage.js +58 -0
  95. package/src/util/PopupUtils.js +93 -0
  96. package/src/util/TabbableElements.js +1 -1
  97. package/src/util/clamp.js +12 -0
  98. package/src/util/getClassCopy.js +10 -0
  99. package/src/util/isElementInView.js +15 -0
  100. package/src/util/isNodeTabbable.js +4 -4
  101. package/used-modules.txt +7 -0
  102. package/dist/config/AssetsPath.js +0 -17
  103. package/dist/renderer/ifDefined.js +0 -21
  104. package/dist/renderer/scopeHTML.js +0 -32
  105. package/src/config/AssetsPath.js +0 -17
  106. package/src/renderer/ifDefined.js +0 -21
  107. package/src/renderer/scopeHTML.js +0 -32
@@ -3,19 +3,20 @@ import { boot } from "./Boot.js";
3
3
  import UI5ElementMetadata from "./UI5ElementMetadata.js";
4
4
  import EventProvider from "./EventProvider.js";
5
5
  import getSingletonElementInstance from "./util/getSingletonElementInstance.js";
6
- import "./StaticAreaItem.js";
6
+ import StaticAreaItem from "./StaticAreaItem.js";
7
7
  import updateShadowRoot from "./updateShadowRoot.js";
8
8
  import { renderDeferred, renderImmediately, cancelRender } from "./Render.js";
9
9
  import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js";
10
10
  import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js";
11
11
  import { skipOriginalEvent } from "./config/NoConflict.js";
12
12
  import getEffectiveDir from "./locale/getEffectiveDir.js";
13
- import Integer from "./types/Integer.js";
14
- import Float from "./types/Float.js";
13
+ import DataType from "./types/DataType.js";
15
14
  import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js";
16
15
  import isValidPropertyName from "./util/isValidPropertyName.js";
16
+ import isDescendantOf from "./util/isDescendantOf.js";
17
17
  import { isSlot, getSlotName, getSlottedElementsList } from "./util/SlotsHelper.js";
18
18
  import arraysAreEqual from "./util/arraysAreEqual.js";
19
+ import getClassCopy from "./util/getClassCopy.js";
19
20
  import { markAsRtlAware } from "./locale/RTLAwareRegistry.js";
20
21
  import isLegacyBrowser from "./isLegacyBrowser.js";
21
22
 
@@ -42,7 +43,7 @@ function _invalidate(changeInfo) {
42
43
 
43
44
  this._changedState.push(changeInfo);
44
45
  renderDeferred(this);
45
- this._eventProvider.fireEvent("change", { ...changeInfo, target: this });
46
+ this._eventProvider.fireEvent("invalidate", { ...changeInfo, target: this });
46
47
  }
47
48
 
48
49
  /**
@@ -101,7 +102,6 @@ class UI5Element extends HTMLElement {
101
102
  async connectedCallback() {
102
103
  this.setAttribute(this.constructor.getMetadata().getPureTag(), "");
103
104
 
104
- const needsShadowDOM = this.constructor._needsShadowDOM();
105
105
  const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
106
106
 
107
107
  this._inDOM = true;
@@ -112,10 +112,6 @@ class UI5Element extends HTMLElement {
112
112
  await this._processChildren();
113
113
  }
114
114
 
115
- if (needsShadowDOM && !this.shadowRoot) { // Workaround for Firefox74 bug
116
- await Promise.resolve();
117
- }
118
-
119
115
  if (!this._inDOM) { // Component removed from DOM while _processChildren was running
120
116
  return;
121
117
  }
@@ -133,7 +129,6 @@ class UI5Element extends HTMLElement {
133
129
  * @private
134
130
  */
135
131
  disconnectedCallback() {
136
- const needsShadowDOM = this.constructor._needsShadowDOM();
137
132
  const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
138
133
 
139
134
  this._inDOM = false;
@@ -142,13 +137,11 @@ class UI5Element extends HTMLElement {
142
137
  this._stopObservingDOMChildren();
143
138
  }
144
139
 
145
- if (needsShadowDOM) {
146
- if (this._fullyConnected) {
147
- if (typeof this.onExitDOM === "function") {
148
- this.onExitDOM();
149
- }
150
- this._fullyConnected = false;
140
+ if (this._fullyConnected) {
141
+ if (typeof this.onExitDOM === "function") {
142
+ this.onExitDOM();
151
143
  }
144
+ this._fullyConnected = false;
152
145
  }
153
146
 
154
147
  if (this.staticAreaItem && this.staticAreaItem.parentElement) {
@@ -258,7 +251,7 @@ class UI5Element extends HTMLElement {
258
251
 
259
252
  // Listen for any invalidation on the child if invalidateOnChildChange is true or an object (ignore when false or not set)
260
253
  if (child.isUI5Element && slotData.invalidateOnChildChange) {
261
- child._attachChange(this._getChildChangeListener(slotName));
254
+ child.attachInvalidate(this._getChildChangeListener(slotName));
262
255
  }
263
256
 
264
257
  // Listen for the slotchange event if the child is a slot itself
@@ -318,7 +311,7 @@ class UI5Element extends HTMLElement {
318
311
 
319
312
  children.forEach(child => {
320
313
  if (child && child.isUI5Element) {
321
- child._detachChange(this._getChildChangeListener(slotName));
314
+ child.detachInvalidate(this._getChildChangeListener(slotName));
322
315
  }
323
316
 
324
317
  if (isSlot(child)) {
@@ -333,20 +326,20 @@ class UI5Element extends HTMLElement {
333
326
  * Attach a callback that will be executed whenever the component is invalidated
334
327
  *
335
328
  * @param callback
336
- * @protected
329
+ * @public
337
330
  */
338
- _attachChange(callback) {
339
- this._eventProvider.attachEvent("change", callback);
331
+ attachInvalidate(callback) {
332
+ this._eventProvider.attachEvent("invalidate", callback);
340
333
  }
341
334
 
342
335
  /**
343
336
  * Detach the callback that is executed whenever the component is invalidated
344
337
  *
345
338
  * @param callback
346
- * @protected
339
+ * @public
347
340
  */
348
- _detachChange(callback) {
349
- this._eventProvider.detachEvent("change", callback);
341
+ detachInvalidate(callback) {
342
+ this._eventProvider.detachEvent("invalidate", callback);
350
343
  }
351
344
 
352
345
  /**
@@ -383,12 +376,8 @@ class UI5Element extends HTMLElement {
383
376
  const propertyTypeClass = properties[nameInCamelCase].type;
384
377
  if (propertyTypeClass === Boolean) {
385
378
  newValue = newValue !== null;
386
- }
387
- if (propertyTypeClass === Integer) {
388
- newValue = parseInt(newValue);
389
- }
390
- if (propertyTypeClass === Float) {
391
- newValue = parseFloat(newValue);
379
+ } else if (isDescendantOf(propertyTypeClass, DataType)) {
380
+ newValue = propertyTypeClass.attributeToProperty(newValue);
392
381
  }
393
382
  this[nameInCamelCase] = newValue;
394
383
  }
@@ -401,22 +390,24 @@ class UI5Element extends HTMLElement {
401
390
  if (!this.constructor.getMetadata().hasAttribute(name)) {
402
391
  return;
403
392
  }
404
-
405
- if (typeof newValue === "object") {
406
- return;
407
- }
408
-
393
+ const properties = this.constructor.getMetadata().getProperties();
394
+ const propertyTypeClass = properties[name].type;
409
395
  const attrName = camelToKebabCase(name);
410
396
  const attrValue = this.getAttribute(attrName);
411
- if (typeof newValue === "boolean") {
397
+
398
+ if (propertyTypeClass === Boolean) {
412
399
  if (newValue === true && attrValue === null) {
413
400
  this.setAttribute(attrName, "");
414
401
  } else if (newValue === false && attrValue !== null) {
415
402
  this.removeAttribute(attrName);
416
403
  }
417
- } else if (attrValue !== newValue) {
418
- this.setAttribute(attrName, newValue);
419
- }
404
+ } else if (isDescendantOf(propertyTypeClass, DataType)) {
405
+ this.setAttribute(attrName, propertyTypeClass.propertyToAttribute(newValue));
406
+ } else if (typeof newValue !== "object") {
407
+ if (attrValue !== newValue) {
408
+ this.setAttribute(attrName, newValue);
409
+ }
410
+ } // else { return; } // old object handling
420
411
  }
421
412
 
422
413
  /**
@@ -442,7 +433,7 @@ class UI5Element extends HTMLElement {
442
433
  * @private
443
434
  */
444
435
  _initializeState() {
445
- this._state = Object.assign({}, this.constructor.getMetadata().getInitialState());
436
+ this._state = { ...this.constructor.getMetadata().getInitialState() };
446
437
  }
447
438
 
448
439
  /**
@@ -795,7 +786,7 @@ class UI5Element extends HTMLElement {
795
786
  }
796
787
 
797
788
  if (!this.staticAreaItem) {
798
- this.staticAreaItem = document.createElement("ui5-static-area-item");
789
+ this.staticAreaItem = StaticAreaItem.createInstance();
799
790
  this.staticAreaItem.setOwnerElement(this);
800
791
  }
801
792
  if (!this.staticAreaItem.parentElement) {
@@ -860,6 +851,8 @@ class UI5Element extends HTMLElement {
860
851
  const oldState = this._state[prop];
861
852
  if (propData.multiple && propData.compareValues) {
862
853
  isDifferent = !arraysAreEqual(oldState, value);
854
+ } else if (isDescendantOf(propData.type, DataType)) {
855
+ isDifferent = !propData.type.valuesAreEqual(oldState, value);
863
856
  } else {
864
857
  isDifferent = oldState !== value;
865
858
  }
@@ -997,9 +990,10 @@ class UI5Element extends HTMLElement {
997
990
  window.customElements.define(tag, this);
998
991
 
999
992
  if (altTag && !customElements.get(altTag)) {
1000
- class oldClassName extends this {}
1001
993
  registerTag(altTag);
1002
- window.customElements.define(altTag, oldClassName);
994
+ window.customElements.define(altTag, getClassCopy(this, () => {
995
+ console.log(`The ${altTag} tag is deprecated and will be removed in the next release, please use ${tag} instead.`); // eslint-disable-line
996
+ }));
1003
997
  }
1004
998
  }
1005
999
  return this;
@@ -126,7 +126,7 @@ class UI5ElementMetadata {
126
126
  */
127
127
  hasAttribute(propName) {
128
128
  const propData = this.getProperties()[propName];
129
- return propData.type !== Object && !propData.noAttribute;
129
+ return propData.type !== Object && !propData.noAttribute && !propData.multiple;
130
130
  }
131
131
 
132
132
  /**
@@ -20,6 +20,9 @@ const registerIconLoader = async (collectionName, loader) => {
20
20
 
21
21
  const _loadIconCollectionOnce = async collectionName => {
22
22
  if (!iconCollectionPromises.has(collectionName)) {
23
+ if (!loaders.has(collectionName)) {
24
+ throw new Error(`No loader registered for the ${collectionName} icons collection. Probably you forgot to import the "AllIcons.js" module for the respective package.`);
25
+ }
23
26
  const loadIcons = loaders.get(collectionName);
24
27
  iconCollectionPromises.set(collectionName, loadIcons(collectionName));
25
28
  }
@@ -70,6 +73,12 @@ const _parseName = name => {
70
73
  if (collection === "SAP-icons-TNT") {
71
74
  collection = "tnt";
72
75
  }
76
+ // hardcoded alias in case icon explorer is used, resolve `BusinessSuiteInAppSymbols` to `business-suite`
77
+ // aliases can be made a feature in the future if more collections need it or more aliases are needed.
78
+ if (collection === "BusinessSuiteInAppSymbols") {
79
+ collection = "business-suite";
80
+ name = name.replace("icon-", "");
81
+ }
73
82
  const registryKey = `${collection}/${name}`;
74
83
  return { name, collection, registryKey };
75
84
  };
@@ -105,6 +114,7 @@ const _getRegisteredNames = async () => {
105
114
  // fetch one icon of each collection to trigger the bundle load
106
115
  await getIconData("edit");
107
116
  await getIconData("tnt/arrow");
117
+ await getIconData("business-suite/3d");
108
118
  return Array.from(registry.keys());
109
119
  };
110
120
 
@@ -0,0 +1,30 @@
1
+ import getSharedResource from "../getSharedResource.js";
2
+
3
+ const registry = getSharedResource("SVGIllustration.registry", new Map());
4
+ const ILLUSTRATION_NOT_FOUND = "ILLUSTRATION_NOT_FOUND";
5
+
6
+ const registerIllustration = (name, { dialogSvg, sceneSvg, spotSvg, set, title, subtitle } = {}) => { // eslint-disable-line
7
+ registry.set(`${set}/${name}`, {
8
+ dialogSvg,
9
+ sceneSvg,
10
+ spotSvg,
11
+ title,
12
+ subtitle,
13
+ });
14
+ };
15
+
16
+ const getIllustrationDataSync = nameProp => {
17
+ let set = "fiori";
18
+
19
+ if (nameProp.startsWith("Tnt")) {
20
+ set = "tnt";
21
+ nameProp = nameProp.replace(/^Tnt/, "");
22
+ }
23
+
24
+ return registry.get(`${set}/${nameProp}`) || ILLUSTRATION_NOT_FOUND;
25
+ };
26
+
27
+ export {
28
+ getIllustrationDataSync,
29
+ registerIllustration,
30
+ };
@@ -5,6 +5,8 @@ import {
5
5
  isRight,
6
6
  isHome,
7
7
  isEnd,
8
+ isPageDown,
9
+ isPageUp,
8
10
  } from "../Keys.js";
9
11
  import getActiveElement from "../util/getActiveElement.js";
10
12
 
@@ -52,6 +54,7 @@ class ItemNavigation {
52
54
  * - currentIndex: the index of the item that will be initially selected (from which navigation will begin)
53
55
  * - navigationMode (Auto|Horizontal|Vertical): whether the items are displayed horizontally (Horizontal), vertically (Vertical) or as a matrix (Auto) meaning the user can navigate in both directions (up/down and left/right)
54
56
  * - rowSize: tells how many items per row there are when the items are not rendered as a flat list but rather as a matrix. Relevant for navigationMode=Auto
57
+ * - skipItemsSize: tells how many items upon PAGE_UP and PAGE_DOWN should be skipped to applying the focus on the next item
55
58
  * - behavior (Static|Cycling): tells what to do when trying to navigate beyond the first and last items
56
59
  * Static means that nothing happens if the user tries to navigate beyond the first/last item.
57
60
  * Cycling means that when the user navigates beyond the last item they go to the first and vice versa.
@@ -85,6 +88,7 @@ class ItemNavigation {
85
88
  this._behavior = options.behavior || ItemNavigationBehavior.Static;
86
89
  this._navigationMode = options.navigationMode || NavigationMode.Auto;
87
90
  this._affectedPropertiesNames = options.affectedPropertiesNames || [];
91
+ this._skipItemsSize = options.skipItemsSize || null;
88
92
  }
89
93
 
90
94
  /**
@@ -142,6 +146,10 @@ class ItemNavigation {
142
146
  this._handleHome();
143
147
  } else if (isEnd(event)) {
144
148
  this._handleEnd();
149
+ } else if (isPageUp(event)) {
150
+ this._handlePageUp();
151
+ } else if (isPageDown(event)) {
152
+ this._handlePageDown();
145
153
  } else {
146
154
  return; // if none of the supported keys is pressed, we don't want to prevent the event or update the item navigation
147
155
  }
@@ -222,6 +230,64 @@ class ItemNavigation {
222
230
  this._currentIndex += (homeEndRange - 1 - this._currentIndex % homeEndRange); // eslint-disable-line
223
231
  }
224
232
 
233
+ _handlePageUp() {
234
+ if (this._rowSize > 1) {
235
+ // eslint-disable-next-line
236
+ // TODO: handle page up on matrix (grid) layout - ColorPalette, ProductSwitch.
237
+ return;
238
+ }
239
+ this._handlePageUpFlat();
240
+ }
241
+
242
+ _handlePageDown() {
243
+ if (this._rowSize > 1) {
244
+ // eslint-disable-next-line
245
+ // TODO: handle page up on matrix (grid) layout - ColorPalette, ProductSwitch.
246
+ return;
247
+ }
248
+ this._handlePageDownFlat();
249
+ }
250
+
251
+ /**
252
+ * Handles PAGE_UP in a flat list-like structure, both vertically and horizontally.
253
+ */
254
+ _handlePageUpFlat() {
255
+ if (this._skipItemsSize === null) {
256
+ // Move the focus to the very top (as Home).
257
+ this._currentIndex -= this._currentIndex;
258
+ }
259
+
260
+ if (this._currentIndex + 1 > this._skipItemsSize) {
261
+ // When there are more than "skipItemsSize" number of items to the top,
262
+ // move the focus up/left with the predefined number.
263
+ this._currentIndex -= this._skipItemsSize;
264
+ } else {
265
+ // Otherwise, move the focus to the very top (as Home).
266
+ this._currentIndex -= this._currentIndex;
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Handles PAGE_DOWN in a flat list-like structure, both vertically and horizontally.
272
+ */
273
+ _handlePageDownFlat() {
274
+ if (this._skipItemsSize === null) {
275
+ // Move the focus to the very bottom (as End).
276
+ this._currentIndex = this._getItems().length - 1;
277
+ }
278
+
279
+ const currentToEndRange = this._getItems().length - this._currentIndex - 1;
280
+
281
+ if (currentToEndRange > this._skipItemsSize) {
282
+ // When there are more than "skipItemsSize" number of items until the bottom,
283
+ // move the focus down/right with the predefined number.
284
+ this._currentIndex += this._skipItemsSize;
285
+ } else {
286
+ // Otherwise, move the focus to the very bottom (as End).
287
+ this._currentIndex = this._getItems().length - 1;
288
+ }
289
+ }
290
+
225
291
  _applyTabIndex() {
226
292
  const items = this._getItems();
227
293
  for (let i = 0; i < items.length; i++) {
@@ -70,7 +70,13 @@ class ScrollEnablement extends EventProvider {
70
70
  this._container.scrollTop = top;
71
71
  }
72
72
 
73
- 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
+
74
80
  return scroll({
75
81
  element: this._container,
76
82
  dx,
@@ -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(),
@@ -41,16 +50,18 @@ const getConfigurationSettingsObject = () => {
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
  }
@@ -66,6 +78,7 @@ const attachListeners = () => {
66
78
  };
67
79
 
68
80
  const cssVariablesLoaded = () => {
81
+ const core = getCore();
69
82
  if (!core) {
70
83
  return;
71
84
  }
@@ -78,6 +91,26 @@ const cssVariablesLoaded = () => {
78
91
  return !!link.href.match(/\/css(-|_)variables\.css/);
79
92
  };
80
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
+
81
114
  const OpenUI5Support = {
82
115
  isLoaded,
83
116
  init,
@@ -85,6 +118,8 @@ const OpenUI5Support = {
85
118
  getLocaleDataObject,
86
119
  attachListeners,
87
120
  cssVariablesLoaded,
121
+ getNextZIndex,
122
+ setInitialZIndex,
88
123
  };
89
124
 
90
125
  registerFeature("OpenUI5Support", OpenUI5Support);
@@ -1,4 +1,4 @@
1
- const assetParameters = {"themes":{"default":"sap_fiori_3","all":["sap_fiori_3","sap_fiori_3_dark","sap_belize","sap_belize_hcb","sap_belize_hcw","sap_fiori_3_hcb","sap_fiori_3_hcw"]},"languages":{"default":"en","all":["ar","bg","ca","cs","cy","da","de","el","en","en_GB","en_US_sappsd","en_US_saprigi","en_US_saptrc","es","es_MX","et","fi","fr","fr_CA","hi","hr","hu","in","it","iw","ja","kk","ko","lt","lv","ms","nl","no","pl","pt_PT","pt","ro","ru","sh","sk","sl","sv","th","tr","uk","vi","zh_CN","zh_TW"]},"locales":{"default":"en","all":["ar","ar_EG","ar_SA","bg","ca","cs","da","de","de_AT","de_CH","el","el_CY","en","en_AU","en_GB","en_HK","en_IE","en_IN","en_NZ","en_PG","en_SG","en_ZA","es","es_AR","es_BO","es_CL","es_CO","es_MX","es_PE","es_UY","es_VE","et","fa","fi","fr","fr_BE","fr_CA","fr_CH","fr_LU","he","hi","hr","hu","id","it","it_CH","ja","kk","ko","lt","lv","ms","nb","nl","nl_BE","pl","pt","pt_PT","ro","ru","ru_UA","sk","sl","sr","sv","th","tr","uk","vi","zh_CN","zh_HK","zh_SG","zh_TW"]}};
1
+ const assetParameters = {"themes":{"default":"sap_fiori_3","all":["sap_fiori_3","sap_fiori_3_dark","sap_belize","sap_belize_hcb","sap_belize_hcw","sap_fiori_3_hcb","sap_fiori_3_hcw","sap_horizon"]},"languages":{"default":"en","all":["ar","bg","ca","cs","cy","da","de","el","en","en_GB","en_US_sappsd","en_US_saprigi","en_US_saptrc","es","es_MX","et","fi","fr","fr_CA","hi","hr","hu","in","it","iw","ja","kk","ko","lt","lv","ms","nl","no","pl","pt_PT","pt","ro","ru","sh","sk","sl","sv","th","tr","uk","vi","zh_CN","zh_TW"]},"locales":{"default":"en","all":["ar","ar_EG","ar_SA","bg","ca","cs","da","de","de_AT","de_CH","el","el_CY","en","en_AU","en_GB","en_HK","en_IE","en_IN","en_NZ","en_PG","en_SG","en_ZA","es","es_AR","es_BO","es_CL","es_CO","es_MX","es_PE","es_UY","es_VE","et","fa","fi","fr","fr_BE","fr_CA","fr_CH","fr_LU","he","hi","hr","hu","id","it","it_CH","ja","kk","ko","lt","lv","ms","nb","nl","nl_BE","pl","pt","pt_PT","ro","ru","ru_UA","sk","sl","sr","sv","th","tr","uk","vi","zh_CN","zh_HK","zh_SG","zh_TW"]}};
2
2
 
3
3
  const DEFAULT_THEME = assetParameters.themes.default;
4
4
  const DEFAULT_LANGUAGE = assetParameters.languages.default;
@@ -15,6 +15,7 @@ class I18nBundle {
15
15
  /**
16
16
  * Returns a text in the currently loaded language
17
17
  *
18
+ * @public
18
19
  * @param {Object|String} textObj key/defaultText pair or just the key
19
20
  * @param params Values for the placeholders
20
21
  * @returns {*}
@@ -29,6 +30,9 @@ class I18nBundle {
29
30
  }
30
31
 
31
32
  const bundle = getI18nBundleData(this.packageName);
33
+ if (bundle && !bundle[textObj.key]) {
34
+ console.warn(`Key ${textObj.key} not found in the i18n bundle, the default text will be used`); // eslint-disable-line
35
+ }
32
36
  const messageText = bundle && bundle[textObj.key] ? bundle[textObj.key] : (textObj.defaultText || textObj.key);
33
37
 
34
38
  return formatMessage(messageText, params);
@@ -1,31 +1,32 @@
1
- import { html, svg, render } from "lit-html/lit-html.js";
2
- import scopeHTML from "./scopeHTML.js";
1
+ import { render } from "lit-html";
2
+ import {
3
+ html,
4
+ svg,
5
+ unsafeStatic,
6
+ } from "lit-html/static.js";
3
7
 
4
- let tags;
5
- let suffix;
6
-
7
- const setTags = t => {
8
- tags = t;
9
- };
10
- const setSuffix = s => {
11
- suffix = s;
12
- };
13
-
14
- const litRender = (templateResult, domNode, styles, { eventContext } = {}) => {
8
+ const litRender = (templateResult, domNode, styles, { host } = {}) => {
15
9
  if (styles) {
16
10
  templateResult = html`<style>${styles}</style>${templateResult}`;
17
11
  }
18
- render(templateResult, domNode, { eventContext });
12
+ render(templateResult, domNode, { host });
19
13
  };
20
14
 
21
- const scopedHtml = (strings, ...values) => html(scopeHTML(strings, tags, suffix), ...values);
22
- const scopedSvg = (strings, ...values) => svg(scopeHTML(strings, tags, suffix), ...values);
15
+ const scopeTag = (tag, tags, suffix) => {
16
+ const resultTag = suffix && (tags || []).includes(tag) ? `${tag}-${suffix}` : tag;
17
+ return unsafeStatic(resultTag);
18
+ };
23
19
 
24
- export { setTags, setSuffix };
25
- export { scopedHtml as html, scopedSvg as svg };
20
+ export {
21
+ html,
22
+ svg,
23
+ unsafeStatic,
24
+ };
25
+ export { scopeTag };
26
26
  export { repeat } from "lit-html/directives/repeat.js";
27
27
  export { classMap } from "lit-html/directives/class-map.js";
28
28
  export { styleMap } from "lit-html/directives/style-map.js";
29
+ export { ifDefined } from "lit-html/directives/if-defined.js";
29
30
  export { unsafeHTML } from "lit-html/directives/unsafe-html.js";
30
31
 
31
32
  export default litRender;