(function() {
/** SVG icon template handling for UR harmonization */
Help4.engine.ur.IconTemplate = class {
static ICON_THEME_MAP = {
horizon: 'sap_horizon',
belize: 'sap_belize',
quartz: 'sap_fiori_3'
};
static CSS_VAR_PREFIX = '--help4-sap-ui-icon';
static SVG_CLASS_TO_VAR = {
sapSvgIconNegative: {fill: `var(${this.CSS_VAR_PREFIX}-negative)`}, // orig color: #fa6161 !important
sapSvgIconCritical: {fill: `var(${this.CSS_VAR_PREFIX}-critical)`}, // #f7bf00 !important
sapSvgIconPositive: {fill: `var(${this.CSS_VAR_PREFIX}-positive)`}, // #6dad1f !important
sapSvgIconBase: {fill: `var(${this.CSS_VAR_PREFIX}-base)`} // #1d232a !important
};
/**
* Load icon library matching current theme
* @param {Help4.engine.ur.UrHarmonizationEngine} engine
*/
static async prepare(engine) {
const {dom, existingSvg, currentBase, loadIcons} = _checkCurrent.call(this, engine);
if (!loadIcons) return;
// create a copy of the icons in the Companion DOM
let response = await fetch(`/sap/public/icmandir/its/ls/theming/Base/baseLib/${currentBase}/svg/libs/SAPGUI-icons.svg`);
if (!response.ok && engine._mock) response = await fetch(`${currentBase}-SAPGUI-icons.svg`); // attempt loading directly from mock system
engine._failedIconBase = response.ok ? null : currentBase; // do not reset on app navigation, template comes from top origin
if (!response.ok) {
engine._log?.('CMP: Unable to load icon library', response, undefined, Help4.engine.ur.Connection.LOG_LEVEL.WARNING);
return;
}
const svgText = await response.text();
if (svgText.startsWith('<?xml ') && svgText.includes('<svg ')) {
const {Element} = Help4;
const {SVG_CLASS_TO_VAR} = this;
const {ICON_LIB_ID} = engine.constructor;
const {content} = Element.create('template', {html: svgText});
// rename ids to be Help4-specific
content.querySelectorAll('symbol[id]')
.forEach(s => s.id = `${ICON_LIB_ID}-${s.id}`);
content.querySelectorAll('path[class]')
.forEach(path => {
const style = SVG_CLASS_TO_VAR[path.getAttribute('class')];
if (style) {
path.removeAttribute('class');
Help4.extendObject(path.style, style);
}
});
/** @type {Node} */
const svg = content.querySelector('svg')?.cloneNode(true) || document.createElement('svg');
Element.setAttribute(svg, {
id: ICON_LIB_ID,
style: {display: 'none'},
'data-theme': currentBase
});
existingSvg
? existingSvg.replaceWith(svg)
: dom.appendChild(svg);
}
}
}
/**
* @memberof Help4.engine.ur
* @private
* @param {Help4.engine.ur.UrHarmonizationEngine} engine
* @returns {{dom: ShadowRoot|HTMLElement, existingSvg: ?HTMLElement, currentBase: string, loadIcons: boolean}}
*/
function _checkCurrent(engine) {
const {ICON_THEME_MAP} = this;
const {
_failedIconBase,
constructor: {ICON_LIB_ID},
controller
} = engine;
const {CMP4, core: {theme}} = controller.getConfiguration();
const dom = /** @type {ShadowRoot|HTMLElement} */ CMP4 ? controller.getDom2('shadow') : controller.getDom();
const existingSvg = /** @type {HTMLElement} */ dom.querySelector('#' + ICON_LIB_ID);
const currentBase = /** @type {string} */ Object.entries(ICON_THEME_MAP).find(([key]) => theme.includes(key))?.[1] || 'sap_horizon';
const loadedBase = /** @type {string} */ existingSvg ? existingSvg.dataset.help4Theme : '';
// load icons if they haven't failed to load before and the existing SVG is outdated
const loadIcons = currentBase !== _failedIconBase && (!existingSvg || currentBase !== loadedBase);
return {dom, existingSvg, currentBase, loadIcons};
}
})();