@ui5/webcomponents-base 1.0.0-rc.15 → 1.0.2

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 (115) hide show
  1. package/.eslintignore +2 -1
  2. package/CHANGELOG.md +53 -0
  3. package/README.md +26 -2
  4. package/bundle.esm.js +6 -2
  5. package/dist/CSP.js +59 -0
  6. package/dist/Device.js +5 -0
  7. package/dist/EventProvider.js +19 -25
  8. package/dist/FontFace.js +7 -95
  9. package/dist/InitialConfiguration.js +11 -7
  10. package/dist/Keys.js +9 -0
  11. package/dist/ManagedStyles.js +83 -0
  12. package/dist/Render.js +3 -1
  13. package/dist/StaticAreaItem.js +11 -9
  14. package/dist/SystemCSSVars.js +4 -25
  15. package/dist/UI5Element.js +43 -59
  16. package/dist/UI5ElementMetadata.js +9 -1
  17. package/dist/asset-registries/Icons.js +26 -8
  18. package/dist/asset-registries/Illustrations.js +10 -3
  19. package/dist/asset-registries/LocaleData.js +11 -2
  20. package/dist/assets-meta/IconCollectionsAlias.js +18 -0
  21. package/dist/config/Theme.js +14 -0
  22. package/dist/css/FontFace.css +45 -0
  23. package/dist/css/OverrideFontFace.css +32 -0
  24. package/dist/css/SystemCSSVars.css +17 -0
  25. package/dist/delegate/ItemNavigation.js +66 -0
  26. package/dist/generated/AssetParameters.js +1 -1
  27. package/dist/generated/css/FontFace.css.js +5 -0
  28. package/dist/generated/css/OverrideFontFace.css.js +5 -0
  29. package/dist/generated/css/SystemCSSVars.css.js +5 -0
  30. package/dist/i18nBundle.js +33 -2
  31. package/dist/renderer/LitRenderer.js +7 -4
  32. package/dist/renderer/directives/style-map.js +72 -0
  33. package/dist/resources/bundle.esm.js +19 -8
  34. package/dist/resources/bundle.esm.js.map +1 -1
  35. package/dist/sap/base/Log.js +2 -10
  36. package/dist/sap/base/assert.js +1 -5
  37. package/dist/test-resources/elements/WithStaticArea.js +2 -1
  38. package/dist/test-resources/pages/AllTestElements.html +3 -0
  39. package/dist/test-resources/pages/i18n.html +1 -3
  40. package/dist/test-resources/specs/ConfigurationChange.spec.js +9 -9
  41. package/dist/test-resources/specs/ConfigurationScript.spec.js +24 -24
  42. package/dist/test-resources/specs/ConfigurationURL.spec.js +33 -33
  43. package/dist/test-resources/specs/CustomTheme.spec.js +7 -7
  44. package/dist/test-resources/specs/EventProvider.spec.js +63 -0
  45. package/dist/test-resources/specs/StaticArea.spec.js +55 -13
  46. package/dist/test-resources/specs/Theming.spec.js +11 -11
  47. package/dist/test-resources/specs/UI5ElementInvalidation.js +29 -29
  48. package/dist/test-resources/specs/UI5ElementLifecycle.js +11 -11
  49. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +11 -11
  50. package/dist/test-resources/specs/UI5ElementMetadataExt.js +8 -8
  51. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +6 -6
  52. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +36 -36
  53. package/dist/test-resources/specs/UI5ElementShadowDOM.js +9 -9
  54. package/dist/test-resources/specs/UI5ElementSlots.js +9 -9
  55. package/dist/theming/CustomStyle.js +23 -3
  56. package/dist/theming/applyTheme.js +11 -10
  57. package/dist/theming/getEffectiveLinksHrefs.js +20 -0
  58. package/dist/theming/getStylesString.js +4 -2
  59. package/dist/theming/getThemeDesignerTheme.js +25 -5
  60. package/dist/theming/preloadLinks.js +23 -0
  61. package/dist/types/DataType.js +12 -0
  62. package/dist/types/Float.js +4 -0
  63. package/dist/types/Integer.js +4 -0
  64. package/dist/updateShadowRoot.js +8 -4
  65. package/dist/util/createLinkInHead.js +19 -0
  66. package/dist/util/encodeXML.js +35 -0
  67. package/dist/util/escapeRegex.js +10 -0
  68. package/dist/util/generateHighlightedMarkup.js +42 -0
  69. package/hash.txt +1 -1
  70. package/lib/generate-asset-parameters/index.js +0 -1
  71. package/lib/generate-styles/index.js +18 -0
  72. package/package-scripts.js +9 -6
  73. package/package.json +9 -11
  74. package/src/CSP.js +59 -0
  75. package/src/Device.js +5 -0
  76. package/src/EventProvider.js +19 -25
  77. package/src/FontFace.js +7 -95
  78. package/src/InitialConfiguration.js +11 -7
  79. package/src/Keys.js +9 -0
  80. package/src/ManagedStyles.js +83 -0
  81. package/src/Render.js +3 -1
  82. package/src/StaticAreaItem.js +11 -9
  83. package/src/SystemCSSVars.js +4 -25
  84. package/src/UI5Element.js +43 -59
  85. package/src/UI5ElementMetadata.js +9 -1
  86. package/src/asset-registries/Icons.js +26 -8
  87. package/src/asset-registries/Illustrations.js +10 -3
  88. package/src/asset-registries/LocaleData.js +11 -2
  89. package/src/assets-meta/IconCollectionsAlias.js +18 -0
  90. package/src/config/Theme.js +14 -0
  91. package/src/css/FontFace.css +45 -0
  92. package/src/css/OverrideFontFace.css +32 -0
  93. package/src/css/SystemCSSVars.css +17 -0
  94. package/src/delegate/ItemNavigation.js +66 -0
  95. package/src/i18nBundle.js +33 -2
  96. package/src/renderer/LitRenderer.js +7 -4
  97. package/src/renderer/directives/style-map.js +72 -0
  98. package/src/theming/CustomStyle.js +23 -3
  99. package/src/theming/applyTheme.js +11 -10
  100. package/src/theming/getEffectiveLinksHrefs.js +20 -0
  101. package/src/theming/getStylesString.js +4 -2
  102. package/src/theming/getThemeDesignerTheme.js +25 -5
  103. package/src/theming/preloadLinks.js +23 -0
  104. package/src/types/DataType.js +12 -0
  105. package/src/types/Float.js +4 -0
  106. package/src/types/Integer.js +4 -0
  107. package/src/updateShadowRoot.js +8 -4
  108. package/src/util/createLinkInHead.js +19 -0
  109. package/src/util/encodeXML.js +35 -0
  110. package/src/util/escapeRegex.js +10 -0
  111. package/src/util/generateHighlightedMarkup.js +42 -0
  112. package/dist/config/AssetsPath.js +0 -17
  113. package/dist/theming/createThemePropertiesStyleTag.js +0 -20
  114. package/src/config/AssetsPath.js +0 -17
  115. package/src/theming/createThemePropertiesStyleTag.js +0 -20
