@ui5/webcomponents-base 0.0.0-2c7615fe9 → 0.0.0-3236d56be

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 (147) hide show
  1. package/.eslintignore +3 -2
  2. package/CHANGELOG.md +199 -0
  3. package/README.md +26 -2
  4. package/bundle.esm.js +3 -2
  5. package/dist/Boot.js +34 -18
  6. package/dist/CSP.js +59 -0
  7. package/dist/CustomElementsRegistry.js +60 -4
  8. package/dist/CustomElementsScope.js +20 -98
  9. package/dist/CustomElementsScopeUtils.js +108 -0
  10. package/dist/Device.js +20 -1
  11. package/dist/EventProvider.js +5 -2
  12. package/dist/FeaturesRegistry.js +4 -1
  13. package/dist/FontFace.js +7 -95
  14. package/dist/InitialConfiguration.js +11 -7
  15. package/dist/Keys.js +47 -0
  16. package/dist/ManagedStyles.js +83 -0
  17. package/dist/Render.js +3 -1
  18. package/dist/Runtimes.js +107 -0
  19. package/dist/StaticAreaItem.js +4 -10
  20. package/dist/SystemCSSVars.js +4 -25
  21. package/dist/UI5Element.js +31 -24
  22. package/dist/UI5ElementMetadata.js +17 -1
  23. package/dist/asset-registries/Icons.js +21 -14
  24. package/dist/asset-registries/Illustrations.js +10 -3
  25. package/dist/asset-registries/LocaleData.js +17 -3
  26. package/dist/assets-meta/IconCollectionsAlias.js +18 -0
  27. package/dist/config/Icons.js +52 -0
  28. package/dist/config/Theme.js +25 -0
  29. package/dist/css/BusyIndicator.css +76 -0
  30. package/dist/css/FontFace.css +75 -0
  31. package/dist/css/OverrideFontFace.css +32 -0
  32. package/dist/css/SystemCSSVars.css +17 -0
  33. package/dist/features/F6Navigation.js +108 -0
  34. package/dist/features/OpenUI5Enablement.js +119 -0
  35. package/dist/generated/AssetParameters.js +1 -1
  36. package/dist/generated/VersionInfo.js +10 -0
  37. package/dist/generated/css/BusyIndicator.css.js +5 -0
  38. package/dist/generated/css/FontFace.css.js +5 -0
  39. package/dist/generated/css/OverrideFontFace.css.js +5 -0
  40. package/dist/generated/css/SystemCSSVars.css.js +5 -0
  41. package/dist/i18nBundle.js +33 -2
  42. package/dist/renderer/LitRenderer.js +32 -12
  43. package/dist/renderer/directives/style-map.js +72 -0
  44. package/dist/renderer/executeTemplate.js +19 -2
  45. package/dist/resources/bundle.esm.js +14 -8
  46. package/dist/resources/bundle.esm.js.map +1 -1
  47. package/dist/sap/base/Log.js +2 -10
  48. package/dist/sap/base/assert.js +1 -5
  49. package/dist/sap/base/security/encodeCSS.js +14 -0
  50. package/dist/sap/base/security/encodeXML.js +23 -0
  51. package/dist/sap/base/strings/toHex.js +8 -0
  52. package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +1 -1
  53. package/dist/test-resources/pages/i18n.html +1 -3
  54. package/dist/test-resources/specs/ConfigurationChange.spec.js +9 -9
  55. package/dist/test-resources/specs/ConfigurationScript.spec.js +24 -24
  56. package/dist/test-resources/specs/ConfigurationURL.spec.js +33 -33
  57. package/dist/test-resources/specs/CustomTheme.spec.js +7 -7
  58. package/dist/test-resources/specs/EventProvider.spec.js +63 -0
  59. package/dist/test-resources/specs/StaticArea.spec.js +35 -35
  60. package/dist/test-resources/specs/Theming.spec.js +11 -11
  61. package/dist/test-resources/specs/UI5ElementInvalidation.js +29 -29
  62. package/dist/test-resources/specs/UI5ElementLifecycle.js +11 -11
  63. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +11 -11
  64. package/dist/test-resources/specs/UI5ElementMetadataExt.js +8 -8
  65. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +6 -6
  66. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +36 -36
  67. package/dist/test-resources/specs/UI5ElementShadowDOM.js +9 -9
  68. package/dist/test-resources/specs/UI5ElementSlots.js +9 -9
  69. package/dist/theming/CustomStyle.js +23 -3
  70. package/dist/theming/applyTheme.js +11 -10
  71. package/dist/theming/getEffectiveLinksHrefs.js +27 -0
  72. package/dist/theming/getEffectiveStyle.js +9 -0
  73. package/dist/theming/getStylesString.js +4 -2
  74. package/dist/theming/getThemeDesignerTheme.js +25 -5
  75. package/dist/theming/preloadLinks.js +23 -0
  76. package/dist/updateShadowRoot.js +8 -4
  77. package/dist/util/FocusableElements.js +8 -6
  78. package/dist/util/InvisibleMessage.js +11 -9
  79. package/dist/util/TabbableElements.js +4 -0
  80. package/dist/util/createLinkInHead.js +19 -0
  81. package/dist/util/escapeRegex.js +10 -0
  82. package/dist/util/generateHighlightedMarkup.js +42 -0
  83. package/dist/util/getNormalizedTarget.js +16 -0
  84. package/dist/util/isNodeHidden.js +1 -1
  85. package/lib/generate-asset-parameters/index.js +8 -5
  86. package/lib/generate-styles/index.js +26 -0
  87. package/lib/generate-version-info/index.js +32 -0
  88. package/package-scripts.js +12 -16
  89. package/package.json +10 -12
  90. package/src/Boot.js +34 -18
  91. package/src/CSP.js +59 -0
  92. package/src/CustomElementsRegistry.js +60 -4
  93. package/src/CustomElementsScope.js +20 -98
  94. package/src/CustomElementsScopeUtils.js +108 -0
  95. package/src/Device.js +20 -1
  96. package/src/EventProvider.js +5 -2
  97. package/src/FeaturesRegistry.js +4 -1
  98. package/src/FontFace.js +7 -95
  99. package/src/InitialConfiguration.js +11 -7
  100. package/src/Keys.js +47 -0
  101. package/src/ManagedStyles.js +83 -0
  102. package/src/Render.js +3 -1
  103. package/src/Runtimes.js +107 -0
  104. package/src/StaticAreaItem.js +4 -10
  105. package/src/SystemCSSVars.js +4 -25
  106. package/src/UI5Element.js +31 -24
  107. package/src/UI5ElementMetadata.js +17 -1
  108. package/src/asset-registries/Icons.js +21 -14
  109. package/src/asset-registries/Illustrations.js +10 -3
  110. package/src/asset-registries/LocaleData.js +17 -3
  111. package/src/assets-meta/IconCollectionsAlias.js +18 -0
  112. package/src/config/Icons.js +52 -0
  113. package/src/config/Theme.js +25 -0
  114. package/src/css/BusyIndicator.css +76 -0
  115. package/src/css/FontFace.css +75 -0
  116. package/src/css/OverrideFontFace.css +32 -0
  117. package/src/css/SystemCSSVars.css +17 -0
  118. package/src/features/F6Navigation.js +108 -0
  119. package/src/features/OpenUI5Enablement.js +119 -0
  120. package/src/i18nBundle.js +33 -2
  121. package/src/renderer/LitRenderer.js +32 -12
  122. package/src/renderer/directives/style-map.js +72 -0
  123. package/src/renderer/executeTemplate.js +19 -2
  124. package/src/theming/CustomStyle.js +23 -3
  125. package/src/theming/applyTheme.js +11 -10
  126. package/src/theming/getEffectiveLinksHrefs.js +27 -0
  127. package/src/theming/getEffectiveStyle.js +9 -0
  128. package/src/theming/getStylesString.js +4 -2
  129. package/src/theming/getThemeDesignerTheme.js +25 -5
  130. package/src/theming/preloadLinks.js +23 -0
  131. package/src/updateShadowRoot.js +8 -4
  132. package/src/util/FocusableElements.js +8 -6
  133. package/src/util/InvisibleMessage.js +11 -9
  134. package/src/util/TabbableElements.js +4 -0
  135. package/src/util/createLinkInHead.js +19 -0
  136. package/src/util/escapeRegex.js +10 -0
  137. package/src/util/generateHighlightedMarkup.js +42 -0
  138. package/src/util/getNormalizedTarget.js +16 -0
  139. package/src/util/isNodeHidden.js +1 -1
  140. package/used-modules.txt +4 -1
  141. package/dist/config/AssetsPath.js +0 -17
  142. package/dist/theming/createThemePropertiesStyleTag.js +0 -20
  143. package/dist/util/encodeCSS.js +0 -24
  144. package/hash.txt +0 -1
  145. package/src/config/AssetsPath.js +0 -17
  146. package/src/theming/createThemePropertiesStyleTag.js +0 -20
  147. package/src/util/encodeCSS.js +0 -24
