@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
@@ -1,9 +1,9 @@
1
1
  import findNodeOwner from "./findNodeOwner.js";
2
2
 
3
3
  const getEffectiveAriaLabelText = el => {
4
- if (!el.ariaLabelledby) {
5
- if (el.ariaLabel) {
6
- return el.ariaLabel;
4
+ if (!el.accessibleNameRef) {
5
+ if (el.accessibleName) {
6
+ return el.accessibleName;
7
7
  }
8
8
 
9
9
  return undefined;
@@ -19,7 +19,7 @@ const getEffectiveAriaLabelText = el => {
19
19
  * @param {String} readyIds (Optional) Defines a string of elements ids. The text of these elements will be returned. If used you should provide either el or ownerDocument
20
20
  */
21
21
  const getAriaLabelledByTexts = (el, ownerDocument, readyIds = "") => {
22
- const ids = (readyIds && readyIds.split(" ")) || el.ariaLabelledby.split(" ");
22
+ const ids = (readyIds && readyIds.split(" ")) || el.accessibleNameRef.split(" ");
23
23
  const owner = ownerDocument || findNodeOwner(el);
24
24
  let result = "";
25
25
 
@@ -21,6 +21,10 @@ const getLastFocusableElement = async container => {
21
21
  return findFocusableElement(container, false);
22
22
  };
23
23
 
24
+ const isElemFocusable = el => {
25
+ return el.hasAttribute("data-ui5-focus-redirect") || !isNodeHidden(el);
26
+ };
27
+
24
28
  const findFocusableElement = async (container, forward) => {
25
29
  let child;
26
30
 
@@ -48,7 +52,7 @@ const findFocusableElement = async (container, forward) => {
48
52
  return null;
49
53
  }
50
54
 
51
- if (child.nodeType === 1 && !isNodeHidden(child) && !isFocusTrap(child)) {
55
+ if (child.nodeType === 1 && isElemFocusable(child) && !isFocusTrap(child)) {
52
56
  if (isNodeClickable(child)) {
53
57
  return (child && typeof child.focus === "function") ? child : null;
54
58
  }
@@ -0,0 +1,7 @@
1
+ import sanitizeHTML from "../sap/base/security/sanitizeHTML.js";
2
+ import URLListValidator from "../sap/base/security/URLListValidator.js";
3
+
4
+ export {
5
+ URLListValidator,
6
+ sanitizeHTML,
7
+ };
@@ -0,0 +1,58 @@
1
+ import InvisibleMessageMode from "../types/InvisibleMessageMode.js";
2
+ import getSingletonElementInstance from "./getSingletonElementInstance.js";
3
+ import { attachBoot } from "../Boot.js";
4
+
5
+ let politeSpan;
6
+ let assertiveSpan;
7
+
8
+ attachBoot(() => {
9
+ if (politeSpan && assertiveSpan) {
10
+ return;
11
+ }
12
+
13
+ const styles = `position: absolute;
14
+ clip: rect(1px,1px,1px,1px);
15
+ user-select: none;
16
+ left: -1000px;
17
+ top: -1000px;
18
+ pointer-events: none;`;
19
+
20
+ politeSpan = document.createElement("span");
21
+ assertiveSpan = document.createElement("span");
22
+
23
+ politeSpan.classList.add("ui5-invisiblemessage-polite");
24
+ assertiveSpan.classList.add("ui5-invisiblemessage-assertive");
25
+
26
+ politeSpan.setAttribute("aria-live", "polite");
27
+ assertiveSpan.setAttribute("aria-live", "assertive");
28
+
29
+ politeSpan.setAttribute("role", "alert");
30
+ assertiveSpan.setAttribute("role", "alert");
31
+
32
+ politeSpan.style.cssText = styles;
33
+ assertiveSpan.style.cssText = styles;
34
+
35
+ getSingletonElementInstance("ui5-static-area").appendChild(politeSpan);
36
+ getSingletonElementInstance("ui5-static-area").appendChild(assertiveSpan);
37
+ });
38
+
39
+ /**
40
+ * Inserts the string into the respective span, depending on the mode provided.
41
+ *
42
+ * @param {string} message String to be announced by the screen reader.
43
+ * @param {sap.ui.core.InvisibleMessageMode} mode The mode to be inserted in the aria-live attribute.
44
+ */
45
+ const announce = (message, mode) => {
46
+ // If no type is presented, fallback to polite announcement.
47
+ const span = mode === InvisibleMessageMode.Assertive ? assertiveSpan : politeSpan;
48
+
49
+ // Set textContent to empty string in order to trigger screen reader's announcement.
50
+ span.textContent = "";
51
+ span.textContent = message;
52
+
53
+ if (mode !== InvisibleMessageMode.Assertive && mode !== InvisibleMessageMode.Polite) {
54
+ console.warn(`You have entered an invalid mode. Valid values are: "Polite" and "Assertive". The framework will automatically set the mode to "Polite".`); // eslint-disable-line
55
+ }
56
+ };
57
+
58
+ export default announce;
@@ -0,0 +1,93 @@
1
+ import getSharedResource from "../getSharedResource.js";
2
+ import { getFeature } from "../FeaturesRegistry.js";
3
+ import getActiveElement from "./getActiveElement.js";
4
+
5
+ const PopupUtilsData = getSharedResource("PopupUtilsData", {});
6
+ PopupUtilsData.currentZIndex = PopupUtilsData.currentZIndex || 100;
7
+
8
+ const getFocusedElement = () => {
9
+ const element = getActiveElement();
10
+ return (element && typeof element.focus === "function") ? element : null;
11
+ };
12
+
13
+ const isFocusedElementWithinNode = node => {
14
+ const fe = getFocusedElement();
15
+
16
+ if (fe) {
17
+ return isNodeContainedWithin(node, fe);
18
+ }
19
+
20
+ return false;
21
+ };
22
+
23
+ const isNodeContainedWithin = (parent, child) => {
24
+ let currentNode = parent;
25
+
26
+ if (currentNode.shadowRoot) {
27
+ currentNode = Array.from(currentNode.shadowRoot.children).find(n => n.localName !== "style");
28
+ }
29
+
30
+ if (currentNode === child) {
31
+ return true;
32
+ }
33
+
34
+ const childNodes = currentNode.localName === "slot" ? currentNode.assignedNodes() : currentNode.children;
35
+
36
+ if (childNodes) {
37
+ return Array.from(childNodes).some(n => isNodeContainedWithin(n, child));
38
+ }
39
+ };
40
+
41
+ const isPointInRect = (x, y, rect) => {
42
+ return x >= rect.left && x <= rect.right
43
+ && y >= rect.top && y <= rect.bottom;
44
+ };
45
+
46
+ const isClickInRect = (event, rect) => {
47
+ let x;
48
+ let y;
49
+
50
+ if (event.touches) {
51
+ const touch = event.touches[0];
52
+ x = touch.clientX;
53
+ y = touch.clientY;
54
+ } else {
55
+ x = event.clientX;
56
+ y = event.clientY;
57
+ }
58
+
59
+ return isPointInRect(x, y, rect);
60
+ };
61
+
62
+ const getClosedPopupParent = el => {
63
+ const parent = el.parentElement || (el.getRootNode && el.getRootNode().host);
64
+
65
+ if (parent && ((parent.showAt && parent.isUI5Element) || (parent.open && parent.isUI5Element) || parent === document.documentElement)) {
66
+ return parent;
67
+ }
68
+
69
+ return getClosedPopupParent(parent);
70
+ };
71
+
72
+ const getNextZIndex = () => {
73
+ const OpenUI5Support = getFeature("OpenUI5Support");
74
+ if (OpenUI5Support && OpenUI5Support.isLoaded()) { // use OpenUI5 for getting z-index values, if loaded
75
+ return OpenUI5Support.getNextZIndex();
76
+ }
77
+
78
+ PopupUtilsData.currentZIndex += 2;
79
+ return PopupUtilsData.currentZIndex;
80
+ };
81
+
82
+ const getCurrentZIndex = () => {
83
+ return PopupUtilsData.currentZIndex;
84
+ };
85
+
86
+ export {
87
+ getFocusedElement,
88
+ isClickInRect,
89
+ getClosedPopupParent,
90
+ getNextZIndex,
91
+ getCurrentZIndex,
92
+ isFocusedElementWithinNode,
93
+ };
@@ -17,7 +17,7 @@ const getTabbables = (nodes, tabbables) => {
17
17
  }
18
18
 
19
19
  Array.from(nodes).forEach(currentNode => {
20
- if (currentNode.nodeType === Node.TEXT_NODE || currentNode.nodeType === Node.COMMENT_NODE) {
20
+ if (currentNode.nodeType === Node.TEXT_NODE || currentNode.nodeType === Node.COMMENT_NODE || currentNode.hasAttribute("data-sap-no-tab-ref")) {
21
21
  return;
22
22
  }
23
23
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Returns a value clamped between an upper bound 'max' and lower bound 'min'.
3
+ * @param {number} val value
4
+ * @param {number} min lower bound
5
+ * @param {number} max upper bound
6
+ * @returns {number}
7
+ */
8
+ const clamp = (val, min, max) => {
9
+ return Math.min(Math.max(val, min), max);
10
+ };
11
+
12
+ export default clamp;
@@ -0,0 +1,10 @@
1
+ const getClassCopy = (klass, constructorCallback) => {
2
+ return class classCopy extends klass {
3
+ constructor() {
4
+ super();
5
+ constructorCallback && constructorCallback();
6
+ }
7
+ };
8
+ };
9
+
10
+ export default getClassCopy;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Determines if the element is within the viewport.
3
+ * @param el {HTMLElement}
4
+ */
5
+ const isElementInView = el => {
6
+ const rect = el.getBoundingClientRect();
7
+
8
+ return (
9
+ rect.top >= 0 && rect.left >= 0
10
+ && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
11
+ && rect.right <= (window.innerWidth || document.documentElement.clientWidth)
12
+ );
13
+ };
14
+
15
+ export default isElementInView;
@@ -15,14 +15,14 @@ const isNodeTabbable = node => {
15
15
  return false;
16
16
  }
17
17
 
18
- if (nodeName === "a" || /input|select|textarea|button|object/.test(nodeName)) {
19
- return !node.disabled;
20
- }
21
-
22
18
  const tabIndex = node.getAttribute("tabindex");
23
19
  if (tabIndex !== null && tabIndex !== undefined) {
24
20
  return parseInt(tabIndex) >= 0;
25
21
  }
22
+
23
+ if (nodeName === "a" || /input|select|textarea|button|object/.test(nodeName)) {
24
+ return !node.disabled;
25
+ }
26
26
  };
27
27
 
28
28
  export default isNodeTabbable;
@@ -0,0 +1,7 @@
1
+ # Needed files from OpenUI5
2
+
3
+ sap/base/util/now.js
4
+ sap/base/Log.js
5
+ sap/base/assert.js
6
+ sap/base/security/URLListValidator.js
7
+ sap/base/security/sanitizeHTML.js
@@ -1,17 +0,0 @@
1
- import { getAssetsPath as getConfiguredAssetsPath } from "../InitialConfiguration.js";
2
-
3
- let assetsPath;
4
-
5
- const getAssetsPath = () => {
6
- if (assetsPath === undefined) {
7
- assetsPath = getConfiguredAssetsPath();
8
- }
9
-
10
- return assetsPath;
11
- };
12
-
13
- const setAssetsPath = newAssetsPath => {
14
- assetsPath = newAssetsPath;
15
- };
16
-
17
- export { getAssetsPath, setAssetsPath }; // eslint-disable-line
@@ -1,21 +0,0 @@
1
- import {
2
- AttributePart,
3
- directive,
4
- noChange,
5
- } from "lit-html/lit-html.js";
6
-
7
- /*
8
- lit-html directive that removes and attribute if it is undefined
9
- */
10
- export default directive(value => part => {
11
- if ((value === undefined) && part instanceof AttributePart) {
12
- if (value !== part.value) {
13
- const name = part.committer.name;
14
- part.committer.element.removeAttribute(name);
15
- }
16
- } else if (part.committer && part.committer.element && part.committer.element.getAttribute(part.committer.name) === value) {
17
- part.setValue(noChange);
18
- } else {
19
- part.setValue(value);
20
- }
21
- });
@@ -1,32 +0,0 @@
1
- const cache = new Map();
2
-
3
- const scopeHTML = (strings, tags, suffix) => {
4
- if (suffix && tags && tags.length) {
5
- strings = strings.map(string => {
6
- if (cache.has(string)) {
7
- return cache.get(string);
8
- }
9
-
10
- /*
11
- const allTags = [...string.matchAll(/<(ui5-.*?)[> ]/g)].map(x => x[1]);
12
- allTags.forEach(t => {
13
- if (!tags.includes(t)) {
14
- throw new Error(`${t} not found in ${string}`);
15
- // console.log(t, " in ", string);
16
- }
17
- });
18
- */
19
-
20
- let result = string;
21
- tags.forEach(tag => {
22
- result = result.replace(new RegExp(`(</?)(${tag})(/?[> \t\n])`, "g"), `$1$2-${suffix}$3`);
23
- });
24
- cache.set(string, result);
25
- return result;
26
- });
27
- }
28
-
29
- return strings;
30
- };
31
-
32
- export default scopeHTML;
@@ -1,17 +0,0 @@
1
- import { getAssetsPath as getConfiguredAssetsPath } from "../InitialConfiguration.js";
2
-
3
- let assetsPath;
4
-
5
- const getAssetsPath = () => {
6
- if (assetsPath === undefined) {
7
- assetsPath = getConfiguredAssetsPath();
8
- }
9
-
10
- return assetsPath;
11
- };
12
-
13
- const setAssetsPath = newAssetsPath => {
14
- assetsPath = newAssetsPath;
15
- };
16
-
17
- export { getAssetsPath, setAssetsPath }; // eslint-disable-line
@@ -1,21 +0,0 @@
1
- import {
2
- AttributePart,
3
- directive,
4
- noChange,
5
- } from "lit-html/lit-html.js";
6
-
7
- /*
8
- lit-html directive that removes and attribute if it is undefined
9
- */
10
- export default directive(value => part => {
11
- if ((value === undefined) && part instanceof AttributePart) {
12
- if (value !== part.value) {
13
- const name = part.committer.name;
14
- part.committer.element.removeAttribute(name);
15
- }
16
- } else if (part.committer && part.committer.element && part.committer.element.getAttribute(part.committer.name) === value) {
17
- part.setValue(noChange);
18
- } else {
19
- part.setValue(value);
20
- }
21
- });
@@ -1,32 +0,0 @@
1
- const cache = new Map();
2
-
3
- const scopeHTML = (strings, tags, suffix) => {
4
- if (suffix && tags && tags.length) {
5
- strings = strings.map(string => {
6
- if (cache.has(string)) {
7
- return cache.get(string);
8
- }
9
-
10
- /*
11
- const allTags = [...string.matchAll(/<(ui5-.*?)[> ]/g)].map(x => x[1]);
12
- allTags.forEach(t => {
13
- if (!tags.includes(t)) {
14
- throw new Error(`${t} not found in ${string}`);
15
- // console.log(t, " in ", string);
16
- }
17
- });
18
- */
19
-
20
- let result = string;
21
- tags.forEach(tag => {
22
- result = result.replace(new RegExp(`(</?)(${tag})(/?[> \t\n])`, "g"), `$1$2-${suffix}$3`);
23
- });
24
- cache.set(string, result);
25
- return result;
26
- });
27
- }
28
-
29
- return strings;
30
- };
31
-
32
- export default scopeHTML;