@@ -1,15 +1,26 @@
1
+ const warnings = new Set();
2
+
1
3
  const getThemeMetadata = () => {
2
4
  // Check if the class was already applied, most commonly to the link/style tag with the CSS Variables
3
- let el = document.querySelector(".sapThemeMetaData-Base-baseLib");
5
+ let el = document.querySelector(".sapThemeMetaData-Base-baseLib") || document.querySelector(".sapThemeMetaData-UI5-sap-ui-core");
4
6
  if (el) {
5
7
  return getComputedStyle(el).backgroundImage;
6
8
  }
7
9
 
8
10
  el = document.createElement("span");
9
11
  el.style.display = "none";
12
+
13
+ // Try with sapThemeMetaData-Base-baseLib first
10
14
  el.classList.add("sapThemeMetaData-Base-baseLib");
11
15
  document.body.appendChild(el);
12
- const metadata = getComputedStyle(el).backgroundImage;
16
+ let metadata = getComputedStyle(el).backgroundImage;
17
+
18
+ // Try with sapThemeMetaData-UI5-sap-ui-core only if the previous selector was not found
19
+ if (metadata === "none") {
20
+ el.classList.add("sapThemeMetaData-UI5-sap-ui-core");
21
+ metadata = getComputedStyle(el).backgroundImage;
22
+ }
23
+
13
24
  document.body.removeChild(el);
14
25
 
15
26
  return metadata;
@@ -24,14 +35,20 @@ const parseThemeMetadata = metadataString => {
24
35
  try {
25
36
  paramsString = decodeURIComponent(paramsString);
26
37
  } catch (ex) {
27
- console.warn("Malformed theme metadata string, unable to decodeURIComponent"); // eslint-disable-line
38
+ if (!warnings.has("decode")) {
39
+ console.warn("Malformed theme metadata string, unable to decodeURIComponent"); // eslint-disable-line
40
+ warnings.add("decode");
41
+ }
28
42
  return;
29
43
  }
30
44
  }
31
45
  try {
32
46
  return JSON.parse(paramsString);
33
47
  } catch (ex) {
34
- console.warn("Malformed theme metadata string, unable to parse JSON"); // eslint-disable-line
48
+ if (!warnings.has("parse")) {
49
+ console.warn("Malformed theme metadata string, unable to parse JSON"); // eslint-disable-line
50
+ warnings.add("parse");
51
+ }
35
52
  }
36
53
  }