@@ -0,0 +1,108 @@
1
+ let suf;
2
+ let rulesObj = {
3
+ include: [/^ui5-/],
4
+ exclude: [],
5
+ };
6
+ const tagsCache = new Map(); // true/false means the tag should/should not be cached, undefined means not known yet.
7
+
8
+ /**
9
+ * Sets the suffix to be used for custom elements scoping, f.e. pass "demo" to get tags such as "ui5-button-demo".
10
+ * Note: by default all tags starting with "ui5-" will be scoped, unless you change this by calling "setCustomElementsScopingRules"
11
+ *
12
+ * @public
13
+ * @param suffix The scoping suffix
14
+ */
15
+ const setCustomElementsScopingSuffix = suffix => {
16
+ if (!suffix.match(/^[a-zA-Z0-9_-]+$/)) {
17
+ throw new Error("Only alphanumeric characters and dashes allowed for the scoping suffix");
18
+ }
19
+
20
+ suf = suffix;
21
+ };
22
+
23
+ /**
24
+ * Returns the currently set scoping suffix, or undefined if not set.
25
+ *
26
+ * @public
27
+ * @returns {String|undefined}
28
+ */
29
+ const getCustomElementsScopingSuffix = () => {
30
+ return suf;
31
+ };
32
+
33
+ /**
34
+ * Sets the rules, governing which custom element tags to scope and which not, f.e.
35
+ * setCustomElementsScopingRules({include: [/^ui5-/]}, exclude: [/^ui5-mylib-/, /^ui5-carousel$/]);
36
+ * will scope all elements starting with "ui5-" but not the ones starting with "ui5-mylib-" and not "ui5-carousel".
37
+ *
38
+ * @public
39
+ * @param rules Object with "include" and "exclude" properties, both arrays of regular expressions. Note that "include"
40
+ * rules are applied first and "exclude" rules second.
41
+ */
42
+ const setCustomElementsScopingRules = rules => {
43
+ if (!rules || !rules.include) {
44
+ throw new Error(`"rules" must be an object with at least an "include" property`);
45
+ }
46
+
47
+ if (!Array.isArray(rules.include) || rules.include.some(rule => !(rule instanceof RegExp))) {
48
+ throw new Error(`"rules.include" must be an array of regular expressions`);
49
+ }
50
+
51
+ if (rules.exclude && (!Array.isArray(rules.exclude) || rules.exclude.some(rule => !(rule instanceof RegExp)))) {
52
+ throw new Error(`"rules.exclude" must be an array of regular expressions`);
53
+ }
54
+
55
+ rules.exclude = rules.exclude || [];
56
+ rulesObj = rules;
57
+ tagsCache.clear(); // reset the cache upon setting new rules
58
+ };
59
+
60
+ /**
61
+ * Returns the rules, governing which custom element tags to scope and which not. By default, all elements
62
+ * starting with "ui5-" are scoped. The default rules are: {include: [/^ui5-/]}.
63
+ *
64
+ * @public
65
+ * @returns {Object}
66
+ */
67
+ const getCustomElementsScopingRules = () => {
68
+ return rulesObj;
69
+ };
70
+
71
+ /**
72
+ * Determines whether custom elements with the given tag should be scoped or not.
73
+ * The tag is first matched against the "include" rules and then against the "exclude" rules and the
74
+ * result is cached until new rules are set.
75
+ *
76
+ * @public
77
+ * @param tag
78
+ */
79
+ const shouldScopeCustomElement = tag => {
80
+ if (!tagsCache.has(tag)) {
81
+ const result = rulesObj.include.some(rule => tag.match(rule)) && !rulesObj.exclude.some(rule => tag.match(rule));
82
+ tagsCache.set(tag, result);
83
+ }
84
+
85
+ return tagsCache.get(tag);
86
+ };
87
+
88
+ /**
89
+ * Returns the currently set scoping suffix, if any and if the tag should be scoped, or undefined otherwise.
90
+ *
91
+ * @public
92
+ * @param tag
93
+ * @returns {String}
94
+ */
95
+ const getEffectiveScopingSuffixForTag = tag => {
96
+ if (shouldScopeCustomElement(tag)) {
97
+ return getCustomElementsScopingSuffix();
98
+ }
99
+ };
100
+
101
+ export {
102
+ setCustomElementsScopingSuffix,
103
+ getCustomElementsScopingSuffix,
104
+ setCustomElementsScopingRules,
105
+ getCustomElementsScopingRules,
106
+ shouldScopeCustomElement,
107
+ getEffectiveScopingSuffixForTag,
108
+ };
package/dist/Device.js CHANGED
@@ -5,9 +5,13 @@ const chrome = !ie && /(Chrome|CriOS)/.test(ua);
5
5
  const safari = !ie && !chrome && /(Version|PhantomJS)\/(\d+\.\d+).*Safari/.test(ua);
