@ui5/webcomponents-base 0.0.0-dc3ccac50 → 0.0.0-deac3098a
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.
- package/.eslintignore +1 -1
- package/CHANGELOG.md +158 -0
- package/dist/Boot.js +34 -18
- package/dist/CustomElementsRegistry.js +60 -4
- package/dist/CustomElementsScope.js +20 -98
- package/dist/CustomElementsScopeUtils.js +108 -0
- package/dist/Device.js +10 -1
- package/dist/FeaturesRegistry.js +4 -1
- package/dist/Keys.js +47 -0
- package/dist/Runtimes.js +107 -0
- package/dist/StaticAreaItem.js +4 -1
- package/dist/UI5Element.js +18 -3
- package/dist/UI5ElementMetadata.js +9 -1
- package/dist/asset-registries/Icons.js +3 -7
- package/dist/asset-registries/LocaleData.js +6 -1
- package/dist/config/Icons.js +52 -0
- package/dist/config/Theme.js +11 -0
- package/dist/css/BusyIndicator.css +76 -0
- package/dist/css/FontFace.css +40 -10
- package/dist/features/F6Navigation.js +108 -0
- package/dist/features/OpenUI5Enablement.js +119 -0
- package/dist/generated/AssetParameters.js +1 -1
- package/dist/generated/VersionInfo.js +10 -0
- package/dist/generated/css/BusyIndicator.css.js +5 -0
- package/dist/generated/css/FontFace.css.js +1 -1
- package/dist/renderer/LitRenderer.js +29 -11
- package/dist/renderer/executeTemplate.js +19 -2
- package/dist/resources/bundle.esm.js +8 -13
- package/dist/resources/bundle.esm.js.map +1 -1
- package/dist/sap/base/security/encodeCSS.js +14 -0
- package/dist/sap/base/security/encodeXML.js +23 -0
- package/dist/sap/base/strings/toHex.js +8 -0
- package/dist/theming/CustomStyle.js +23 -3
- package/dist/theming/applyTheme.js +8 -4
- package/dist/theming/getEffectiveLinksHrefs.js +7 -0
- package/dist/theming/getEffectiveStyle.js +9 -0
- package/dist/theming/getThemeDesignerTheme.js +24 -5
- package/dist/updateShadowRoot.js +1 -1
- package/dist/util/FocusableElements.js +8 -6
- package/dist/util/InvisibleMessage.js +11 -9
- package/dist/util/TabbableElements.js +4 -0
- package/dist/util/escapeRegex.js +10 -0
- package/dist/util/generateHighlightedMarkup.js +42 -0
- package/dist/util/getNormalizedTarget.js +16 -0
- package/dist/util/isNodeHidden.js +1 -1
- package/hash.txt +1 -1
- package/lib/generate-version-info/index.js +27 -0
- package/package-scripts.js +4 -7
- package/package.json +4 -4
- package/src/Boot.js +34 -18
- package/src/CustomElementsRegistry.js +60 -4
- package/src/CustomElementsScope.js +20 -98
- package/src/CustomElementsScopeUtils.js +108 -0
- package/src/Device.js +10 -1
- package/src/FeaturesRegistry.js +4 -1
- package/src/Keys.js +47 -0
- package/src/Runtimes.js +107 -0
- package/src/StaticAreaItem.js +4 -1
- package/src/UI5Element.js +18 -3
- package/src/UI5ElementMetadata.js +9 -1
- package/src/asset-registries/Icons.js +3 -7
- package/src/asset-registries/LocaleData.js +6 -1
- package/src/config/Icons.js +52 -0
- package/src/config/Theme.js +11 -0
- package/src/css/BusyIndicator.css +76 -0
- package/src/css/FontFace.css +40 -10
- package/src/features/F6Navigation.js +108 -0
- package/src/features/OpenUI5Enablement.js +119 -0
- package/src/renderer/LitRenderer.js +29 -11
- package/src/renderer/executeTemplate.js +19 -2
- package/src/theming/CustomStyle.js +23 -3
- package/src/theming/applyTheme.js +8 -4
- package/src/theming/getEffectiveLinksHrefs.js +7 -0
- package/src/theming/getEffectiveStyle.js +9 -0
- package/src/theming/getThemeDesignerTheme.js +24 -5
- package/src/updateShadowRoot.js +1 -1
- package/src/util/FocusableElements.js +8 -6
- package/src/util/InvisibleMessage.js +11 -9
- package/src/util/TabbableElements.js +4 -0
- package/src/util/escapeRegex.js +10 -0
- package/src/util/generateHighlightedMarkup.js +42 -0
- package/src/util/getNormalizedTarget.js +16 -0
- package/src/util/isNodeHidden.js +1 -1
- package/used-modules.txt +4 -1
- package/dist/util/encodeCSS.js +0 -24
- package/src/util/encodeCSS.js +0 -24
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import toHex from '../strings/toHex.js';
|
|
2
|
+
var rCSS = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff\u2028\u2029][0-9A-Fa-f]?/g;
|
|
3
|
+
var fnCSS = function (sChar) {
|
|
4
|
+
var iChar = sChar.charCodeAt(0);
|
|
5
|
+
if (sChar.length === 1) {
|
|
6
|
+
return '\\' + toHex(iChar);
|
|
7
|
+
} else {
|
|
8
|
+
return '\\' + toHex(iChar) + ' ' + sChar.substr(1);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var fnEncodeCSS = function (sString) {
|
|
12
|
+
return sString.replace(rCSS, fnCSS);
|
|
13
|
+
};
|
|
14
|
+
export default fnEncodeCSS;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import toHex from '../strings/toHex.js';
|
|
2
|
+
var rHtml = /[\x00-\x2b\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\xff\u2028\u2029]/g, rHtmlReplace = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/, mHtmlLookup = {
|
|
3
|
+
'<': '<',
|
|
4
|
+
'>': '>',
|
|
5
|
+
'&': '&',
|
|
6
|
+
'"': '"'
|
|
7
|
+
};
|
|
8
|
+
var fnHtml = function (sChar) {
|
|
9
|
+
var sEncoded = mHtmlLookup[sChar];
|
|
10
|
+
if (!sEncoded) {
|
|
11
|
+
if (rHtmlReplace.test(sChar)) {
|
|
12
|
+
sEncoded = '�';
|
|
13
|
+
} else {
|
|
14
|
+
sEncoded = '&#x' + toHex(sChar.charCodeAt(0)) + ';';
|
|
15
|
+
}
|
|
16
|
+
mHtmlLookup[sChar] = sEncoded;
|
|
17
|
+
}
|
|
18
|
+
return sEncoded;
|
|
19
|
+
};
|
|
20
|
+
var fnEncodeXML = function (sString) {
|
|
21
|
+
return sString.replace(rHtml, fnHtml);
|
|
22
|
+
};
|
|
23
|
+
export default fnEncodeXML;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { reRenderAllUI5Elements } from "../Render.js";
|
|
2
|
+
import getSharedResource from "../getSharedResource.js";
|
|
2
3
|
import EventProvider from "../EventProvider.js";
|
|
3
4
|
|
|
4
|
-
const eventProvider = new EventProvider();
|
|
5
|
+
const eventProvider = getSharedResource("CustomStyle.eventProvider", new EventProvider());
|
|
5
6
|
const CUSTOM_CSS_CHANGE = "CustomCSSChange";
|
|
6
7
|
|
|
7
8
|
const attachCustomCSSChange = listener => {
|
|
@@ -16,14 +17,33 @@ const fireCustomCSSChange = tag => {
|
|
|
16
17
|
return eventProvider.fireEvent(CUSTOM_CSS_CHANGE, tag);
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
const customCSSFor = {};
|
|
20
|
+
const customCSSFor = getSharedResource("CustomStyle.customCSSFor", {});
|
|
21
|
+
|
|
22
|
+
// Listen to the eventProvider, in case other copies of this CustomStyle module fire this
|
|
23
|
+
// event, and this copy would therefore need to reRender the ui5 webcomponents; but
|
|
24
|
+
// don't reRender if it was this copy that fired the event to begin with.
|
|
25
|
+
let skipRerender;
|
|
26
|
+
attachCustomCSSChange(tag => {
|
|
27
|
+
if (!skipRerender) {
|
|
28
|
+
reRenderAllUI5Elements({ tag });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
20
31
|
|
|
21
32
|
const addCustomCSS = (tag, css) => {
|
|
22
33
|
if (!customCSSFor[tag]) {
|
|
23
34
|
customCSSFor[tag] = [];
|
|
24
35
|
}
|
|
25
36
|
customCSSFor[tag].push(css);
|
|
26
|
-
|
|
37
|
+
|
|
38
|
+
skipRerender = true;
|
|
39
|
+
try {
|
|
40
|
+
// The event is fired and the attached event listeners are all called synchronously
|
|
41
|
+
// The skipRerender flag will be used to avoid calling reRenderAllUI5Elements twice when it is this copy
|
|
42
|
+
// of CustomStyle.js which is firing the `CustomCSSChange` event.
|
|
43
|
+
fireCustomCSSChange(tag);
|
|
44
|
+
} finally {
|
|
45
|
+
skipRerender = false;
|
|
46
|
+
}
|
|
27
47
|
|
|
28
48
|
return reRenderAllUI5Elements({ tag });
|
|
29
49
|
};
|
|
@@ -16,8 +16,10 @@ const loadThemeBase = async theme => {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
const cssData = await getThemeProperties(BASE_THEME_PACKAGE, theme);
|
|
20
|
+
if (cssData) {
|
|
21
|
+
createOrUpdateStyle(cssData, "data-ui5-theme-properties", BASE_THEME_PACKAGE);
|
|
22
|
+
}
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
const deleteThemeBase = () => {
|
|
@@ -31,8 +33,10 @@ const loadComponentPackages = async theme => {
|
|
|
31
33
|
return;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
+
const cssData = await getThemeProperties(packageName, theme);
|
|
37
|
+
if (cssData) {
|
|
38
|
+
createOrUpdateStyle(cssData, "data-ui5-theme-properties", packageName);
|
|
39
|
+
}
|
|
36
40
|
});
|
|
37
41
|
};
|
|
38
42
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getUrl } from "../CSP.js";
|
|
2
|
+
import { getFeature } from "../FeaturesRegistry.js";
|
|
2
3
|
|
|
3
4
|
const flatten = arr => {
|
|
4
5
|
return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []);
|
|
@@ -6,6 +7,8 @@ const flatten = arr => {
|
|
|
6
7
|
|
|
7
8
|
const getEffectiveLinksHrefs = (ElementClass, forStaticArea = false) => {
|
|
8
9
|
let stylesData = ElementClass[forStaticArea ? "staticAreaStyles" : "styles"];
|
|
10
|
+
const OpenUI5Enablement = getFeature("OpenUI5Enablement");
|
|
11
|
+
|
|
9
12
|
if (!stylesData) {
|
|
10
13
|
return;
|
|
11
14
|
}
|
|
@@ -14,6 +17,10 @@ const getEffectiveLinksHrefs = (ElementClass, forStaticArea = false) => {
|
|
|
14
17
|
stylesData = [stylesData];
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
if (OpenUI5Enablement) {
|
|
21
|
+
stylesData.push(OpenUI5Enablement.getBusyIndicatorStyles());
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
return flatten(stylesData).filter(data => !!data).map(data => getUrl(data.packageName, data.fileName));
|
|
18
25
|
};
|
|
19
26
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getCustomCSS, attachCustomCSSChange } from "./CustomStyle.js";
|
|
2
2
|
import getStylesString from "./getStylesString.js";
|
|
3
|
+
import { getFeature } from "../FeaturesRegistry.js";
|
|
3
4
|
|
|
4
5
|
const effectiveStyleMap = new Map();
|
|
5
6
|
|
|
@@ -10,9 +11,15 @@ attachCustomCSSChange(tag => {
|
|
|
10
11
|
const getEffectiveStyle = (ElementClass, forStaticArea = false) => {
|
|
11
12
|
const tag = ElementClass.getMetadata().getTag();
|
|
12
13
|
const key = `${tag}_${forStaticArea ? "static" : "normal"}`;
|
|
14
|
+
const OpenUI5Enablement = getFeature("OpenUI5Enablement");
|
|
13
15
|
|
|
14
16
|
if (!effectiveStyleMap.has(key)) {
|
|
15
17
|
let effectiveStyle;
|
|
18
|
+
let busyIndicatorStyles = "";
|
|
19
|
+
|
|
20
|
+
if (OpenUI5Enablement) {
|
|
21
|
+
busyIndicatorStyles = getStylesString(OpenUI5Enablement.getBusyIndicatorStyles());
|
|
22
|
+
}
|
|
16
23
|
|
|
17
24
|
if (forStaticArea) {
|
|
18
25
|
effectiveStyle = getStylesString(ElementClass.staticAreaStyles);
|
|
@@ -21,6 +28,8 @@ const getEffectiveStyle = (ElementClass, forStaticArea = false) => {
|
|
|
21
28
|
const builtInStyles = getStylesString(ElementClass.styles);
|
|
22
29
|
effectiveStyle = `${builtInStyles} ${customStyle}`;
|
|
23
30
|
}
|
|
31
|
+
|
|
32
|
+
effectiveStyle = `${effectiveStyle} ${busyIndicatorStyles}`;
|
|
24
33
|
effectiveStyleMap.set(key, effectiveStyle);
|
|
25
34
|
}
|
|
26
35
|
|
|
@@ -1,3 +1,5 @@
|
|
|
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
5
|
let el = document.querySelector(".sapThemeMetaData-Base-baseLib") || document.querySelector(".sapThemeMetaData-UI5-sap-ui-core");
|
|
@@ -7,10 +9,18 @@ const getThemeMetadata = () => {
|
|
|
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
|
-
el.classList.add("sapThemeMetaData-UI5-sap-ui-core");
|
|
12
15
|
document.body.appendChild(el);
|
|
13
|
-
|
|
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
|
+
|
|
14
24
|
document.body.removeChild(el);
|
|
15
25
|
|
|
16
26
|
return metadata;
|
|
@@ -25,14 +35,20 @@ const parseThemeMetadata = metadataString => {
|
|
|
25
35
|
try {
|
|
26
36
|
paramsString = decodeURIComponent(paramsString);
|
|
27
37
|
} catch (ex) {
|
|
28
|
-
|
|
38
|
+
if (!warnings.has("decode")) {
|
|
39
|
+
console.warn("Malformed theme metadata string, unable to decodeURIComponent"); // eslint-disable-line
|
|
40
|
+
warnings.add("decode");
|
|
41
|
+
}
|
|
29
42
|
return;
|
|
30
43
|
}
|
|
31
44
|
}
|
|
32
45
|
try {
|
|
33
46
|
return JSON.parse(paramsString);
|
|
34
47
|
} catch (ex) {
|
|
35
|
-
|
|
48
|
+
if (!warnings.has("parse")) {
|
|
49
|
+
console.warn("Malformed theme metadata string, unable to parse JSON"); // eslint-disable-line
|
|
50
|
+
warnings.add("parse");
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
}
|
|
38
54
|
};
|
|
@@ -45,7 +61,10 @@ const processThemeMetadata = metadata => {
|
|
|
45
61
|
themeName = metadata.Path.match(/\.([^.]+)\.css_variables$/)[1];
|
|
46
62
|
baseThemeName = metadata.Extends[0];
|
|
47
63
|
} catch (ex) {
|
|
48
|
-
|
|
64
|
+
if (!warnings.has("object")) {
|
|
65
|
+
console.warn("Malformed theme metadata Object", metadata); // eslint-disable-line
|
|
66
|
+
warnings.add("object");
|
|
67
|
+
}
|
|
49
68
|
return;
|
|
50
69
|
}
|
|
51
70
|
|
package/dist/updateShadowRoot.js
CHANGED
|
@@ -24,7 +24,7 @@ const updateShadowRoot = (element, forStaticArea = false) => {
|
|
|
24
24
|
styleStrOrHrefsArr = getEffectiveStyle(element.constructor, forStaticArea);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
element.constructor.render(renderResult, shadowRoot, styleStrOrHrefsArr, { host: element });
|
|
27
|
+
element.constructor.render(renderResult, shadowRoot, styleStrOrHrefsArr, forStaticArea, { host: element });
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export default updateShadowRoot;
|
|
@@ -5,27 +5,27 @@ const isFocusTrap = el => {
|
|
|
5
5
|
return el.hasAttribute("data-ui5-focus-trap");
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
const getFirstFocusableElement = async container => {
|
|
8
|
+
const getFirstFocusableElement = async (container, startFromContainer) => {
|
|
9
9
|
if (!container || isNodeHidden(container)) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
return findFocusableElement(container, true);
|
|
13
|
+
return findFocusableElement(container, true, startFromContainer);
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const getLastFocusableElement = async container => {
|
|
16
|
+
const getLastFocusableElement = async (container, startFromContainer) => {
|
|
17
17
|
if (!container || isNodeHidden(container)) {
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
return findFocusableElement(container, false);
|
|
21
|
+
return findFocusableElement(container, false, startFromContainer);
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const isElemFocusable = el => {
|
|
25
25
|
return el.hasAttribute("data-ui5-focus-redirect") || !isNodeHidden(el);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const findFocusableElement = async (container, forward) => {
|
|
28
|
+
const findFocusableElement = async (container, forward, startFromContainer) => {
|
|
29
29
|
let child;
|
|
30
30
|
|
|
31
31
|
if (container.shadowRoot) {
|
|
@@ -33,8 +33,10 @@ const findFocusableElement = async (container, forward) => {
|
|
|
33
33
|
} else if (container.assignedNodes && container.assignedNodes()) {
|
|
34
34
|
const assignedElements = container.assignedNodes();
|
|
35
35
|
child = forward ? assignedElements[0] : assignedElements[assignedElements.length - 1];
|
|
36
|
+
} else if (startFromContainer) {
|
|
37
|
+
child = container;
|
|
36
38
|
} else {
|
|
37
|
-
child = forward ? container.
|
|
39
|
+
child = forward ? container.firstElementChild : container.lastElementChild;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
let focusableDescendant;
|
|
@@ -5,18 +5,20 @@ import { attachBoot } from "../Boot.js";
|
|
|
5
5
|
let politeSpan;
|
|
6
6
|
let assertiveSpan;
|
|
7
7
|
|
|
8
|
+
const setOutOfViewportStyles = el => {
|
|
9
|
+
el.style.position = "absolute";
|
|
10
|
+
el.style.clip = "rect(1px,1px,1px,1px)";
|
|
11
|
+
el.style.userSelect = "none";
|
|
12
|
+
el.style.left = "-1000px";
|
|
13
|
+
el.style.top = "-1000px";
|
|
14
|
+
el.style.pointerEvents = "none";
|
|
15
|
+
};
|
|
16
|
+
|
|
8
17
|
attachBoot(() => {
|
|
9
18
|
if (politeSpan && assertiveSpan) {
|
|
10
19
|
return;
|
|
11
20
|
}
|
|
12
21
|
|
|
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
22
|
politeSpan = document.createElement("span");
|
|
21
23
|
assertiveSpan = document.createElement("span");
|
|
22
24
|
|
|
@@ -29,8 +31,8 @@ attachBoot(() => {
|
|
|
29
31
|
politeSpan.setAttribute("role", "alert");
|
|
30
32
|
assertiveSpan.setAttribute("role", "alert");
|
|
31
33
|
|
|
32
|
-
politeSpan
|
|
33
|
-
assertiveSpan
|
|
34
|
+
setOutOfViewportStyles(politeSpan);
|
|
35
|
+
setOutOfViewportStyles(assertiveSpan);
|
|
34
36
|
|
|
35
37
|
getSingletonElementInstance("ui5-static-area").appendChild(politeSpan);
|
|
36
38
|
getSingletonElementInstance("ui5-static-area").appendChild(assertiveSpan);
|
|
@@ -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 "../sap/base/security/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;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the normalized event target in cases when it has shadow root.
|
|
3
|
+
* @param {Object} target The original event target
|
|
4
|
+
* @returns {Object} The normalized target
|
|
5
|
+
*/
|
|
6
|
+
const getNormalizedTarget = target => {
|
|
7
|
+
let element = target;
|
|
8
|
+
|
|
9
|
+
if (target.shadowRoot && target.shadowRoot.activeElement) {
|
|
10
|
+
element = target.shadowRoot.activeElement;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return element;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default getNormalizedTarget;
|
|
@@ -3,7 +3,7 @@ const isNodeHidden = node => {
|
|
|
3
3
|
return false;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
return (node.offsetWidth <= 0 && node.offsetHeight <= 0) || node.style.visibility === "hidden";
|
|
6
|
+
return (node.offsetWidth <= 0 && node.offsetHeight <= 0) || (node.style && node.style.visibility === "hidden");
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export default isNodeHidden;
|
package/hash.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
cXJZ69/6jBfio6JHiMNyQTuQ1WE=
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const mkdirp = require('mkdirp');
|
|
3
|
+
|
|
4
|
+
const version = JSON.parse(fs.readFileSync("package.json")).version;
|
|
5
|
+
|
|
6
|
+
// Parse version
|
|
7
|
+
const matches = version.match(/^([0-9]+)\.([0-9]+)\.([0-9]+)(.*)$/);
|
|
8
|
+
if (!matches) {
|
|
9
|
+
throw new Error("Unsupported version format");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const isNext = version.match(/[a-f0-9]{9}$/);
|
|
13
|
+
const buildTime = Math.floor(new Date().getTime() / 1000);
|
|
14
|
+
|
|
15
|
+
const fileContent = `const VersionInfo = {
|
|
16
|
+
version: "${version}",
|
|
17
|
+
major: ${matches[1]},
|
|
18
|
+
minor: ${matches[2]},
|
|
19
|
+
patch: ${matches[3]},
|
|
20
|
+
suffix: "${matches[4]}",
|
|
21
|
+
isNext: ${isNext ? "true" : "false"},
|
|
22
|
+
buildTime: ${buildTime},
|
|
23
|
+
};
|
|
24
|
+
export default VersionInfo;`;
|
|
25
|
+
|
|
26
|
+
mkdirp.sync("dist/generated/");
|
|
27
|
+
fs.writeFileSync("dist/generated/VersionInfo.js", fileContent);
|
package/package-scripts.js
CHANGED
|
@@ -2,27 +2,23 @@ const resolve = require("resolve");
|
|
|
2
2
|
|
|
3
3
|
const assetParametersScript = resolve.sync("@ui5/webcomponents-base/lib/generate-asset-parameters/index.js");
|
|
4
4
|
const stylesScript = resolve.sync("@ui5/webcomponents-base/lib/generate-styles/index.js");
|
|
5
|
+
const versionScript = resolve.sync("@ui5/webcomponents-base/lib/generate-version-info/index.js");
|
|
5
6
|
const serve = resolve.sync("@ui5/webcomponents-tools/lib/serve/index.js");
|
|
6
7
|
const generateHash = resolve.sync("@ui5/webcomponents-tools/lib/hash/generate.js");
|
|
7
8
|
const hashIsUpToDate = resolve.sync("@ui5/webcomponents-tools/lib/hash/upToDate.js");
|
|
8
9
|
const copyUsedModules = resolve.sync("@ui5/webcomponents-tools/lib/copy-list/index.js");
|
|
9
|
-
const replaceGlobalCore = resolve.sync("@ui5/webcomponents-tools/lib/replace-global-core/index.js");
|
|
10
10
|
const esmAbsToRel = resolve.sync("@ui5/webcomponents-tools/lib/esm-abs-to-rel/index.js");
|
|
11
11
|
const UP_TO_DATE = `node "${hashIsUpToDate}" dist/ hash.txt && echo "Up to date."`;
|
|
12
12
|
|
|
13
13
|
const scripts = {
|
|
14
14
|
clean: "rimraf dist && rimraf .port",
|
|
15
15
|
lint: "eslint . --config config/.eslintrc.js",
|
|
16
|
-
prepare: "nps clean integrate copy generateAssetParameters generateStyles",
|
|
16
|
+
prepare: "nps clean integrate copy generateAssetParameters generateVersionInfo generateStyles",
|
|
17
17
|
integrate: {
|
|
18
|
-
default: "nps integrate.copy-used-modules integrate.
|
|
18
|
+
default: "nps integrate.copy-used-modules integrate.replace-amd integrate.amd-to-es6 integrate.esm-abs-to-rel integrate.third-party",
|
|
19
19
|
"copy-used-modules": `node "${copyUsedModules}" ./used-modules.txt dist/`,
|
|
20
|
-
"copy-overlay": `copy-and-watch "overlay/**/*.js" dist/`,
|
|
21
20
|
"replace-amd": "replace-in-file sap.ui.define define dist/**/*.js",
|
|
22
|
-
"replace-export-true": `replace-in-file ", /* bExport= */ true" "" dist/**/*.js`,
|
|
23
|
-
"replace-export-false": `replace-in-file ", /* bExport= */ false" "" dist/**/*.js`,
|
|
24
21
|
"amd-to-es6": "amdtoes6 --src=dist/ --replace --glob=**/*.js",
|
|
25
|
-
"replace-global-core-usage": `node "${replaceGlobalCore}" dist/`,
|
|
26
22
|
"esm-abs-to-rel": `node "${esmAbsToRel}" dist/ dist/`,
|
|
27
23
|
"third-party": {
|
|
28
24
|
default: "nps integrate.third-party.copy integrate.third-party.fix",
|
|
@@ -40,6 +36,7 @@ const scripts = {
|
|
|
40
36
|
test: `copy-and-watch "test/**/*.*" dist/test-resources`,
|
|
41
37
|
},
|
|
42
38
|
generateAssetParameters: `node "${assetParametersScript}"`,
|
|
39
|
+
generateVersionInfo: `node "${versionScript}"`,
|
|
43
40
|
generateStyles: `node "${stylesScript}"`,
|
|
44
41
|
watch: {
|
|
45
42
|
default: 'concurrently "nps watch.test" "nps watch.src" "nps watch.bundle" "nps watch.styles"',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ui5/webcomponents-base",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-deac3098a",
|
|
4
4
|
"description": "UI5 Web Components: webcomponents.base",
|
|
5
5
|
"author": "SAP SE (https://www.sap.com)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"prepublishOnly": "npm run clean && npm run build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"lit-html": "2.0.
|
|
35
|
+
"lit-html": "2.0.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@buxlabs/amd-to-es6": "0.16.1",
|
|
39
39
|
"@openui5/sap.ui.core": "1.94.0",
|
|
40
|
-
"@ui5/webcomponents-tools": "0.0.0-
|
|
41
|
-
"chromedriver": "
|
|
40
|
+
"@ui5/webcomponents-tools": "0.0.0-deac3098a",
|
|
41
|
+
"chromedriver": "100.0.0",
|
|
42
42
|
"clean-css": "^5.2.2",
|
|
43
43
|
"copy-and-watch": "^0.1.5",
|
|
44
44
|
"eslint": "^7.22.0",
|
package/src/Boot.js
CHANGED
|
@@ -1,40 +1,56 @@
|
|
|
1
|
-
import EventProvider from "./EventProvider.js";
|
|
2
1
|
import whenDOMReady from "./util/whenDOMReady.js";
|
|
3
2
|
import insertFontFace from "./FontFace.js";
|
|
4
3
|
import insertSystemCSSVars from "./SystemCSSVars.js";
|
|
5
4
|
import { getTheme } from "./config/Theme.js";
|
|
6
5
|
import applyTheme from "./theming/applyTheme.js";
|
|
6
|
+
import { registerCurrentRuntime } from "./Runtimes.js";
|
|
7
7
|
import { getFeature } from "./FeaturesRegistry.js";
|
|
8
8
|
|
|
9
|
-
let
|
|
10
|
-
const eventProvider = new EventProvider();
|
|
9
|
+
let bootPromise;
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Attach a callback that will be executed on boot
|
|
14
13
|
* @public
|
|
15
14
|
* @param listener
|
|
16
15
|
*/
|
|
17
|
-
const attachBoot = listener => {
|
|
18
|
-
|
|
16
|
+
const attachBoot = async listener => {
|
|
17
|
+
await boot();
|
|
18
|
+
listener();
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const boot = async () => {
|
|
22
|
-
if (
|
|
23
|
-
return;
|
|
22
|
+
if (bootPromise) {
|
|
23
|
+
return bootPromise;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
/* eslint-disable no-alert, no-async-promise-executor */
|
|
27
|
+
/*
|
|
28
|
+
Note(since we disable eslint rule):
|
|
29
|
+
If an async executor function throws an error, the error will be lost and won't cause the newly-constructed Promise to reject.
|
|
30
|
+
This could make it difficult to debug and handle some errors.
|
|
31
|
+
*/
|
|
32
|
+
bootPromise = new Promise(async resolve => {
|
|
33
|
+
registerCurrentRuntime();
|
|
34
|
+
|
|
35
|
+
const OpenUI5Support = getFeature("OpenUI5Support");
|
|
36
|
+
const F6Navigation = getFeature("F6Navigation");
|
|
37
|
+
if (OpenUI5Support) {
|
|
38
|
+
await OpenUI5Support.init();
|
|
39
|
+
} else if (F6Navigation) {
|
|
40
|
+
F6Navigation.init();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await whenDOMReady();
|
|
44
|
+
await applyTheme(getTheme());
|
|
45
|
+
OpenUI5Support && OpenUI5Support.attachListeners();
|
|
46
|
+
insertFontFace();
|
|
47
|
+
insertSystemCSSVars();
|
|
48
|
+
|
|
49
|
+
resolve();
|
|
50
|
+
});
|
|
51
|
+
/* eslint-enable no-alert, no-async-promise-executor */
|
|
30
52
|
|
|
31
|
-
|
|
32
|
-
await applyTheme(getTheme());
|
|
33
|
-
OpenUI5Support && OpenUI5Support.attachListeners();
|
|
34
|
-
insertFontFace();
|
|
35
|
-
insertSystemCSSVars();
|
|
36
|
-
await eventProvider.fireEventAsync("boot");
|
|
37
|
-
booted = true;
|
|
53
|
+
return bootPromise;
|
|
38
54
|
};
|
|
39
55
|
|
|
40
56
|
export {
|