37
54
  };
@@ -44,7 +61,10 @@ const processThemeMetadata = metadata => {
44
61
  themeName = metadata.Path.match(/\.([^.]+)\.css_variables$/)[1];
45
62
  baseThemeName = metadata.Extends[0];
46
63
  } catch (ex) {
47
- console.warn("Malformed theme metadata Object", metadata); // eslint-disable-line
64
+ if (!warnings.has("object")) {
65
+ console.warn("Malformed theme metadata Object", metadata); // eslint-disable-line
66
+ warnings.add("object");
67
+ }
48
68
  return;
49
69
  }
50
70
 
@@ -0,0 +1,23 @@
1
+ import getEffectiveLinksHrefs from "./getEffectiveLinksHrefs.js";
2
+ import createLinkInHead from "../util/createLinkInHead.js";
3
+ import { shouldUseLinks, shouldPreloadLinks } from "../CSP.js";
4
+
5
+ const preloaded = new Set();
6
+
7
+ const preloadLinks = ElementClass => {
8
+ if (!shouldUseLinks() || !shouldPreloadLinks()) {
9
+ return;
10
+ }
11
+
12
+ const linksHrefs = getEffectiveLinksHrefs(ElementClass, false) || [];
13
+ const staticAreaLinksHrefs = getEffectiveLinksHrefs(ElementClass, true) || [];
14
+
15
+ [...linksHrefs, ...staticAreaLinksHrefs].forEach(href => {
16
+ if (!preloaded.has(href)) {
17
+ createLinkInHead(href, { rel: "preload", as: "style" });
18
+ preloaded.add(href);
19
+ }
20
+ });
21
+ };
22
+
23
+ export default preloadLinks;
@@ -11,6 +11,18 @@ class DataType {
11
11
  static isValid(value) {
12
12
  }
13
13
 
14
+ static attributeToProperty(attributeValue) {
15
+ return attributeValue;
16
+ }
17
+
18
+ static propertyToAttribute(propertyValue) {
19
+ return `${propertyValue}`;
20
+ }
21
+
22
+ static valuesAreEqual(value1, value2) {
23
+ return value1 === value2;
24
+ }
25
+
14
26
  static generateTypeAccessors(types) {
15
27
  Object.keys(types).forEach(type => {
16
28
  Object.defineProperty(this, type, {
@@ -5,6 +5,10 @@ class Float extends DataType {
5
5
  // Assuming that integers are floats as well!
6
6
  return Number(value) === value;
7
7
  }
8
+
9
+ static attributeToProperty(attributeValue) {
10
+ return parseFloat(attributeValue);
11
+ }
8
12
  }
9
13
 
10
14
  export default Float;
@@ -4,6 +4,10 @@ class Integer extends DataType {
4
4
  static isValid(value) {
5
5
  return Number.isInteger(value);
6
6
  }
7
+
8
+ static attributeToProperty(attributeValue) {
9
+ return parseInt(attributeValue);
10
+ }
7
11
  }
8
12
 
9
13
  export default Integer;
@@ -1,7 +1,9 @@
1
1
  import executeTemplate from "./renderer/executeTemplate.js";
2
2
  import getConstructableStyle from "./theming/getConstructableStyle.js";
3
3
  import getEffectiveStyle from "./theming/getEffectiveStyle.js";
4
+ import getEffectiveLinksHrefs from "./theming/getEffectiveLinksHrefs.js";
4
5
  import isLegacyBrowser from "./isLegacyBrowser.js";
6
+ import { shouldUseLinks } from "./CSP.js";
5
7
 
6
8
  /**
7
9
  * Updates the shadow root of a UI5Element or its static area item
@@ -9,18 +11,20 @@ import isLegacyBrowser from "./isLegacyBrowser.js";
9
11
  * @param forStaticArea
10
12
  */
11
13
  const updateShadowRoot = (element, forStaticArea = false) => {
12
- let styleToPrepend;
14
+ let styleStrOrHrefsArr;
13
15
  const template = forStaticArea ? "staticAreaTemplate" : "template";
14
16
  const shadowRoot = forStaticArea ? element.staticAreaItem.shadowRoot : element.shadowRoot;
15
17
  const renderResult = executeTemplate(element.constructor[template], element);
16
18
 
17
- if (document.adoptedStyleSheets) { // Chrome
19
+ if (shouldUseLinks()) {
20
+ styleStrOrHrefsArr = getEffectiveLinksHrefs(element.constructor, forStaticArea);
21
+ } else if (document.adoptedStyleSheets) { // Chrome
18
22
  shadowRoot.adoptedStyleSheets = getConstructableStyle(element.constructor, forStaticArea);
19
23
  } else if (!isLegacyBrowser()) { // FF, Safari
20
- styleToPrepend = getEffectiveStyle(element.constructor, forStaticArea);
24
+ styleStrOrHrefsArr = getEffectiveStyle(element.constructor, forStaticArea);
21
25
  }
22
26
 
23
- element.constructor.render(renderResult, shadowRoot, styleToPrepend, { host: element });
27
+ element.constructor.render(renderResult, shadowRoot, styleStrOrHrefsArr, { host: element });
24
28
  };
25
29
 
26
30
  export default updateShadowRoot;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Creates a <link> tag in the <head> tag
3
+ * @param href - the CSS
4
+ * @param attributes - optional attributes to add to the tag
5
+ * @returns {HTMLElement}
6
+ */
7
+ const createLinkInHead = (href, attributes = {}) => {
8
+ const link = document.createElement("link");
9
+ link.type = "text/css";
10
+ link.rel = "stylesheet";
11
+
12
+ Object.entries(attributes).forEach(pair => link.setAttribute(...pair));
13
+
14
+ link.href = href;
15
+ document.head.appendChild(link);
16
+ return link;
17
+ };
18
+
19
+ export default createLinkInHead;
@@ -0,0 +1,35 @@
1
+ const fnToHex = (iChar, iLength) => {
2
+ let sHex = iChar.toString(16);
3
+ if (iLength) {
4
+ sHex = sHex.padStart(iLength, "0");
5
+ }
6
+ return sHex;
7
+ };
8
+
9
+ const rHtml = /[\x00-\x2b\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\xff\u2028\u2029]/g, // eslint-disable-line no-control-regex
10
+ rHtmlReplace = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/, // eslint-disable-line no-control-regex
11
+ mHtmlLookup = {
12
+ "<": "&lt;",
13
+ ">": "&gt;",
14
+ "&": "&amp;",
15
+ "\"": "&quot;",
16
+ };
17
+
18
+ const fnHtml = sChar => {
19
+ let sEncoded = mHtmlLookup[sChar];
20
+ if (!sEncoded) {
21
+ if (rHtmlReplace.test(sChar)) {
22
+ sEncoded = "&#xfffd;";
23
+ } else {
24
+ sEncoded = `&#x${fnToHex(sChar.charCodeAt(0))};`;
25
+ }
26
+ mHtmlLookup[sChar] = sEncoded;
27
+ }
28
+ return sEncoded;
29
+ };
30
+
31
+ const fnEncodeXML = sString => {
32
+ return sString.replace(rHtml, fnHtml);
33
+ };
34
+
35
+ export default fnEncodeXML;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Escape a regular expression text so that it can be used in a regular expression.
3
+ * @param {string} text The string to be interpreted literally
4
+ * @returns Regular expression string to pass to regex
5
+ */
6
+ function escapeRegex(text) {
7
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8
+ }
9
+
10
+ export default escapeRegex;
@@ -0,0 +1,42 @@
1
+ import escapeRegex from "./escapeRegex.js";
2
+ import encodeXML from "./encodeXML.js";
3
+
4
+ // utility to replace all occurances of a string
5
+ function replaceAll(text, find, replace, caseInsensitive) {
6
+ return text.replace(new RegExp(escapeRegex(find), `${caseInsensitive ? "i" : ""}g`), replace);
7
+ }
8
+
9
+ /**
10
+ * Generate markup for a raw string where a particular text is wrapped with some tag, by default `<b>` (bold) tag.
11
+ * All inputs to this function are considered literal text, and special characters will always be escaped.
12
+ * @param {string} text The text to add highlighting to
13
+ * @param {string} textToHighlight The text which should be highlighted
14
+ * @return {string} the markup HTML which contains all occurrances of the input text surrounded with a `<b>` tag.
15
+ */
16
+ function generateHighlightedMarkup(text, textToHighlight) {
17
+ if (!text || !textToHighlight) {
18
+ return text;
19
+ }
20
+ // a token is some string that does not appear in either of the input strings
21
+ // repeat the token until it does not appear in the string
22
+ const makeToken = t => {
23
+ const [s, e] = t.split("");
24
+ while (text.indexOf(t) >= 0 || textToHighlight.indexOf(t) >= 0) {
25
+ t = `${s}${t}${e}`;
26
+ }
27
+ return t;
28
+ };
29
+ // It doesn't matter what characters are used as long as all 4 of them are unique
30
+ // And also that encodeXML will not change these characters
31
+ const openToken = makeToken("12");
32
+ const closeToken = makeToken("34");
33
+ // wrap every occurance of the textToHighlight using the open/close tokens (instead of markup at this point)
34
+ let result = encodeXML(replaceAll(text, textToHighlight, match => `${openToken}${match}${closeToken}`, true));
35
+ // now replace the open and close tokens with the markup that we expect
36
+ [[openToken, "<b>"], [closeToken, "</b>"]].forEach(([find, replace]) => {
37
+ result = replaceAll(result, find, replace);
38
+ });
39
+ return result;
40
+ }
41
+
42
+ export default generateHighlightedMarkup;
@@ -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,20 +0,0 @@
1
- import createStyleInHead from "../util/createStyleInHead.js";
2
-
3
- /**
4
- * Creates/updates a style element holding all CSS Custom Properties
5
- * @param cssText
6
- * @param packageName
7
- */
8
- const createThemePropertiesStyleTag = (cssText, packageName) => {
9
- const styleElement = document.head.querySelector(`style[data-ui5-theme-properties="${packageName}"]`);
10
- if (styleElement) {
11
- styleElement.textContent = cssText || ""; // in case of undefined
12
- } else {
13
- const attributes = {
14
- "data-ui5-theme-properties": packageName,
15
- };
16
- createStyleInHead(cssText, attributes);
17
- }
18
- };
19
-
20
- export default createThemePropertiesStyleTag;
@@ -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,20 +0,0 @@
1
- import createStyleInHead from "../util/createStyleInHead.js";
2
-
3
- /**
4
- * Creates/updates a style element holding all CSS Custom Properties
5
- * @param cssText
6
- * @param packageName
7
- */
8
- const createThemePropertiesStyleTag = (cssText, packageName) => {
9
- const styleElement = document.head.querySelector(`style[data-ui5-theme-properties="${packageName}"]`);
10
- if (styleElement) {
11
- styleElement.textContent = cssText || ""; // in case of undefined
12
- } else {
13
- const attributes = {
14
- "data-ui5-theme-properties": packageName,
15
- };
16
- createStyleInHead(cssText, attributes);
17
- }
18
- };
19
-
20
- export default createThemePropertiesStyleTag;