UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

821 lines (727 loc) 31 kB
/*! * OpenUI5 * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ /** * @namespace * @name sap.ui.core.theming * @public */ sap.ui.define([ 'sap/ui/core/Core', 'sap/ui/core/Configuration', 'sap/ui/core/Lib', 'sap/ui/thirdparty/URI', '../Element', 'sap/base/util/UriParameters', 'sap/base/Log', 'sap/base/util/extend', 'sap/base/util/syncFetch', 'sap/ui/core/theming/ThemeManager', './ThemeHelper' ], function(Core, Configuration, Library, URI, Element, UriParameters, Log, extend, syncFetch, ThemeManager, ThemeHelper) { "use strict"; var syncCallBehavior = Configuration.getSyncCallBehavior(); /** * A helper used for (read-only) access to CSS parameters at runtime. * * @author SAP SE * @namespace * * @public * @alias sap.ui.core.theming.Parameters */ var Parameters = {}; var mParameters = null; var sTheme = null; var aParametersToLoad = []; var aCallbackRegistry = []; var sBootstrapOrigin = new URI(sap.ui.require.toUrl(""), document.baseURI).origin(); var mOriginsNeedingCredentials = {}; // match a CSS url var rCssUrl = /url[\s]*\('?"?([^\'")]*)'?"?\)/; var bUseInlineParameters = UriParameters.fromQuery(window.location.search).get("sap-ui-xx-no-inline-theming-parameters") !== "true"; /** * Resolves relative URLs in parameter values. * Only for inline-parameters. */ function checkAndResolveRelativeUrl(sUrl, sThemeBaseUrl) { var aMatch = rCssUrl.exec(sUrl); if (aMatch) { var oUri = new URI(aMatch[1]); if (oUri.is("relative")) { // Rewrite relative URLs based on the theme base url // Otherwise they would be relative to the HTML page which is incorrect var sNormalizedUrl = oUri.absoluteTo(sThemeBaseUrl).normalize().toString(); sUrl = "url('" + sNormalizedUrl + "')"; } } return sUrl; } function mergeParameterSet(mCurrent, mNew, sThemeBaseUrl) { for (var sParam in mNew) { if (typeof mCurrent[sParam] === "undefined") { mCurrent[sParam] = checkAndResolveRelativeUrl(mNew[sParam], sThemeBaseUrl); } } return mCurrent; } function mergeParameters(mNewParameters, sThemeBaseUrl) { // normalize parameter maps // scoped themes like sap_belize already provide nested objects: if (typeof mNewParameters["default"] !== "object") { mNewParameters = { "default": mNewParameters, "scopes": {} }; } // ensure parameters objects mParameters = mParameters || {}; mParameters["default"] = mParameters["default"] || {}; mParameters["scopes"] = mParameters["scopes"] || {}; // merge default parameters mergeParameterSet(mParameters["default"], mNewParameters["default"], sThemeBaseUrl); // merge scopes if (typeof mNewParameters["scopes"] === "object") { for (var sScopeName in mNewParameters["scopes"]) { // ensure scope object mParameters["scopes"][sScopeName] = mParameters["scopes"][sScopeName] || {}; // merge scope set mergeParameterSet(mParameters["scopes"][sScopeName], mNewParameters["scopes"][sScopeName], sThemeBaseUrl); } } } function forEachStyleSheet(fnCallback) { document.querySelectorAll("link[id^=sap-ui-theme-]").forEach(function(linkNode) { fnCallback(linkNode.getAttribute("id")); }); } function parseParameters(sId, bAsync) { var oUrl = getThemeBaseUrlForId(sId); var bThemeApplied = ThemeHelper.checkAndRemoveStyle({ id: sId }); if (!bThemeApplied && !bAsync) { Log.warning("Parameters have been requested but theme is not applied, yet.", "sap.ui.core.theming.Parameters"); } // In some browsers (e.g. Safari) it might happen that after switching the theme or adopting the <link>'s href, // the parameters from the previous stylesheet are taken. This can be prevented by checking whether the theme is applied. if (bThemeApplied && bUseInlineParameters) { var oLink = document.getElementById(sId); var sDataUri = window.getComputedStyle(oLink).getPropertyValue("background-image"); var aParams = /\(["']?data:text\/plain;utf-8,(.*?)['"]?\)$/i.exec(sDataUri); if (aParams && aParams.length >= 2) { var sParams = aParams[1]; // decode only if necessary if (sParams.charAt(0) !== "{" && sParams.charAt(sParams.length - 1) !== "}") { try { sParams = decodeURIComponent(sParams); } catch (ex) { Log.warning("Could not decode theme parameters URI from " + oUrl.styleSheetUrl); } } try { var oParams = JSON.parse(sParams); mergeParameters(oParams, oUrl.themeBaseUrl); return true; // parameters successfully parsed } catch (ex) { Log.warning("Could not parse theme parameters from " + oUrl.styleSheetUrl + ". Loading library-parameters.json as fallback solution."); } } } // sync: return false if parameter could not be parsed OR theme is not applied OR library has no parameters // For sync path this triggers a sync library-parameters.json request as fallback // async: always return bThemeApplied. Issues during parsing are not relevant for further processing because // there is no fallback as in the sync case return bAsync ? bThemeApplied : false; } /** * Load parameters for a library/theme combination as identified by the URL of the library.css * @param {string} sId the library name for which parameters might be loaded */ function loadParameters(sId) { var oUrl = getThemeBaseUrlForId(sId); // try to parse the inline-parameters for the given library // this may fail for a number of reasons, see below if (!parseParameters(sId)) { // derive parameter file URL from CSS file URL // $1: name of library (incl. variants) // $2: additional parameters, e.g. for sap-ui-merged, version/sap-ui-dist-version var sUrl = oUrl.styleSheetUrl.replace(/\/(?:css_variables|library)([^\/.]*)\.(?:css|less)($|[?#])/, function($0, $1, $2) { return "/library-parameters.json" + ($2 ? $2 : ""); }); if (syncCallBehavior === 2) { Log.error("[nosync] Loading library-parameters.json ignored", sUrl, "sap.ui.core.theming.Parameters"); return; } else if (syncCallBehavior === 1) { Log.error("[nosync] Loading library-parameters.json with sync XHR", sUrl, "sap.ui.core.theming.Parameters"); } // check if we need to send credentials var sThemeOrigin = new URI(oUrl.themeBaseUrl).origin(); var bWithCredentials = mOriginsNeedingCredentials[sThemeOrigin]; var aWithCredentials = []; // initially we don't have any information if the target origin needs credentials or not ... if (bWithCredentials === undefined) { // ... so we assume that for all cross-origins except the UI5 bootstrap we need credentials. // Setting the XHR's "withCredentials" flag does not do anything for same origin requests. if (sUrl.startsWith(sBootstrapOrigin)) { aWithCredentials = [false, true]; } else { aWithCredentials = [true, false]; } } else { aWithCredentials = [bWithCredentials]; } // trigger a sync. loading of the parameters.json file loadParametersJSON(sUrl, oUrl.themeBaseUrl, aWithCredentials); } } function getThemeBaseUrlForId (sId) { // read inline parameters from css style rule // (can be switched off for testing purposes via private URI parameter "sap-ui-xx-no-inline-theming-parameters=true") var oLink = document.getElementById(sId); if (!oLink) { Log.warning("Could not find stylesheet element with ID", sId, "sap.ui.core.theming.Parameters"); return undefined; } var sStyleSheetUrl = oLink.href; // Remove CSS file name and query to create theme base url (to resolve relative urls) return { themeBaseUrl: new URI(sStyleSheetUrl).filename("").query("").toString(), styleSheetUrl : sStyleSheetUrl }; } /** * Loads a parameters.json file from given URL. * @param {string} sUrl URL * @param {string} sThemeBaseUrl Base URL * @param {boolean[]} aWithCredentials probing values for requesting with or without credentials */ function loadParametersJSON(sUrl, sThemeBaseUrl, aWithCredentials) { var oHeaders = { Accept: syncFetch.ContentTypes.JSON }; var bCurrentWithCredentials = aWithCredentials.shift(); if (bCurrentWithCredentials) { // the X-Requested-With Header is essential for the Theming-Service to determine if a GET request will be handled // This forces a preflight request which should give us valid Allow headers: // Access-Control-Allow-Origin: ... fully qualified requestor origin ... // Access-Control-Allow-Credentials: true oHeaders["X-Requested-With"] = "XMLHttpRequest"; } function fnErrorCallback(error) { // ignore failure at least temporarily as long as there are libraries built using outdated tools which produce no json file Log.error("Could not load theme parameters from: " + sUrl, error); // could be an error as well, but let's avoid more CSN messages... if (aWithCredentials.length > 0) { // In a CORS scenario, IF we have sent credentials on the first try AND the request failed, // we expect that a service could have answered with the following Allow header: // Access-Control-Allow-Origin: * // In this case we must not send credentials, otherwise the service would have answered with: // Access-Control-Allow-Origin: https://... // Access-Control-Allow-Credentials: true // Due to security constraints, the browser does not hand out any more information in a CORS scenario, // so now we try again without credentials. Log.warning("Initial library-parameters.json request failed ('withCredentials=" + bCurrentWithCredentials + "'; sUrl: '" + sUrl + "').\n" + "Retrying with 'withCredentials=" + !bCurrentWithCredentials + "'.", "sap.ui.core.theming.Parameters"); loadParametersJSON(sUrl, sThemeBaseUrl, aWithCredentials); } } // load and evaluate parameter file try { var response = syncFetch(sUrl, { credentials: bCurrentWithCredentials ? "include" : "omit", headers: oHeaders }); if (response.ok) { var data = response.json(); // Once we have a successful request we track the credentials setting for this origin var sThemeOrigin = new URI(sThemeBaseUrl).origin(); mOriginsNeedingCredentials[sThemeOrigin] = bCurrentWithCredentials; if (Array.isArray(data)) { // in the sap-ui-merged use case, multiple JSON files are merged into and transfered as a single JSON array for (var j = 0; j < data.length; j++) { var oParams = data[j]; mergeParameters(oParams, sThemeBaseUrl); } } else { mergeParameters(data, sThemeBaseUrl); } } else { throw new Error(response.statusText || response.status); } } catch (error) { fnErrorCallback(error); } } /** * Retrieves a map containing all inline-parameters. * * @param {boolean} bAsync=undefined whether to load and parse the parameters asynchronously, default sync * @returns {object} a map of all parameters */ function getParameters(bAsync) { // Inital loading if (!mParameters) { // Merge an empty parameter set to initialize the internal object mergeParameters({}, ""); forEachStyleSheet(function (sId) { if (bAsync) { if (!parseParameters(sId, bAsync)) { aParametersToLoad.push(sId); } } else { loadParameters(sId); } }); } return mParameters; } function parsePendingLibraryParameters() { var aPendingThemes = []; aParametersToLoad.forEach(function (sId) { // Try to parse parameters (in case theme is already applied). Else keep parameter ID for later if (!parseParameters(sId, /*bAsync=*/true)) { aPendingThemes.push(sId); } }); // Keep theme IDs which are not ready for later aParametersToLoad = aPendingThemes; } /** * Loads library-parameters.json files if some libraries are missing. */ function loadPendingLibraryParameters() { // lazy loading of further library parameters aParametersToLoad.forEach(loadParameters); // clear queue aParametersToLoad = []; } /** * Called by the Core when a new library and its stylesheet have been loaded. * Must be called AFTER a link-tag (with id: "sap-ui-theme" + sLibName) for the theme has been created. * @param {string} sLibId id of theme link-tag * @private */ Parameters._addLibraryTheme = function(sLibId) { // only queue new libraries if some have been loaded already // otherwise they will be loaded when the first one requests a parameter // see "Parameters.get" for lazy loading of queued library parameters if (mParameters) { aParametersToLoad.push("sap-ui-theme-" + sLibId); } }; /** * Returns parameter value from given map and handles legacy parameter names * * @param {object} mOptions options map * @param {string} mOptions.parameterName Parameter name / key * @param {string} mOptions.scopeName Scope name * @param {boolean} mOptions.loadPendingParameters If set to "true" and no parameter value is found, * all pending parameters will be loaded (see Parameters._addLibraryTheme) * @param {boolean} mOptions.async whether the parameter value should be retrieved asynchronous * @returns {string|undefined} parameter value or undefined * @private */ function getParam(mOptions) { var bAsync = mOptions.async, oParams = getParameters(bAsync); if (mOptions.scopeName) { oParams = oParams["scopes"][mOptions.scopeName]; } else { oParams = oParams["default"]; } var sParamValue = oParams[mOptions.parameterName]; // [Compatibility]: if a parameter contains a prefix, we cut off the ":" and try again // e.g. "my.lib:paramName" if (!sParamValue) { var iIndex = mOptions.parameterName.indexOf(":"); if (iIndex != -1) { var sParamNameWithoutColon = mOptions.parameterName.substr(iIndex + 1); sParamValue = oParams[sParamNameWithoutColon]; } } // Sync: Fallback path for when parameter could not be found so far, library.css MIGHT be not loaded if (mOptions.loadPendingParameters && typeof sParamValue === "undefined" && !bAsync) { // Include library theme in case it's not already done, since link tag for library // is added asynchronous after initLibrary has been executed var aAllLibrariesRequireCss = Library.getAllInstancesRequiringCss(); aAllLibrariesRequireCss.forEach(function (oLibThemingInfo) { ThemeManager._includeLibraryThemeAndEnsureThemeRoot(oLibThemingInfo); }); loadPendingLibraryParameters(); sParamValue = getParam({ parameterName: mOptions.parameterName, scopeName: mOptions.scopeName, loadPendingParameters: false // prevent recursion }); } return sParamValue; } function getParamForActiveScope(sParamName, oElement, bAsync) { // check for scopes and try to find the classes in Control Tree var aScopeChain = Parameters.getActiveScopesFor(oElement, bAsync); var aFilteredScopeChain = aScopeChain.flat().reduce(function (aResult, sScope) { if (aResult.indexOf(sScope) === -1) { aResult.push(sScope); } return aResult; }, []); for (var i = 0; i < aFilteredScopeChain.length; i++) { var sScopeName = aFilteredScopeChain[i]; var sParamValue = getParam({ parameterName: sParamName, scopeName: sScopeName, async: bAsync }); if (sParamValue) { return sParamValue; } } // if no matching scope was found return the default parameter return getParam({ parameterName: sParamName, async: bAsync }); } /** * Returns the scopes from current theming parameters. * * @private * @ui5-restricted sap.ui.core * @param {boolean} [bAvoidLoading] Whether loading of parameters should be avoided * @param {boolean} [bAsync] Whether loading of parameters should be asynchronous * @return {string[]|undefined} Scope names */ Parameters._getScopes = function(bAvoidLoading, bAsync) { if ( bAvoidLoading && !mParameters ) { return; } var oParams = getParameters(bAsync); var aScopes = Object.keys(oParams["scopes"]); return aScopes; }; /** * Returns the active scope(s) for a given control by looking up the hierarchy. * * The lookup navigates the DOM hierarchy if it's available. Otherwise if controls aren't rendered yet, * it navigates the control hierarchy. By navigating the control hierarchy, inner-html elements * with the respective scope classes can't get recognized as the Custom Style Class API does only for * root elements. * * @private * @ui5-restricted sap.viz * @param {object} oElement element/control instance * @param {boolean} bAsync Whether the scope should be retrieved asynchronous * @return {Array.<Array.<string>>} Two dimensional array with scopes in bottom up order */ Parameters.getActiveScopesFor = function(oElement, bAsync) { var aScopeChain = []; if (oElement instanceof Element) { var domRef = oElement.getDomRef(); // make sure to first load all pending parameters // doing it later (lazy) might change the behavior in case a scope is initially not defined if (bAsync) { parsePendingLibraryParameters(); } else { loadPendingLibraryParameters(); } // check for scopes and try to find the classes in parent chain var aScopes = this._getScopes(undefined, bAsync); if (aScopes.length) { if (domRef) { var fnNodeHasStyleClass = function(sScopeName) { var scopeList = domRef.classList; return scopeList && scopeList.contains(sScopeName); }; while (domRef) { var aFoundScopeClasses = aScopes.filter(fnNodeHasStyleClass); if (aFoundScopeClasses.length > 0) { aScopeChain.push(aFoundScopeClasses); } domRef = domRef.parentNode; } } else { var fnControlHasStyleClass = function(sScopeName) { return typeof oElement.hasStyleClass === "function" && oElement.hasStyleClass(sScopeName); }; while (oElement) { var aFoundScopeClasses = aScopes.filter(fnControlHasStyleClass); if (aFoundScopeClasses.length > 0) { aScopeChain.push(aFoundScopeClasses); } oElement = typeof oElement.getParent === "function" && oElement.getParent(); } } } } return aScopeChain; }; /** * <p> * Returns the current value for one or more theming parameters, depending on the given arguments. * The synchronous usage of this API has been deprecated and only the asynchronous usage should still be used * (see the 4th bullet point and the code examples below). * </p> * * <p> * The theming parameters are immutable and cannot be changed at runtime. * Multiple <code>Parameters.get()</code> API calls for the same parameter name will always result in the same parameter value. * </p> * * <p> * The following API variants are available (see also the below examples): * <ul> * <li> <b>(deprecated since 1.92)</b> If no parameter is given a key-value map containing all parameters is returned</li> * <li> <b>(deprecated since 1.94)</b> If a <code>string</code> is given as first parameter the value is returned as a <code>string</code></li> * <li> <b>(deprecated since 1.94)</b> If an <code>array</code> is given as first parameter a key-value map containing all parameters from the <code>array</code> is returned</li> * <li>If an <code>object</code> is given as first parameter the result is returned immediately in case all parameters are loaded and available or within the callback in case not all CSS files are already loaded. * This is the <b>only asynchronous</b> API variant. This variant is the preferred way to retrieve theming parameters. * The structure of the return value is the same as listed above depending on the type of the name property within the <code>object</code>.</li> * </ul> * </p> * * <p>The returned key-value maps are a copy so changing values in the map does not have any effect</p> * * <p> * Please see the examples below for a detailed guide on how to use the <b>asynchronous variant</b> of the API. * </p> * * @example <caption>Scenario 1: Parameters are already available</caption> * // "sapUiParam1", "sapUiParam2", "sapUiParam3" are already available * Parameters.get({ * name: ["sapUiParam1", "sapUiParam2", "sapUiParam3"], * callback: function(mParams) { * // callback is not called, since all Parameters are available synchronously * } * }); * // As described above, returns a map with key-value pairs corresponding to the parameters: * // mParams = {sapUiParam1: '...value...', sapUiParam2: '...value...', sapUiParam3: '...value...'} * * @example <caption>Scenario 2: Some Parameters are missing </caption> * // "sapUiParam1", "sapUiParam2" are already available * // "sapUiParam3" is not yet available * Parameters.get({ * name: ["sapUiParam1", "sapUiParam2", "sapUiParam3"], * callback: function(mParams) { * // Parameters.get() callback gets the same map with key-value pairs as in "Scenario 1". * // mParams = {sapUiParam1: '...value...', sapUiParam2: '...value...', sapUiParam3: '...value...'} * } * }); * // return-value is undefined, since not all Parameters are yet available synchronously * * @example <caption>Scenario 3: Default values</caption> * // Scenario 1 (all parameters are available): the returned parameter map can be used to merge with a map of default values. * // Scenario 2 (one or more parameters are missing): the returned undefined value does not change the default parameters * // This allows you to always retrieve a consistent set of parameters, either synchronously via the return-value or asynchronously via the provided callback. * var mMyParams = Object.assign({ * sapUiParam1: "1rem", * sapUiParam2: "#FF0000", * sapUiParam3: "16px" * }, Parameters.get({ * name: ["sapUiParam1", "sapUiParam2", "sapUiParam3"], * callback: function(mParams) { * // merge the current parameters with the actual parameters in case they are retrieved asynchronously * Object.assign(mMyParams, mParams); * } * }); * * @param {string | string[] | object} vName the (array with) CSS parameter name(s) or an object containing the (array with) CSS parameter name(s), * the scopeElement and a callback for async retrieval of parameters. * @param {string | string[]} vName.name the (array with) CSS parameter name(s) * @param {sap.ui.core.Element} [vName.scopeElement] * Element / control instance to take into account when looking for a parameter value. * This can make a difference when a parameter value is overridden in a theme scope set via a CSS class. * @param {function} [vName.callback] If given, the callback is only executed in case there are still parameters pending and one or more of the requested parameters is missing. * @param {sap.ui.core.Element} [oElement] * Element / control instance to take into account when looking for a parameter value. * This can make a difference when a parameter value is overridden in a theme scope set via a CSS class. * @returns {string | object | undefined} the CSS parameter value(s) or <code>undefined</code> if the parameters could not be retrieved. * * @public */ Parameters.get = function(vName, oElement) { var sParamName, fnAsyncCallback, bAsync, aNames, iIndex; var findRegisteredCallback = function (oCallbackInfo) { return oCallbackInfo.callback === fnAsyncCallback; }; if (!Core.isInitialized()) { Log.warning("Called sap.ui.core.theming.Parameters.get() before core has been initialized. " + "Consider using the API only when required, e.g. onBeforeRendering."); } if (!sTheme) { sTheme = Configuration.getTheme(); } // Parameters.get() without arguments returns // copy of complete default parameter set if (arguments.length === 0) { Log.warning( "Legacy variant usage of sap.ui.core.theming.Parameters.get API detected. Do not use the Parameters.get() API to retrieve ALL theming parameters, " + "as this will lead to unwanted synchronous requests. " + "Use the asynchronous API variant instead and retrieve a fixed set of parameters.", "LegacyParametersGet", "sap.ui.support", function() { return { type: "LegacyParametersGet" }; } ); // first try to load all pending parameters loadPendingLibraryParameters(); // retrieve parameters // optionally might also trigger a sync JSON request, if a library was loaded but not parsed yet var oParams = getParameters(); return Object.assign({}, oParams["default"]); } if (!vName) { return undefined; } if (vName instanceof Object && !Array.isArray(vName)) { // async variant of Parameters.get if (!vName.name) { Log.warning("sap.ui.core.theming.Parameters.get was called with an object argument without one or more parameter names."); return undefined; } oElement = vName.scopeElement; fnAsyncCallback = vName.callback; aNames = typeof vName.name === "string" ? [vName.name] : vName.name; bAsync = true; } else { // legacy variant if (typeof vName === "string") { aNames = [vName]; } else { // vName is Array aNames = vName; } Log.warning( "Legacy variant usage of sap.ui.core.theming.Parameters.get API detected for parameter(s): '" + aNames.join(", ") + "'. This could lead to bad performance and additional synchronous XHRs, as parameters might not be available yet. Use asynchronous variant instead.", "LegacyParametersGet", "sap.ui.support", function() { return { type: "LegacyParametersGet" }; } ); } var resolveWithParameter, vResult; var lookForParameter = function (sName) { if (oElement instanceof Element) { return getParamForActiveScope(sName, oElement, bAsync); } else { if (bAsync) { parsePendingLibraryParameters(); } return getParam({ parameterName: sName, loadPendingParameters: !bAsync, async: bAsync }); } }; vResult = {}; for (var i = 0; i < aNames.length; i++) { sParamName = aNames[i]; var sParamValue = lookForParameter(sParamName); if (!bAsync || sParamValue) { vResult[sParamName] = sParamValue; } } if (bAsync && fnAsyncCallback && Object.keys(vResult).length !== aNames.length) { if (!ThemeManager.themeLoaded) { resolveWithParameter = function () { ThemeManager.detachEvent("ThemeChanged", resolveWithParameter); var vParams = this.get({ // Don't pass callback again name: vName.name, scopeElement: vName.scopeElement }); if (!vParams || (typeof vParams === "object" && (Object.keys(vParams).length !== aNames.length))) { Log.error("One or more parameters could not be found.", "sap.ui.core.theming.Parameters"); } fnAsyncCallback(vParams); aCallbackRegistry.splice(aCallbackRegistry.findIndex(findRegisteredCallback), 1); }.bind(this); // Check if identical callback is already registered and reregister with current parameters iIndex = aCallbackRegistry.findIndex(findRegisteredCallback); if (iIndex >= 0) { ThemeManager.detachEvent("ThemeChanged", aCallbackRegistry[iIndex].eventHandler); aCallbackRegistry[iIndex].eventHandler = resolveWithParameter; } else { aCallbackRegistry.push({ callback: fnAsyncCallback, eventHandler: resolveWithParameter }); } ThemeManager.attachEvent("ThemeChanged", resolveWithParameter); return undefined; // Don't return partial result in case we expect themeChanged event. } else { Log.error("One or more parameters could not be found.", "sap.ui.core.theming.Parameters"); } } return aNames.length === 1 ? vResult[aNames[0]] : vResult; }; /** * * Uses the parameters provide to re-set the parameters map or * reloads them as usually. * * @param {Object} mLibraryParameters * @private */ Parameters._setOrLoadParameters = function(mLibraryParameters) { // don't use this.reset(), as it will set the variable to null mParameters = { "default": {}, "scopes": {} }; sTheme = Configuration.getTheme(); forEachStyleSheet(function(sId) { var sLibname = sId.substr(13); // length of sap-ui-theme- if (mLibraryParameters[sLibname]) { // if parameters are already provided for this lib, use them (e.g. from LessSupport) extend(mParameters["default"], mLibraryParameters[sLibname]); } else { // otherwise use inline-parameters or library-parameters.json loadParameters(sId); } }); }; /** * Resets the CSS parameters which finally will reload the parameters * the next time they are queried via the method <code>get</code>. * * @public * @deprecated since 1.92 */ Parameters.reset = function() { this._reset.apply(this, arguments); }; /** * Resets the CSS parameters which finally will reload the parameters * the next time they are queried via the method <code>get</code>. * * @private * @ui5-restricted sap.ui.core.theming */ Parameters._reset = function() { // hidden parameter {boolean} bOnlyWhenNecessary var bOnlyWhenNecessary = arguments[0] === true; if ( !bOnlyWhenNecessary || Configuration.getTheme() !== sTheme ) { sTheme = Configuration.getTheme(); aParametersToLoad = []; mParameters = null; ThemeHelper.reset(); } }; /** * Helper function to get an image URL based on a given theme parameter. * * @private * @param {string} sParamName the theme parameter which contains the logo definition. If nothing is defined the parameter 'sapUiGlobalLogo' is used. * @param {boolean} bForce whether a valid URL should be returned even if there is no logo defined. */ Parameters._getThemeImage = function(sParamName, bForce) { sParamName = sParamName || "sapUiGlobalLogo"; var logo = Parameters.get(sParamName); if (logo) { var match = rCssUrl.exec(logo); if (match) { logo = match[1]; } else if (logo === "''" || logo === "none") { logo = null; } } if (bForce && !logo) { return sap.ui.require.toUrl('sap/ui/core/themes/base/img/1x1.gif'); } return logo; }; return Parameters; }, /* bExport= */ true);