UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

185 lines (154 loc) 5.76 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ sap.ui.define([ 'sap/base/future', 'sap/base/Log' ], function (future, Log) { "use strict"; var mLibThemeMetadata = {}; // Theme defaulting const DEFAULT_THEME = "sap_horizon"; // dark mode detection const bDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; // Theme Fallback for variants const rThemeVariantPattern = /(_hcb|_hcw|_dark)$/g; /** * The list of all known themes incl. their variants. * Any SAP theme outside this list will receive a fallback to the predefined default theme. * * Note: This list needs to be updated on each release and/or removal of a theme. */ const aKnownThemes = [ // horizon "sap_horizon", "sap_horizon_dark", "sap_horizon_hcb", "sap_horizon_hcw", // fiori_3 "sap_fiori_3", "sap_fiori_3_dark", "sap_fiori_3_hcb", "sap_fiori_3_hcw" ]; // cache for already calculated theme fallbacks const mThemeFallbacks = {}; /** * * @since 1.92.0 * @alias sap.ui.core.theming.ThemeHelper * @static * @namespace * @private * @ui5-restricted sap.ui.core */ var ThemeHelper = {}; ThemeHelper.reset = function () { mLibThemeMetadata = {}; }; ThemeHelper.getMetadata = function (sLibId) { if (!sLibId) { return null; } var sLibName = sLibId.replace("sap-ui-theme-", "").replace(/\./g, "-"); if (mLibThemeMetadata[sLibName]) { return mLibThemeMetadata[sLibName]; } var oMetadataElement = document.createElement("span"); oMetadataElement.classList.add("sapThemeMetaData-UI5-" + sLibName); document.documentElement.appendChild(oMetadataElement); var sDataUri = window.getComputedStyle(oMetadataElement).getPropertyValue("background-image"); document.documentElement.removeChild(oMetadataElement); var aDataUriMatch = /\(["']?data:text\/plain;utf-8,(.*?)['"]?\)/i.exec(sDataUri); if (!aDataUriMatch || aDataUriMatch.length < 2) { return null; } var sMetaData = aDataUriMatch[1]; // [COMPATIBILITY]: The following lines of code are moved unchanged from ThemeManager in order to not introduce any regressions but // neverteheless it's not fully clear if detection of URI encoding and URI decoding itself (especially manual encoding of spaces) // is necessary // Try to detect URI encoding by checking for first and last character for not encoded characters if (sMetaData.charAt(0) !== "{" && sMetaData.charAt(sMetaData.length - 1) !== "}") { try { sMetaData = decodeURI(sMetaData); } catch (ex) { // ignore } } // Remove superfluous escaping of double quotes sMetaData = sMetaData.replace(/\\"/g, '"'); // Replace encoded spaces => not clear if this is really necessary and if there is any valid case where spaces are URI encoded // but we could not detect URI encoding. Keep coding in order to avoid regression. var sMetadataJSON = sMetaData.replace(/%20/g, " "); var oMetadata; try { oMetadata = JSON.parse(sMetadataJSON); mLibThemeMetadata[sLibName] = oMetadata; } catch (ex) { future.errorThrows("Could not parse theme metadata for library " + sLibName + "."); } return oMetadata; }; /** * Validates the given theme and changes it to the predefined standard fallback theme if needed. * * An SAP standard theme is considered invalid when it is either: * - not available anymore (deprecated & removed) * - not yet available (meaning: released in future versions) * * Invalid themes will be defaulted to the predetermined standard default theme. * * Themes for which a theme root exists are expected to be served from their given origin * and will not be adapted. * * @param {string} sTheme the theme to be validated * @param {string|null} sThemeRoot the theme root url for the given theme * @returns {string} the validated and transformed theme name */ ThemeHelper.validateAndFallbackTheme = function(sTheme, sThemeRoot) { // check cache for already determined fallback // only do this for themes from the default location (potential SAP standard themes) if (sThemeRoot == null && mThemeFallbacks[sTheme]) { return mThemeFallbacks[sTheme]; } let sNewTheme = sTheme; // We only fallback for a very specific set of themes: // * no theme-root is given (themes from a different endpoint (i.e. theming-service) are excluded) and // * the given theme is a standard SAP theme ('sap_' prefix) // * not supported in this version if (sThemeRoot == null && (!sTheme || (sTheme.startsWith("sap_") && aKnownThemes.indexOf(sTheme) == -1))) { let sVariant; if (sTheme) { // extract the theme variant if given: "_hcb", "_hcw", "_dark" sVariant = sTheme.match(rThemeVariantPattern)?.[0] || ""; Log.warning(`The configured theme '${sTheme}' is not yet or no longer supported in this version. The valid fallback theme is '${DEFAULT_THEME}${sVariant}'.`, "Theming"); } else { sVariant = bDarkMode ? "_dark" : ""; } sNewTheme = `${DEFAULT_THEME}${sVariant}`; mThemeFallbacks[sTheme] = sNewTheme; } return sNewTheme; }; ThemeHelper.getDefaultThemeInfo = function() { return { DEFAULT_THEME: DEFAULT_THEME, DARK_MODE: bDarkMode }; }; /** * Checks whether the theme is a SAP delivered standard theme or not. * * @param {string} sTheme Name of the theme to check * @returns {boolean} true if the theme is a standard theme, false otherwise * @private * @ui5-restricted sap/ui/core/Theming, sap.ui.core.theming.ThemeManager * @since 1.135 */ ThemeHelper.isStandardTheme = function(sTheme) { return sTheme.startsWith("sap_") || sTheme === "base"; }; return ThemeHelper; });