6
6
  const webkit = !ie && /webkit/.test(ua);
7
7
  const windows = navigator.platform.indexOf("Win") !== -1;
8
+ const iOS = navigator.platform.match(/iPhone|iPad|iPod/) || (navigator.userAgent.match(/Mac/) && "ontouchend" in document);
8
9
  const android = !windows && /Android/.test(ua);
9
10
  const androidPhone = android && /(?=android)(?=.*mobile)/i.test(ua);
10
- const ipad = /ipad/i.test(ua);
11
+ const ipad = /ipad/i.test(ua) || (/Macintosh/i.test(ua) && "ontouchend" in document);
12
+ // With iOS 13 the string 'iPad' was removed from the user agent string through a browser setting, which is applied on all sites by default:
13
+ // "Request Desktop Website -> All websites" (for more infos see: https://forums.developer.apple.com/thread/119186).
14
+ // Therefore the OS is detected as MACINTOSH instead of iOS and the device is a tablet if the Device.support.touch is true.
11
15
 
12
16
  let windowsVersion;
13
17
  let webkitVersion;
@@ -91,6 +95,18 @@ const isDesktop = () => {
91
95
  return (!isTablet() && !isPhone()) || isWindows8OrAbove();
92
96
  };
93
97
 
98
+ const isCombi = () => {
99
+ return isTablet() && isDesktop();
100
+ };
101
+
102
+ const isIOS = () => {
103
+ return iOS;
104
+ };
105
+
106
+ const isAndroid = () => {
107
+ return android || androidPhone;
108
+ };
109
+
94
110
  export {
95
111
  supportsTouch,
96
112
  isIE,
@@ -99,4 +115,7 @@ export {
99
115
  isPhone,
100
116
  isTablet,
101
117
  isDesktop,
118
+ isCombi,
119
+ isIOS,
120
+ isAndroid,
102
121
  };
@@ -19,13 +19,16 @@ class EventProvider {
19
19
 
20
20
  detachEvent(eventName, fnFunction) {
21
21
  const eventRegistry = this._eventRegistry;
22
- let eventListeners = eventRegistry.get(eventName);
22
+ const eventListeners = eventRegistry.get(eventName);
23
23
 
24
24
  if (!eventListeners) {
25
25
  return;
26
26
  }
27
+ const indexOfFnToDetach = eventListeners.indexOf(fnFunction);
27
28
 
28
- eventListeners = eventListeners.filter(fn => fn !== fnFunction);
29
+ if (indexOfFnToDetach !== -1) {
30
+ eventListeners.splice(indexOfFnToDetach, 1);
31
+ }
29
32
 
30
33
  if (eventListeners.length === 0) {
31
34
  eventRegistry.delete(eventName);
@@ -8,4 +8,7 @@ const getFeature = name => {
8
8
  return features.get(name);
9
9
  };
10
10
 
11
- export { registerFeature, getFeature };
11
+ export {
12
+ registerFeature,
13
+ getFeature,
14
+ };
package/dist/FontFace.js CHANGED
@@ -1,95 +1,7 @@
1
- /**
2
- * CSS font face used for the texts provided by SAP.
3
- */
4
- import createStyleInHead from "./util/createStyleInHead.js";
1
+ import { hasStyle, createStyle } from "./ManagedStyles.js";
5
2
  import { getFeature } from "./FeaturesRegistry.js";
6
-
7
- /* CDN Locations */
8
- const font72RegularWoff = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff?ui5-webcomponents`;
9
- const font72RegularWoff2 = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff2?ui5-webcomponents`;
10
-
11
- const font72RegularFullWoff = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff?ui5-webcomponents`;
12
- const font72RegularFullWoff2 = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff2?ui5-webcomponents`;
13
-
14
- const font72BoldWoff = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff?ui5-webcomponents`;
15
- const font72BoldWoff2 = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents`;
16
-
17
- const font72BoldFullWoff = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff?ui5-webcomponents`;
18
- const font72BoldFullWoff2 = `https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents`;
19
-
20
- const fontFaceCSS = `
21
- @font-face {
22
- font-family: "72";
23
- font-style: normal;
24
- font-weight: 400;
25
- src: local("72"),
26
- url(${font72RegularWoff2}) format("woff2"),
27
- url(${font72RegularWoff}) format("woff");
28
- }
29
-
30
- @font-face {
31
- font-family: "72full";
32
- font-style: normal;
33
- font-weight: 400;
34
- src: local('72-full'),
35
- url(${font72RegularFullWoff2}) format("woff2"),
36
- url(${font72RegularFullWoff}) format("woff");
37
-
38
- }
39
-
40
- @font-face {
41
- font-family: "72";
42
- font-style: normal;
43
- font-weight: 700;
44
- src: local('72-Bold'),
45
- url(${font72BoldWoff2}) format("woff2"),
46
- url(${font72BoldWoff}) format("woff");
47
- }
48
-
49
- @font-face {
50
- font-family: "72full";
51
- font-style: normal;
52
- font-weight: 700;
53
- src: local('72-Bold-full'),
54
- url(${font72BoldFullWoff2}) format("woff2"),
55
- url(${font72BoldFullWoff}) format("woff");
56
- }
57
- `;
58
-
59
- /**
60
- * Some diacritics are supported by the 72 font:
61
- * * Grave
62
- * * Acute
63
- * * Circumflex
64
- * * Tilde
65
- *
66
- * However, the following diacritics and the combination of multiple diacritics (including the supported ones) are not supported:
67
- * * Breve
68
- * * Horn
69
- * * Dot below
70
- * * Hook above
71
- *
72
- *
73
- * Override for the characters that aren't covered by the '72' font to other system fonts
74
- *
75
- * U+0102-0103: A and a with Breve
76
- * U+01A0-01A1: O and o with Horn
77
- * U+01AF-01B0: U and u with Horn
78
- * U+1EA0-1EB7: A and a with diacritics that are not supported by the font and combination of multiple diacritics
79
- * U+1EB8-1EC7: E and e with diacritics that are not supported by the font and combination of multiple diacritics
80
- * U+1EC8-1ECB: I and i with diacritics that are not supported by the font and combination of multiple diacritics
81
- * U+1ECC-1EE3: O and o with diacritics that are not supported by the font and combination of multiple diacritics
82
- * U+1EE4-1EF1: U and u with diacritics that are not supported by the font and combination of multiple diacritics
83
- * U+1EF4-1EF7: Y and y with diacritics that are not supported by the font and combination of multiple diacritics
84
- *
85
- */
86
- const overrideFontFaceCSS = `
87
- @font-face {
88
- font-family: '72override';
89
- unicode-range: U+0102-0103, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, U+1EE4-1EF1, U+1EF4-1EF7;
90
- src: local('Arial'), local('Helvetica'), local('sans-serif');
91
- }
92
- `;
3
+ import fontFaceCSS from "./generated/css/FontFace.css.js";
4
+ import overrideFontFaceCSS from "./generated/css/OverrideFontFace.css.js";
93
5
 
94
6
  const insertFontFace = () => {
95
7
  const OpenUI5Support = getFeature("OpenUI5Support");
@@ -104,14 +16,14 @@ const insertFontFace = () => {
104
16
  };
105
17
 
106
18
  const insertMainFontFace = () => {
107
- if (!document.querySelector(`head>style[data-ui5-font-face]`)) {
108
- createStyleInHead(fontFaceCSS, { "data-ui5-font-face": "" });
19
+ if (!hasStyle("data-ui5-font-face")) {
20
+ createStyle(fontFaceCSS, "data-ui5-font-face");
109
21
  }
110
22
  };
111
23
 
112
24
  const insertOverrideFontFace = () => {
113
- if (!document.querySelector(`head>style[data-ui5-font-face-override]`)) {
114
- createStyleInHead(overrideFontFaceCSS, { "data-ui5-font-face-override": "" });
25
+ if (!hasStyle("data-ui5-font-face-override")) {
26
+ createStyle(overrideFontFaceCSS, "data-ui5-font-face-override");
115
27
  }
116
28
  };
117
29
 
@@ -13,7 +13,6 @@ let initialConfig = {
13
13
  noConflict: false, // no URL
14
14
  formatSettings: {},
15
15
  fetchDefaultLanguage: false,
16
- assetsPath: "",
17
16
  };
18
17
 
19
18
  /* General settings */
@@ -62,11 +61,6 @@ const getFormatSettings = () => {
62
61
  return initialConfig.formatSettings;
63
62
  };
64
63
 
65
- const getAssetsPath = () => {
66
- initConfiguration();
67
- return initialConfig.assetsPath;
68
- };
69
-
70
64
  const booleanMapping = new Map();
71
65
  booleanMapping.set("true", true);
72
66
  booleanMapping.set("false", false);
@@ -112,6 +106,14 @@ const parseURLParameters = () => {
112
106
  });
113
107
  };
114
108
 
109
+ const normalizeParamValue = (param, value) => {
110
+ if (param === "theme" && value.includes("@")) { // the theme parameter might have @<URL-TO-THEME> in the value - strip this
111
+ return value.split("@")[0];
112
+ }
113
+
114
+ return value;
115
+ };
116
+
115
117
  const applyURLParam = (key, value, paramType) => {
116
118
  const lowerCaseValue = value.toLowerCase();
117
119
  const param = key.split(`${paramType}-`)[1];
@@ -119,6 +121,9 @@ const applyURLParam = (key, value, paramType) => {
119
121
  if (booleanMapping.has(value)) {
120
122
  value = booleanMapping.get(lowerCaseValue);
121
123
  }
124
+
125
+ value = normalizeParamValue(param, value);
126
+
122
127
  initialConfig[param] = value;
123
128
  };
124
129
 
@@ -158,5 +163,4 @@ export {
158
163
  getNoConflict,
159
164
  getCalendarType,
160
165
  getFormatSettings,
161
- getAssetsPath,
162
166
  };
package/dist/Keys.js CHANGED
@@ -111,6 +111,8 @@ const isSpace = event => (event.key ? (event.key === "Spacebar" || event.key ===
111
111
 
112
112
  const isSpaceShift = event => (event.key ? (event.key === "Spacebar" || event.key === " ") : event.keyCode === KeyCodes.SPACE) && checkModifierKeys(event, false, false, true);
113
113
 
114
+ const isSpaceCtrl = event => (event.key ? (event.key === "Spacebar" || event.key === " ") : event.keyCode === KeyCodes.SPACE) && checkModifierKeys(event, true, false, false);
115
+
114
116
  const isLeft = event => (event.key ? (event.key === "ArrowLeft" || event.key === "Left") : event.keyCode === KeyCodes.ARROW_LEFT) && !hasModifierKeys(event);
115
117
 
116
118
  const isRight = event => (event.key ? (event.key === "ArrowRight" || event.key === "Right") : event.keyCode === KeyCodes.ARROW_RIGHT) && !hasModifierKeys(event);
@@ -131,10 +133,18 @@ const isUpShift = event => (event.key ? (event.key === "ArrowUp" || event.key ==
131
133
 
132
134
  const isDownShift = event => (event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && checkModifierKeys(event, false, false, true);
133
135
 
136
+ const isUpAlt = event => (event.key ? (event.key === "ArrowUp" || event.key === "Up") : event.keyCode === KeyCodes.ARROW_UP) && checkModifierKeys(event, false, true, false);
137
+
138
+ const isDownAlt = event => (event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && checkModifierKeys(event, false, true, false);
139
+
134
140
  const isLeftShift = event => (event.key ? (event.key === "ArrowLeft" || event.key === "Left") : event.keyCode === KeyCodes.ARROW_LEFT) && checkModifierKeys(event, false, false, true);
135
141
 
136
142
  const isRightShift = event => (event.key ? (event.key === "ArrowRight" || event.key === "Right") : event.keyCode === KeyCodes.ARROW_RIGHT) && checkModifierKeys(event, false, false, true);
137
143
 
144
+ const isLeftShiftCtrl = event => (event.key ? (event.key === "ArrowLeft" || event.key === "Left") : event.keyCode === KeyCodes.ARROW_LEFT) && checkModifierKeys(event, true, false, true);
145
+
146
+ const isRightShiftCtrl = event => (event.key ? (event.key === "ArrowRight" || event.key === "Right") : event.keyCode === KeyCodes.ARROW_RIGHT) && checkModifierKeys(event, true, false, true);
147
+
138
148
  const isUpShiftCtrl = event => (event.key ? (event.key === "ArrowUp" || event.key === "Up") : event.keyCode === KeyCodes.ARROW_UP) && checkModifierKeys(event, true, false, true);
139
149
 
140
150
  const isDownShiftCtrl = event => (event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && checkModifierKeys(event, true, false, true);
@@ -145,8 +155,12 @@ const isEnd = event => (event.key ? event.key === "End" : event.keyCode === KeyC
145
155
 
146
156
  const isHomeCtrl = event => (event.key ? event.key === "Home" : event.keyCode === KeyCodes.HOME) && checkModifierKeys(event, true, false, false);
147
157
 
158
+ const isHomeShift = event => (event.key ? event.key === "Home" : event.keyCode === KeyCodes.HOME) && checkModifierKeys(event, false, false, true);
159
+
148
160
  const isEndCtrl = event => (event.key ? event.key === "End" : event.keyCode === KeyCodes.END) && checkModifierKeys(event, true, false, false);
149
161
 
162
+ const isEndShift = event => (event.key ? event.key === "End" : event.keyCode === KeyCodes.END) && checkModifierKeys(event, false, false, true);
163
+
150
164
  const isEscape = event => (event.key ? event.key === "Escape" || event.key === "Esc" : event.keyCode === KeyCodes.ESCAPE) && !hasModifierKeys(event);
151
165
 
152
166
  const isTabNext = event => (event.key ? event.key === "Tab" : event.keyCode === KeyCodes.TAB) && !hasModifierKeys(event);
@@ -157,6 +171,12 @@ const isBackSpace = event => (event.key ? event.key === "Backspace" : event.keyC
157
171
 
158
172
  const isDelete = event => (event.key ? event.key === "Delete" : event.keyCode === KeyCodes.DELETE) && !hasModifierKeys(event);
159
173
 
174
+ const isDeleteShift = event => (event.key ? event.key === "Delete" : event.keyCode === KeyCodes.DELETE) && checkModifierKeys(event, false, false, true);
175
+
176
+ const isInsertShift = event => (event.key ? event.key === "Insert" : event.keyCode === KeyCodes.DELETE) && checkModifierKeys(event, false, false, true);
177
+
178
+ const isInsertCtrl = event => (event.key ? event.key === "Insert" : event.keyCode === KeyCodes.DELETE) && checkModifierKeys(event, true, false, false);
179
+
160
180
  const isPageUp = event => (event.key ? event.key === "PageUp" : event.keyCode === KeyCodes.PAGE_UP) && !hasModifierKeys(event);
161
181
 
162
182
  const isPageDown = event => (event.key ? event.key === "PageDown" : event.keyCode === KeyCodes.PAGE_DOWN) && !hasModifierKeys(event);
@@ -191,12 +211,24 @@ const isF4 = event => {
191
211
 
192
212
  const isF4Shift = event => (event.key ? event.key === "F4" : event.keyCode === KeyCodes.F4) && checkModifierKeys(event, false, false, true);
193
213
 
214
+ const isF6Next = event => ((event.key ? event.key === "F6" : event.keyCode === KeyCodes.F6) && checkModifierKeys(event, false, false, false))
215
+ || ((event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && checkModifierKeys(event, true, true, false));
216
+
217
+ const isF6Previous = event => ((event.key ? event.key === "F6" : event.keyCode === KeyCodes.F6) && checkModifierKeys(event, false, false, true))
218
+ || ((event.key ? (event.key === "ArrowUp" || event.key === "Up") : event.keyCode === KeyCodes.ARROW_Up) && checkModifierKeys(event, true, true, false));
219
+
194
220
  const isF7 = event => (event.key ? event.key === "F7" : event.keyCode === KeyCodes.F7) && !hasModifierKeys(event);
195
221
 
196
222
  const isShowByArrows = event => {
197
223
  return ((event.key === "ArrowDown" || event.key === "Down") || (event.key === "ArrowUp" || event.key === "Up")) && checkModifierKeys(event, /* Ctrl */ false, /* Alt */ true, /* Shift */ false);
198
224
  };
199
225
 
226
+ const isShift = event => event.key === "Shift" || event.keyCode === KeyCodes.SHIFT;
227
+
228
+ const isCtrlA = event => ((event.key === "A" || event.key === "a") || event.which === KeyCodes.A) && checkModifierKeys(event, true, false, false);
229
+
230
+ const isCtrlV = event => ((event.key === "V" || event.key === "v") || event.which === KeyCodes.V) && checkModifierKeys(event, true, false, false);
231
+
200
232
  const hasModifierKeys = event => event.shiftKey || event.altKey || getCtrlKey(event);
201
233
 
202
234
  const getCtrlKey = event => !!(event.metaKey || event.ctrlKey); // double negation doesn't have effect on boolean but ensures null and undefined are equivalent to false.
@@ -208,6 +240,7 @@ export {
208
240
  isEnterShift,
209
241
  isSpace,
210
242
  isSpaceShift,
243
+ isSpaceCtrl,
211
244
  isLeft,
212
245
  isRight,
213
246
  isUp,
@@ -218,8 +251,12 @@ export {
218
251
  isDownCtrl,
219
252
  isUpShift,
220
253
  isDownShift,
254
+ isUpAlt,
255
+ isDownAlt,
221
256
  isLeftShift,
222
257
  isRightShift,
258
+ isLeftShiftCtrl,
259
+ isRightShiftCtrl,
223
260
  isUpShiftCtrl,
224
261
  isDownShiftCtrl,
225
262
  isHome,
@@ -228,6 +265,8 @@ export {
228
265
  isMinus,
229
266
  isHomeCtrl,
230
267
  isEndCtrl,
268
+ isHomeShift,
269
+ isEndShift,
231
270
  isEscape,
232
271
  isTabNext,
233
272
  isTabPrevious,
@@ -236,6 +275,8 @@ export {
236
275
  isShow,
237
276
  isF4,
238
277
  isF4Shift,
278
+ isF6Previous,
279
+ isF6Next,
239
280
  isF7,
240
281
  isPageUp,
241
282
  isPageDown,
@@ -245,4 +286,10 @@ export {
245
286
  isPageDownAlt,
246
287
  isPageUpShiftCtrl,
247
288
  isPageDownShiftCtrl,
289
+ isShift,
290
+ isCtrlA,
291
+ isCtrlV,
292
+ isDeleteShift,
293
+ isInsertShift,
294
+ isInsertCtrl,
248
295
  };
@@ -0,0 +1,83 @@
1
+ import createStyleInHead from "./util/createStyleInHead.js";
2
+ import createLinkInHead from "./util/createLinkInHead.js";
3
+ import { shouldUseLinks, getUrl } from "./CSP.js";
4
+
5
+ const getStyleId = (name, value) => {
6
+ return value ? `${name}|${value}` : name;
7
+ };
8
+
9
+ const createStyle = (data, name, value = "") => {
10
+ const content = typeof data === "string" ? data : data.content;
11
+
12
+ if (shouldUseLinks()) {
13
+ const attributes = {};
14
+ attributes[name] = value;
15
+ const href = getUrl(data.packageName, data.fileName);
16
+ createLinkInHead(href, attributes);
17
+ } else if (document.adoptedStyleSheets) {
18
+ const stylesheet = new CSSStyleSheet();
19
+ stylesheet.replaceSync(content);
20
+ stylesheet._ui5StyleId = getStyleId(name, value); // set an id so that we can find the style later
21
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
22
+ } else {
23
+ const attributes = {};
24
+ attributes[name] = value;
25
+ createStyleInHead(content, attributes);
26
+ }
27
+ };
28
+
29
+ const updateStyle = (data, name, value = "") => {
30
+ const content = typeof data === "string" ? data : data.content;
31
+
32
+ if (shouldUseLinks()) {
33
+ document.querySelector(`head>link[${name}="${value}"]`).href = getUrl(data.packageName, data.fileName);
34
+ } else if (document.adoptedStyleSheets) {
35
+ document.adoptedStyleSheets.find(sh => sh._ui5StyleId === getStyleId(name, value)).replaceSync(content || "");
36
+ } else {
37
+ document.querySelector(`head>style[${name}="${value}"]`).textContent = content || "";
38
+ }
39
+ };
40
+
41
+ const hasStyle = (name, value = "") => {
42
+ if (shouldUseLinks()) {
43
+ return !!document.querySelector(`head>link[${name}="${value}"]`);
44
+ }
45
+
46
+ if (document.adoptedStyleSheets) {
47
+ return !!document.adoptedStyleSheets.find(sh => sh._ui5StyleId === getStyleId(name, value));
48
+ }
49
+
50
+ return !!document.querySelector(`head>style[${name}="${value}"]`);
51
+ };
52
+
53
+ const removeStyle = (name, value = "") => {
54
+ if (shouldUseLinks()) {
55
+ const linkElement = document.querySelector(`head>link[${name}="${value}"]`);
56
+ if (linkElement) {
57
+ linkElement.parentElement.removeChild(linkElement);
58
+ }
59
+ } else if (document.adoptedStyleSheets) {
60
+ document.adoptedStyleSheets = document.adoptedStyleSheets.filter(sh => sh._ui5StyleId !== getStyleId(name, value));
61
+ } else {
62
+ const styleElement = document.querySelector(`head > style[${name}="${value}"]`);
63
+ if (styleElement) {
64
+ styleElement.parentElement.removeChild(styleElement);
65
+ }
66
+ }
67
+ };
68
+
69
+ const createOrUpdateStyle = (data, name, value = "") => {
70
+ if (hasStyle(name, value)) {
71
+ updateStyle(data, name, value);
72
+ } else {
73
+ createStyle(data, name, value);
74
+ }
75
+ };
76
+
77
+ export {
78
+ createStyle,
79
+ hasStyle,
80
+ updateStyle,
81
+ removeStyle,
82
+ createOrUpdateStyle,
83
+ };
package/dist/Render.js CHANGED
@@ -135,6 +135,7 @@ const _resolveTaskPromise = () => {
135
135
  * reRenderAllUI5Elements({tag: "ui5-button"}) -> re-renders only instances of ui5-button
136
136
  * reRenderAllUI5Elements({rtlAware: true}) -> re-renders only rtlAware components
137
137
  * reRenderAllUI5Elements({languageAware: true}) -> re-renders only languageAware components
138
+ * reRenderAllUI5Elements({themeAware: true}) -> re-renders only themeAware components
138
139
  * reRenderAllUI5Elements({rtlAware: true, languageAware: true}) -> re-renders components that are rtlAware or languageAware
139
140
  * etc...
140
141
  *
@@ -147,7 +148,8 @@ const reRenderAllUI5Elements = async filters => {
147
148
  const tag = element.constructor.getMetadata().getTag();
148
149
  const rtlAware = isRtlAware(element.constructor);
149
150
  const languageAware = element.constructor.getMetadata().isLanguageAware();
150
- if (!filters || (filters.tag === tag) || (filters.rtlAware && rtlAware) || (filters.languageAware && languageAware)) {
151
+ const themeAware = element.constructor.getMetadata().isThemeAware();
152
+ if (!filters || (filters.tag === tag) || (filters.rtlAware && rtlAware) || (filters.languageAware && languageAware) || (filters.themeAware && themeAware)) {
151
153
  renderDeferred(element);
152
154
  }
153
155
  });
@@ -0,0 +1,107 @@
1
+ import VersionInfo from "./generated/VersionInfo.js";
2
+ import getSharedResource from "./getSharedResource.js";
3
+
4
+ let currentRuntimeIndex;
5
+ let currentRuntimeAlias = "";
6
+
7
+ const compareCache = new Map();
8
+
9
+ /**
10
+ * Central registry where all runtimes register themselves by pushing an object.
11
+ * The index in the registry servers as an ID for the runtime.
12
+ * @type {*}
13
+ */
14
+ const Runtimes = getSharedResource("Runtimes", []);
15
+
16
+ /**
17
+ * Registers the current runtime in the shared runtimes resource registry
18
+ */
19
+ const registerCurrentRuntime = () => {
20
+ if (currentRuntimeIndex === undefined) {
21
+ currentRuntimeIndex = Runtimes.length;
22
+ Runtimes.push({
23
+ ...VersionInfo,
24
+ alias: currentRuntimeAlias,
25
+ description: `Runtime ${currentRuntimeIndex} - ver ${VersionInfo.version}${currentRuntimeAlias ? ` (${currentRuntimeAlias})` : ""}`,
26
+ });
27
+ }
28
+ };
29
+
30
+ /**
31
+ * Returns the index of the current runtime's object in the shared runtimes resource registry
32
+ * @returns {*}
33
+ */
34
+ const getCurrentRuntimeIndex = () => {
35
+ return currentRuntimeIndex;
36
+ };
37
+
38
+ /**
39
+ * Compares two runtimes and returns 1 if the first is of a bigger version, -1 if the second is of a bigger version, and 0 if equal
40
+ * @param index1 The index of the first runtime to compare
41
+ * @param index2 The index of the second runtime to compare
42
+ * @returns {number}
43
+ */
44
+ const compareRuntimes = (index1, index2) => {
45
+ const cacheIndex = `${index1},${index2}`;
46
+ if (compareCache.has(cacheIndex)) {
47
+ return compareCache.get(cacheIndex);
48
+ }
49
+
50
+ const runtime1 = Runtimes[index1];
51
+ const runtime2 = Runtimes[index2];
52
+
53
+ if (!runtime1 || !runtime2) {
54
+ throw new Error("Invalid runtime index supplied");
55
+ }
56
+
57
+ // If any of the two is a next version, bigger buildTime wins
58
+ if (runtime1.isNext || runtime2.isNext) {
59
+ return runtime1.buildTime - runtime2.buildTime;
60
+ }
61
+
62
+ // If major versions differ, bigger one wins
63
+ const majorDiff = runtime1.major - runtime2.major;
64
+ if (majorDiff) {
65
+ return majorDiff;
66
+ }
67
+
68
+ // If minor versions differ, bigger one wins
69
+ const minorDiff = runtime1.minor - runtime2.minor;
70
+ if (minorDiff) {
71
+ return minorDiff;
72
+ }
73
+
74
+ // If patch versions differ, bigger one wins
75
+ const patchDiff = runtime1.patch - runtime2.patch;
76
+ if (patchDiff) {
77
+ return patchDiff;
78
+ }
79
+
80
+ // Bigger suffix wins, f.e. rc10 > rc9
81
+ // Important: suffix is alphanumeric, must use natural compare
82
+ const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" });
83
+ const result = collator.compare(runtime1.suffix, runtime2.suffix);
84
+
85
+ compareCache.set(cacheIndex, result);
86
+ return result;
87
+ };
88
+
89
+ /**
90
+ * Set an alias for the the current app/library/microfrontend which will appear in debug messages and console warnings
91
+ * @param alias
92
+ */
93
+ const setRuntimeAlias = alias => {
94
+ currentRuntimeAlias = alias;
95
+ };
96
+
97
+ const getAllRuntimes = () => {
98
+ return Runtimes;
99
+ };
100
+
101
+ export {
102
+ getCurrentRuntimeIndex,
103
+ registerCurrentRuntime,
104
+ compareRuntimes,
105
+ setRuntimeAlias,
106
+ getAllRuntimes,
107
+ };