UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

1,349 lines (1,230 loc) 84.5 kB
/*! * OpenUI5 * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ //Provides class sap.ui.core.Configuration sap.ui.define([ '../Device', '../Global', '../base/Object', './CalendarType', './Locale', 'sap/ui/thirdparty/URI', "sap/base/util/UriParameters", "sap/base/util/deepEqual", "sap/base/util/Version", "sap/base/Log", "sap/base/assert", "sap/base/util/extend", "sap/base/util/isEmptyObject" ], function( Device, Global, BaseObject, CalendarType, Locale, URI, UriParameters, deepEqual, Version, Log, assert, extend, isEmptyObject ) { "use strict"; // lazy dependencies. Can't be declared as this would result in cyclic dependencies var LocaleData; /** * Creates a new Configuration object. * * @class Collects and stores the configuration of the current environment. * * The Configuration is initialized once when the {@link sap.ui.core.Core} is created. * There are different ways to set the environment configuration (in ascending priority): * <ol> * <li>System defined defaults</li> * <li>Server wide defaults, read from /sap-ui-config.json</li> * <li>Properties of the global configuration object window["sap-ui-config"]</li> * <li>A configuration string in the data-sap-ui-config attribute of the bootstrap tag.</li> * <li>Individual data-sap-ui-<i>xyz</i> attributes of the bootstrap tag</li> * <li>Using URL parameters</li> * <li>Setters in this Configuration object (only for some parameters)</li> * </ol> * * That is, attributes of the DOM reference override the system defaults, URL parameters * override the DOM attributes (where empty URL parameters set the parameter back to its * system default). Calling setters at runtime will override any previous settings * calculated during object creation. * * The naming convention for parameters is: * <ul> * <li>in the URL : sap-ui-<i>PARAMETER-NAME</i>="value"</li> * <li>in the DOM : data-sap-ui-<i>PARAMETER-NAME</i>="value"</li> * </ul> * where <i>PARAMETER-NAME</i> is the name of the parameter in lower case. * * Values of boolean parameters are case insensitive where "true" and "x" are interpreted as true. * * @extends sap.ui.base.Object * @author Frank Weigel (Martin Schaus) * @public * @alias sap.ui.core.Configuration */ var Configuration = BaseObject.extend("sap.ui.core.Configuration", /** @lends sap.ui.core.Configuration.prototype */ { constructor : function(oCore) { this._oCore = oCore; function detectLanguage() { function navigatorLanguage() { if ( Device.os.android ) { // on Android, navigator.language is hardcoded to 'en', so check UserAgent string instead var match = navigator.userAgent.match(/\s([a-z]{2}-[a-z]{2})[;)]/i); if ( match ) { return match[1]; } // okay, we couldn't find a language setting. It might be better to fallback to 'en' instead of having no language } return navigator.language; } return convertToLocaleOrNull( (navigator.languages && navigator.languages[0]) || navigatorLanguage() || navigator.userLanguage || navigator.browserLanguage ) || new Locale("en"); } // Definition of supported settings // Valid property types are: string, boolean, string[], code, object, function. // Objects as an enumeration list of valid values can also be provided (e.g. Configuration.AnimationMode). var M_SETTINGS = { "theme" : { type : "string", defaultValue : "base" }, "language" : { type : "Locale", defaultValue : detectLanguage() }, "formatLocale" : { type : "Locale", defaultValue : null }, "calendarType" : { type : "string", defaultValue : null }, "trailingCurrencyCode" : { type : "boolean", defaultValue : true }, // "timezone" : "UTC", "accessibility" : { type : "boolean", defaultValue : true }, "autoAriaBodyRole" : { type : "boolean", defaultValue : false, noUrl:true }, //whether the framework automatically adds automatically the ARIA role 'application' to the html body "animation" : { type : "boolean", defaultValue : true }, // deprecated, please use animationMode "animationMode" : { type : Configuration.AnimationMode, defaultValue : undefined }, // If no value is provided, animationMode will be set on instantiation depending on the animation setting. "rtl" : { type : "boolean", defaultValue : null }, "debug" : { type : "boolean", defaultValue : false }, "inspect" : { type : "boolean", defaultValue : false }, "originInfo" : { type : "boolean", defaultValue : false }, "noConflict" : { type : "boolean", defaultValue : false, noUrl:true }, "noDuplicateIds" : { type : "boolean", defaultValue : true }, "trace" : { type : "boolean", defaultValue : false, noUrl:true }, "modules" : { type : "string[]", defaultValue : [], noUrl:true }, "areas" : { type : "string[]", defaultValue : null, noUrl:true }, // "libs" : { type : "string[]", defaultValue : [], noUrl:true }, handled below "onInit" : { type : "code", defaultValue : undefined, noUrl:true }, // could be either a reference to a JavaScript function, the name of a global function (string value) or the name of a module (indicated with prefix "module:") "uidPrefix" : { type : "string", defaultValue : "__", noUrl:true }, "ignoreUrlParams" : { type : "boolean", defaultValue : false, noUrl:true }, "preload" : { type : "string", defaultValue : "auto" }, "rootComponent" : { type : "string", defaultValue : "", noUrl:true }, "preloadLibCss" : { type : "string[]", defaultValue : [] }, "application" : { type : "string", defaultValue : "" }, "appCacheBuster" : { type : "string[]", defaultValue : [] }, "bindingSyntax" : { type : "string", defaultValue : "default", noUrl:true }, // default|simple|complex "versionedLibCss" : { type : "boolean", defaultValue : false }, "manifestFirst" : { type : "boolean", defaultValue : false }, "flexibilityServices" : { type : "string", defaultValue : "/sap/bc/lrep"}, "whitelistService" : { type : "string", defaultValue : null, noUrl: true }, // deprecated, use allowlistService instead "allowlistService" : { type : "string", defaultValue : null, noUrl: true }, // url/to/service "frameOptions" : { type : "string", defaultValue : "default", noUrl: true }, // default/allow/deny/trusted (default => allow) "frameOptionsConfig" : { type : "object", defaultValue : undefined, noUrl:true }, // advanced frame options configuration "support" : { type : "string[]", defaultValue : null }, "testRecorder" : { type : "string[]", defaultValue : null }, "activeTerminologies" : { type : "string[]", defaultValue: undefined}, "xx-rootComponentNode" : { type : "string", defaultValue : "", noUrl:true }, "xx-appCacheBusterMode" : { type : "string", defaultValue : "sync" }, "xx-appCacheBusterHooks": { type : "object", defaultValue : undefined, noUrl:true }, // e.g.: { handleURL: fn, onIndexLoad: fn, onIndexLoaded: fn } "xx-disableCustomizing" : { type : "boolean", defaultValue : false, noUrl:true }, "xx-viewCache" : { type : "boolean", defaultValue : true }, "xx-test-mobile" : { type : "boolean", defaultValue : false }, "xx-depCache" : { type : "boolean", defaultValue : false }, "xx-libraryPreloadFiles": { type : "string[]", defaultValue : [] }, "xx-componentPreload" : { type : "string", defaultValue : "" }, "xx-designMode" : { type : "boolean", defaultValue : false }, "xx-supportedLanguages" : { type : "string[]", defaultValue : [] }, // *=any, sapui5 or list of locales "xx-bootTask" : { type : "function", defaultValue : undefined, noUrl:true }, "xx-suppressDeactivationOfControllerCode" : { type : "boolean", defaultValue : false }, //temporarily to suppress the deactivation of controller code in design mode "xx-lesssupport" : { type : "boolean", defaultValue : false }, "xx-handleValidation" : { type : "boolean", defaultValue : false }, "xx-fiori2Adaptation" : { type : "string[]", defaultValue : [] }, "xx-cache-use" : { type : "boolean", defaultValue : true}, "xx-cache-excludedKeys" : { type : "string[]", defaultValue : []}, "xx-cache-serialization": { type : "boolean", defaultValue : false}, "xx-nosync" : { type : "string", defaultValue : "" }, "xx-waitForTheme" : { type : "string", defaultValue : ""}, // rendering|init "xx-hyphenation" : { type : "string", defaultValue : ""}, // (empty string)|native|thirdparty|disable "xx-flexBundleRequestForced" : { type : "boolean", defaultValue : false }, "xx-cssVariables" : { type : "string", defaultValue : "false" }, // false|true|additional (additional just includes the css_variables.css in addition) "statistics" : { type : "boolean", defaultValue : false } }; var M_COMPAT_FEATURES = { "xx-test" : "1.15", //for testing purposes only "flexBoxPolyfill" : "1.14", "sapMeTabContainer" : "1.14", "sapMeProgessIndicator" : "1.14", "sapMGrowingList" : "1.14", "sapMListAsTable" : "1.14", "sapMDialogWithPadding" : "1.14", "sapCoreBindingSyntax" : "1.24" }; this.oFormatSettings = new Configuration.FormatSettings(this); /* Object that carries the real configuration data */ /*eslint-disable consistent-this */ var config = this; /*eslint-enable consistent-this */ function setValue(sName, sValue) { if ( typeof sValue === "undefined" || sValue === null ) { return; } switch (M_SETTINGS[sName].type) { case "boolean": if ( typeof sValue === "string" ) { if (M_SETTINGS[sName].defaultValue) { config[sName] = sValue.toLowerCase() != "false"; } else { config[sName] = sValue.toLowerCase() === "true" || sValue.toLowerCase() === "x"; } } else { // boolean etc. config[sName] = !!sValue; } break; case "string": config[sName] = "" + sValue; // enforce string break; case "code": config[sName] = typeof sValue === "function" ? sValue : String(sValue); break; case "function": if ( typeof sValue !== "function" ) { throw new Error("unsupported value"); } config[sName] = sValue; break; case "string[]": if ( Array.isArray(sValue) ) { config[sName] = sValue; } else if ( typeof sValue === "string" ) { config[sName] = sValue.split(/[ ,;]/).map(function(s) { return s.trim(); }); } else { throw new Error("unsupported value"); } break; case "object": if ( typeof sValue !== "object" ) { throw new Error("unsupported value"); } config[sName] = sValue; break; case "Locale": var oLocale = convertToLocaleOrNull(sValue); if ( oLocale || M_SETTINGS[sName].defaultValue == null ) { config[sName] = oLocale; } else { throw new Error("unsupported value"); } break; default: // When the type is none of the above types, check if an object as enum is provided to validate the value. var vType = M_SETTINGS[sName].type; if (typeof vType === "object") { checkEnum(vType, sValue, sName); config[sName] = sValue; } else { throw new Error("illegal state"); } } } function getMetaTagValue(sName) { var oMetaTag = document.querySelector("META[name='" + sName + "']"), sMetaContent = oMetaTag && oMetaTag.getAttribute("content"); if (sMetaContent) { return sMetaContent; } } function validateThemeOrigin(sOrigin) { var sAllowedOrigins = getMetaTagValue("sap-allowedThemeOrigins"); return !!sAllowedOrigins && sAllowedOrigins.split(",").some(function(sAllowedOrigin) { return sAllowedOrigin === "*" || sOrigin === sAllowedOrigin.trim(); }); } function validateThemeRoot(sThemeRoot) { var oThemeRoot, sPath; try { // Remove search query as they are not supported for themeRoots/resourceRoots oThemeRoot = new URI(sThemeRoot).search(""); // If the URL is absolute, validate the origin var sOrigin = oThemeRoot.origin(); if (sOrigin && validateThemeOrigin(sOrigin)) { sPath = oThemeRoot.toString(); } else { // For relative URLs or not allowed origins // ensure same origin and resolve relative paths based on href sPath = oThemeRoot.absoluteTo(window.location.href).origin(window.location.origin).normalize().toString(); } return sPath + (sPath.endsWith('/') ? '' : '/') + "UI5/"; } catch (e) { // malformed URL are also not accepted } } // collect the defaults for ( var n in M_SETTINGS ) { config[n] = M_SETTINGS[n].defaultValue; } // apply settings from global config object (already merged with script tag attributes) var oCfg = window["sap-ui-config"] || {}; oCfg.oninit = oCfg.oninit || oCfg["evt-oninit"]; for (var n in M_SETTINGS) { if ( oCfg.hasOwnProperty(n.toLowerCase()) ) { setValue(n, oCfg[n.toLowerCase()]); } else if ( !/^xx-/.test(n) && oCfg.hasOwnProperty("xx-" + n.toLowerCase()) ) { setValue(n, oCfg["xx-" + n.toLowerCase()]); } } // if libs are configured, convert them to modules and prepend them to the existing modules list if ( oCfg.libs ) { config.modules = oCfg.libs.split(",").map(function(lib) { return lib.trim() + ".library"; }).concat(config.modules); } var PARAM_CVERS = "compatversion"; var DEFAULT_CVERS = oCfg[PARAM_CVERS]; var BASE_CVERS = Version("1.14"); this._compatversion = {}; function _getCVers(key){ var v = !key ? DEFAULT_CVERS || BASE_CVERS.toString() : oCfg[PARAM_CVERS + "-" + key.toLowerCase()] || DEFAULT_CVERS || M_COMPAT_FEATURES[key] || BASE_CVERS.toString(); v = Version(v.toLowerCase() === "edge" ? Global.version : v); //Only major and minor version are relevant return Version(v.getMajor(), v.getMinor()); } this._compatversion._default = _getCVers(); for (var n in M_COMPAT_FEATURES) { this._compatversion[n] = _getCVers(n); } // apply the settings from the url (only if not blocked by app configuration) if ( !config.ignoreUrlParams ) { var sUrlPrefix = "sap-ui-"; var oUriParams = UriParameters.fromQuery(window.location.search); // first map SAP parameters, can be overwritten by "sap-ui-*" parameters if ( oUriParams.has('sap-language') ) { // always remember as SAP Logon language var sValue = config.sapLogonLanguage = oUriParams.get('sap-language'); // try to interpret it as a BCP47 language tag, taking some well known SAP language codes into account var oLocale = Locale.fromSAPLogonLanguage(sValue); if ( oLocale ) { config.language = oLocale; } else if ( sValue && !oUriParams.get('sap-locale') && !oUriParams.get('sap-ui-language')) { // only complain about an invalid sap-language if neither sap-locale nor sap-ui-language are given Log.warning("sap-language '" + sValue + "' is not a valid BCP47 language tag and will only be used as SAP logon language"); } } // Check sap-locale after sap-language to ensure compatibility if both parameters are provided (e.g. portal iView). if ( oUriParams.has('sap-locale') ) { setValue("language", oUriParams.get('sap-locale')); } if (oUriParams.has('sap-rtl')) { // "" = false, "X", "x" = true var sValue = oUriParams.get('sap-rtl'); if (sValue === "X" || sValue === "x") { setValue('rtl', true); } else { setValue('rtl', false); } } if (oUriParams.has('sap-theme')) { var sValue = oUriParams.get('sap-theme'); if (sValue === "") { // empty URL parameters set the parameter back to its system default config['theme'] = M_SETTINGS['theme'].defaultValue; } else { setValue('theme', sValue); } } if (oUriParams.has('sap-statistics')) { var sValue = oUriParams.get('sap-statistics'); setValue('statistics', sValue); } // now analyze sap-ui parameters for (var n in M_SETTINGS) { if ( M_SETTINGS[n].noUrl ) { continue; } var sValue = oUriParams.get(sUrlPrefix + n); if ( sValue == null && !/^xx-/.test(n) ) { sValue = oUriParams.get(sUrlPrefix + "xx-" + n); } if (sValue === "") { //empty URL parameters set the parameter back to its system default config[n] = M_SETTINGS[n].defaultValue; } else { //sets the value (null or empty value ignored) setValue(n, sValue); } } // handle legacy URL params through format settings if (oUriParams.has('sap-ui-legacy-date-format')) { this.oFormatSettings.setLegacyDateFormat(oUriParams.get('sap-ui-legacy-date-format')); } if (oUriParams.has('sap-ui-legacy-time-format')) { this.oFormatSettings.setLegacyTimeFormat(oUriParams.get('sap-ui-legacy-time-format')); } if (oUriParams.has('sap-ui-legacy-number-format')) { this.oFormatSettings.setLegacyNumberFormat(oUriParams.get('sap-ui-legacy-number-format')); } } // map of SAP parameters (allows general access) config.sapparams = config.sapparams || {}; // set the SAP logon language to the SAP params config.sapparams['sap-language'] = this.getSAPLogonLanguage(); // read the SAP parameters from URL or META tag ['sap-client', 'sap-server', 'sap-system'].forEach(function(sName) { if (!config.ignoreUrlParams && oUriParams.get(sName)) { config.sapparams[sName] = oUriParams.get(sName); } else { config.sapparams[sName] = getMetaTagValue(sName); } }); // calculate RTL mode this.derivedRTL = Locale._impliesRTL(config.language); // analyze theme parameter var sTheme = config.theme; var sThemeRoot; var iIndex = sTheme.indexOf("@"); if (iIndex >= 0) { sThemeRoot = validateThemeRoot(sTheme.slice(iIndex + 1)); if ( sThemeRoot ) { config.theme = sTheme.slice(0, iIndex); config.themeRoot = sThemeRoot; } else { // fallback to non-URL parameter (if not equal to sTheme) config.theme = (oCfg.theme && oCfg.theme !== sTheme) ? oCfg.theme : "base"; iIndex = -1; // enable theme mapping below } } config.theme = this._normalizeTheme(config.theme, sThemeRoot); var aCoreLangs = config['languagesDeliveredWithCore'] = Locale._coreI18nLocales; var aLangs = config['xx-supportedLanguages']; if ( aLangs.length === 0 || (aLangs.length === 1 && aLangs[0] === '*') ) { aLangs = []; } else if ( aLangs.length === 1 && aLangs[0] === 'default' ) { aLangs = aCoreLangs || []; } config['xx-supportedLanguages'] = aLangs; //parse fiori 2 adaptation parameters var vAdaptations = config['xx-fiori2Adaptation']; if ( vAdaptations.length === 0 || (vAdaptations.length === 1 && vAdaptations[0] === 'false') ) { vAdaptations = false; } else if ( vAdaptations.length === 1 && vAdaptations[0] === 'true' ) { vAdaptations = true; } config['xx-fiori2Adaptation'] = vAdaptations; // determine default for binding syntax if ( config["bindingSyntax"] === "default" ) { config["bindingSyntax"] = (config.getCompatibilityVersion("sapCoreBindingSyntax").compareTo("1.26") < 0) ? "simple" : "complex"; } config["allowlistService"] = config["allowlistService"] || /* fallback to legacy config */ config["whitelistService"]; // Configure allowlistService / frameOptions via <meta> tag if not already defined via UI5 configuration if (!config["allowlistService"]) { var sAllowlistMetaTagValue = getMetaTagValue('sap.allowlistService') || /* fallback to legacy config */ getMetaTagValue('sap.whitelistService'); if (sAllowlistMetaTagValue) { config["allowlistService"] = sAllowlistMetaTagValue; // Set default "frameOptions" to "trusted" instead of "allow" if (config["frameOptions"] === "default") { config["frameOptions"] = "trusted"; } } } // Verify and set default for "frameOptions" configuration if (config["frameOptions"] === "default" || (config["frameOptions"] !== "allow" && config["frameOptions"] !== "deny" && config["frameOptions"] !== "trusted")) { // default => allow config["frameOptions"] = "allow"; } // frameOptionsConfig: Handle compatibility of renamed config option var oFrameOptionsConfig = config["frameOptionsConfig"]; if (oFrameOptionsConfig) { oFrameOptionsConfig.allowlist = oFrameOptionsConfig.allowlist || oFrameOptionsConfig.whitelist; } // in case the flexibilityServices configuration was set to a non-empty, non-default value, sap.ui.fl becomes mandatory if (config.flexibilityServices && config.flexibilityServices !== M_SETTINGS.flexibilityServices.defaultValue && config.modules.indexOf("sap.ui.fl.library") == -1) { config.modules.push("sap.ui.fl.library"); } var aCSSLibs = config['preloadLibCss']; if ( aCSSLibs.length > 0 ) { // a leading "!" denotes that the application has loaded the file already aCSSLibs.appManaged = aCSSLibs[0].slice(0,1) === "!"; if ( aCSSLibs.appManaged ) { aCSSLibs[0] = aCSSLibs[0].slice(1); // also affect same array in "config"! } if ( aCSSLibs[0] === "*" ) { // replace with configured libs aCSSLibs.shift(); // remove * (inplace) config.modules.forEach(function(mod) { var m = mod.match(/^(.*)\.library$/); if ( m ) { aCSSLibs.unshift(m[1]); } }); } } // default legacy boolean to new enum value // TODO: remove when making the configuration non-experimental if ( config["xx-waitForTheme"] === "true" ) { config["xx-waitForTheme"] = "rendering"; } if ( config["xx-waitForTheme"] !== "rendering" && config["xx-waitForTheme"] !== "init" ) { // invalid value or false from legacy boolean setting config["xx-waitForTheme"] = undefined; } // log all non default value for (var n in M_SETTINGS) { if ( config[n] !== M_SETTINGS[n].defaultValue ) { Log.info(" " + n + " = " + config[n]); } } // Setup animation mode. If no animation mode is provided // the value is set depending on the animation setting. if (this.getAnimationMode() === undefined) { if (this.animation) { this.setAnimationMode(Configuration.AnimationMode.full); } else { this.setAnimationMode(Configuration.AnimationMode.minimal); } } else { // Validate and set the provided value for the animation mode this.setAnimationMode(this.getAnimationMode()); } // disable the css variables in case of IE11 if (Device.browser.msie && config["xx-cssVariables"] !== "false") { config["xx-cssVariables"] = "false"; Log.warning("The option xx-cssVariables is not supported on Microsoft Internet Explorer!"); } }, /** * Returns the version of the framework. * * Similar to <code>sap.ui.version</code>. * * @return {module:sap/base/util/Version} the version * @public */ getVersion : function () { if (this._version) { return this._version; } this._version = new Version(Global.version); return this._version; }, /** * Returns the used compatibility version for the given feature. * * @param {string} sFeature the key of desired feature * @return {module:sap/base/util/Version} the used compatibility version * @public */ getCompatibilityVersion : function (sFeature) { if (typeof (sFeature) === "string" && this._compatversion[sFeature]) { return this._compatversion[sFeature]; } return this._compatversion._default; }, /** * Returns the theme name * @return {string} the theme name * @public */ getTheme : function () { return this.theme; }, /** * Allows setting the theme name * @param {string} sTheme the theme name * @return {this} <code>this</code> to allow method chaining * @private */ _setTheme : function (sTheme) { this.theme = sTheme; return this; }, /** * Normalize the given theme, resolve known aliases * @private */ _normalizeTheme : function (sTheme, sThemeBaseUrl) { if ( sTheme && sThemeBaseUrl == null && sTheme.match(/^sap_corbu$/i) ) { return "sap_fiori_3"; } return sTheme; }, /** * Returns a string that identifies the current language. * * The value returned by this methods in most cases corresponds to the exact value that has been * configured by the user or application or that has been determined from the user agent settings. * It has not been normalized, but has been validated against a relaxed version of * {@link http://www.ietf.org/rfc/bcp/bcp47.txt BCP47}, allowing underscores ('_') instead of the * suggested dashes ('-') and not taking the case of letters into account. * * The exceptions mentioned above affect languages that have been specified via the URL parameter * <code>sap-language</code>. That parameter by definition represents an SAP logon language code * ('ABAP language'). Most but not all of these language codes are valid ISO639 two-letter languages * and as such are valid BCP47 language tags. For better BCP47 compliance, the framework * maps the following non-BCP47 SAP logon codes to a BCP47 substitute: * <pre> * "ZH" --> "zh-Hans" // script 'Hans' added to distinguish it from zh-Hant * "ZF" --> "zh-Hant" // ZF is not a valid ISO639 code, use the compliant language + script 'Hant' * "1Q" --> "en-US-x-saptrc" // special language code for supportability (tracing), * represented as en-US with a private extension * "2Q" --> "en-US-x-sappsd" // special language code for supportability (pseudo translation), * represented as en-US with a private extension * "3Q" --> "en-US-x-saprigi" // special language code for the Rigi pseudo language, * represented as en-US with a private extension * </pre> * * For a normalized BCP47 tag, call {@link #getLanguageTag} or call {@link #getLocale} to get a * {@link sap.ui.core.Locale Locale} object matching the language. * * @return {string} Language string as configured * @public */ getLanguage : function () { return this.language.sLocaleId; }, /** * Returns a BCP47-compliant language tag for the current language. * * The return value of this method is especially useful for an HTTP <code>Accept-Language</code> header. * * Retrieves the modern locale, * e.g. he (Hebrew), yi (Yiddish) * * For backward compatibility "sh" is returned for Serbian Latin. * * @returns {string} The language tag for the current language, conforming to BCP47 * @public */ getLanguageTag : function () { return this.language.toLanguageTag(); }, /** * Returns an SAP logon language for the current language. * * @return {string} The SAP logon language code for the current language * @public */ getSAPLogonLanguage : function () { return this.sapLogonLanguage || this.language.getSAPLogonLanguage(); }, /** * Sets a new language to be used from now on for language/region dependent * functionality (e.g. formatting, data types, translated texts, ...). * * When the language can't be interpreted as a BCP47 language (using the relaxed syntax * described in {@link #getLanguage}, an error will be thrown. * * When the language has changed, the Core will fire its * {@link sap.ui.core.Core#event:localizationChanged localizationChanged} event. * * * <h3>Restrictions</h3> * * The framework <strong>does not</strong> guarantee that already created, language * dependent objects will be updated by this call. It therefore remains best practice * for applications to switch the language early, e.g. before any language dependent * objects are created. Applications that need to support more dynamic changes of * the language should listen to the <code>localizationChanged</code> event and adapt * all language dependent objects that they use (e.g. by rebuilding their UI). * * Currently, the framework notifies the following objects about a change of the * localization settings before it fires the <code>localizationChanged</code> event: * * <ul> * <li>date and number data types that are used in property bindings or composite * bindings in existing Elements, Controls, UIAreas or Components</li> * <li>ResourceModels currently assigned to the Core, a UIArea, Component, * Element or Control</li> * <li>Elements or Controls that implement the <code>onlocalizationChanged</code> hook * (note the lowercase 'l' in onlocalizationChanged)</li> * </ul> * * It furthermore derives the RTL mode from the new language, if no explicit RTL * mode has been set. If the RTL mode changes, the following additional actions will be taken: * * <ul> * <li>the URLs of already loaded library theme files will be changed</li> * <li>the <code>dir</code> attribute of the page will be changed to reflect the new mode.</li> * <li>all UIAreas will be invalidated (which results in a rendering of the whole UI5 UI)</li> * </ul> * * This method does not accept SAP language codes for <code>sLanguage</code>. Instead, a second * parameter <code>sSAPLogonLanguage</code> can be provided with an SAP language code corresponding * to the given language. A given value will be returned by the {@link #getSAPLogonLanguage} method. * It is up to the caller to provide a consistent pair of BCP47 language and SAP language code. * The SAP language code is only checked to be of length 2 and must consist of letters or digits only. * * <b>Note</b>: When using this method please take note of and respect the above mentioned restrictions. * * @param {string} sLanguage the new language as a BCP47 compliant language tag; case doesn't matter * and underscores can be used instead of dashes to separate components (compatibility with Java Locale IDs) * @param {string} [sSAPLogonLanguage] SAP language code that corresponds to the <code>sLanguage</code>; * if a value is specified, future calls to <code>getSAPLogonLanguage</code> will return that value; * if no value is specified, the framework will use the ISO639 language part of <code>sLanguage</code> * as SAP Logon language. * @throws {Error} When <code>sLanguage</code> can't be interpreted as a BCP47 language or when * <code>sSAPLanguage</code> is given and can't be interpreted as SAP language code. * @return {this} <code>this</code> to allow method chaining * * @see http://scn.sap.com/docs/DOC-14377 * @public */ setLanguage : function (sLanguage, sSAPLogonLanguage) { var oLocale = convertToLocaleOrNull(sLanguage), bOldRTL = this.getRTL(), mChanges; check(oLocale, "Configuration.setLanguage: sLanguage must be a valid BCP47 language tag"); check(sSAPLogonLanguage == null || (typeof sSAPLogonLanguage === 'string' && /[A-Z0-9]{2,2}/i.test(sSAPLogonLanguage)), "Configuration.setLanguage: sSAPLogonLanguage must be null or be a string of length 2, consisting of digits and latin characters only", /* warn= */ true); if ( oLocale.toString() != this.getLanguageTag() || sSAPLogonLanguage !== this.sapLogonLanguage ) { this.language = oLocale; this.sapLogonLanguage = sSAPLogonLanguage || undefined; this.sapparams['sap-language'] = this.getSAPLogonLanguage(); mChanges = this._collect(); mChanges.language = this.getLanguageTag(); this.derivedRTL = Locale._impliesRTL(oLocale); if ( bOldRTL != this.getRTL() ) { mChanges.rtl = this.getRTL(); } this._endCollect(); } return this; }, /** * Returns a Locale object for the current language. * * The Locale is derived from the {@link #getLanguage language} property. * * @return {sap.ui.core.Locale} The locale * @public */ getLocale : function () { return this.language; }, /** * Returns an SAP parameter by it's name (e.g. sap-client, sap-system, sap-server). * * @experimental * @since 1.45.0 * @param {string} sName The parameter name * @return {string} The SAP parameter value */ getSAPParam : function (sName) { return this.sapparams && this.sapparams[sName]; }, /** * Checks whether the Cache Manager is switched on. * @experimental * @since 1.37.0 * @returns {boolean} */ isUI5CacheOn: function () { return this["xx-cache-use"]; }, /** * Enables/Disables the Cache configuration. * @experimental * @since 1.37.0 * @param {boolean} on true to switch it on, false if to switch it off * @returns {this} */ setUI5CacheOn: function (on) { this["xx-cache-use"] = on; return this; }, /** * Checks whether the Cache Manager serialization support is switched on. * @experimental * @since 1.37.0 * @returns {boolean} */ isUI5CacheSerializationSupportOn: function () { return this["xx-cache-serialization"]; }, /** * Enables/Disables the Cache serialization support * @experimental * @since 1.37.0 * @param {boolean} on true to switch it on, false if to switch it off * @returns {this} */ setUI5CacheSerializationSupport: function (on) { this["xx-cache-serialization"] = on; return this; }, /** * Returns all keys, that the CacheManager will ignore when set/get values. * @experimental * @since 1.37.0 * @returns {string[]} array of keys that CacheManager should ignore * @see sap.ui.core.cache.LRUPersistentCache#keyMatchesExclusionStrings */ getUI5CacheExcludedKeys: function () { return this["xx-cache-excludedKeys"]; }, /** * Returns the calendar type which is being used in locale dependent functionality. * * When it's explicitly set by calling <code>setCalendar</code>, the set calendar type is returned. * Otherwise, the calendar type is determined by checking the format settings and current locale. * * @return {sap.ui.core.CalendarType} the current calendar type * @since 1.28.6 */ getCalendarType : function() { var sName; // lazy load of LocaleData to avoid cyclic dependencies if ( !LocaleData ) { LocaleData = sap.ui.requireSync("sap/ui/core/LocaleData"); } if (this.calendarType) { for (sName in CalendarType) { if (sName.toLowerCase() === this.calendarType.toLowerCase()) { this.calendarType = sName; return this.calendarType; } } Log.warning("Parameter 'calendarType' is set to " + this.calendarType + " which isn't a valid value and therefore ignored. The calendar type is determined from format setting and current locale"); } var sLegacyDateFormat = this.oFormatSettings.getLegacyDateFormat(); switch (sLegacyDateFormat) { case "1": case "2": case "3": case "4": case "5": case "6": return CalendarType.Gregorian; case "7": case "8": case "9": return CalendarType.Japanese; case "A": case "B": return CalendarType.Islamic; case "C": return CalendarType.Persian; } return LocaleData.getInstance(this.getLocale()).getPreferredCalendarType(); }, /** * Sets the new calendar type to be used from now on in locale dependent functionality (for example, * formatting, translation texts, etc.). * * @param {sap.ui.core.CalendarType|null} sCalendarType the new calendar type. Set it with null to clear the calendar type * and the calendar type is calculated based on the format settings and current locale. * @return {this} <code>this</code> to allow method chaining * @public * @since 1.28.6 */ setCalendarType : function(sCalendarType) { var mChanges; if (this.calendarType !== sCalendarType) { mChanges = this._collect(); this.calendarType = mChanges.calendarType = sCalendarType; this._endCollect(); } return this; }, /** * Returns the format locale string with language and region code. Falls back to * language configuration, in case it has not been explicitly defined. * * @return {string} the format locale string with language and country code * @public */ getFormatLocale : function () { return (this.formatLocale || this.language).toString(); }, /** * Sets a new format locale to be used from now on for retrieving locale * specific formatters. Modifying this setting does not have an impact on * the retrieval of translated texts! * * Can either be set to a concrete value (a BCP47 or Java locale compliant * language tag) or to <code>null</code>. When set to <code>null</code> (default * value) then locale specific formatters are retrieved for the current language. * * After changing the format locale, the framework tries to update localization * specific parts of the UI. See the documentation of {@link #setLanguage} for * details and restrictions. * * <b>Note</b>: When a format locale is set, it has higher priority than a number, * date or time format defined with a call to <code>setLegacyNumberFormat</code>, * <code>setLegacyDateFormat</code> or <code>setLegacyTimeFormat</code>. * * <b>Note</b>: See documentation of {@link #setLanguage} for restrictions. * * @param {string|null} sFormatLocale the new format locale as a BCP47 compliant language tag; * case doesn't matter and underscores can be used instead of dashes to separate * components (compatibility with Java Locale IDs) * @return {this} <code>this</code> to allow method chaining * @public * @throws {Error} When <code>sFormatLocale</code> is given, but is not a valid BCP47 language * tag or Java locale identifier */ setFormatLocale : function(sFormatLocale) { var oFormatLocale = convertToLocaleOrNull(sFormatLocale), mChanges; check(sFormatLocale == null || typeof sFormatLocale === "string" && oFormatLocale, "sFormatLocale must be a BCP47 language tag or Java Locale id or null"); if ( toLanguageTag(oFormatLocale) !== toLanguageTag(this.formatLocale) ) { this.formatLocale = oFormatLocale; mChanges = this._collect(); mChanges.formatLocale = toLanguageTag(oFormatLocale); this._endCollect(); } return this; }, /** * List of languages that the SAPUI5 core delivers. * * Might return undefined if the information is not available. * * @experimental */ getLanguagesDeliveredWithCore : function() { return this["languagesDeliveredWithCore"]; }, /** * @experimental */ getSupportedLanguages : function() { return this["xx-supportedLanguages"]; }, /** * Returns whether the accessibility mode is used or not. * @return {boolean} whether the accessibility mode is used or not * @public */ getAccessibility : function () { return this.accessibility; }, /** * Returns whether the framework automatically adds automatically * the ARIA role 'application' to the HTML body or not. * @return {boolean} * @since 1.27.0 * @public */ getAutoAriaBodyRole : function () { return this.autoAriaBodyRole; }, /** * Returns whether the animations are globally used. * @return {boolean} whether the animations are globally used * @public * @deprecated As of version 1.50.0, replaced by {@link sap.ui.core.Configuration#getAnimationMode} */ getAnimation : function () { return this.animation; }, /** * Returns the current animation mode. * * @return {sap.ui.core.Configuration.AnimationMode} The current animationMode * @since 1.50.0 * @public */ getAnimationMode : function () { return this.animationMode; }, /** * Sets the current animation mode. * * Expects an animation mode as string and validates it. If a wrong animation mode was set, an error is * thrown. If the mode is valid it is set, then the attributes <code>data-sap-ui-animation</code> and * <code>data-sap-ui-animation-mode</code> of the HTML document root element are also updated. * If the <code>animationMode</code> is <code>Configuration.AnimationMode.none</code> the old * <code>animation</code> property is set to <code>false</code>, otherwise it is set to <code>true</code>. * * @param {sap.ui.core.Configuration.AnimationMode} sAnimationMode A valid animation mode * @throws {Error} If the provided <code>sAnimationMode</code> does not exist, an error is thrown * @since 1.50.0 * @public */ setAnimationMode : function(sAnimationMode) { checkEnum(Configuration.AnimationMode, sAnimationMode, "animationMode"); // Set the animation to on or off depending on the animation mode to ensure backward compatibility. this.animation = (sAnimationMode !== Configuration.AnimationMode.minimal && sAnimationMode !== Configuration.AnimationMode.none); // Set the animation mode and update html attributes. this.animationMode = sAnimationMode; if (this._oCore && this._oCore._setupAnimation) { this._oCore._setupAnimation(); } }, /** * Returns whether the page uses the RTL text direction. * * If no mode has been explicitly set (neither <code>true</code> nor <code>false</code>), * the mode is derived from the current language setting. * * @return {boolean} whether the page uses the RTL text direction * @public */ getRTL : function () { // if rtl has not been set (still null), return the rtl mode derived from the language return this.rtl === null ? this.derivedRTL : this.rtl; }, /** * Returns whether the Fiori2Adaptation is on. * @return {boolean|string} false - no adaptation, true - full adaptation, comma-separated list - partial adaptation * Possible values: style, collapse, title, back, hierarchy * @public */ getFiori2Adaptation : function () { return this["xx-fiori2Adaptation"]; }, /** * Sets the character orientation mode to be used from now on. * * Can either be set to a concrete value (true meaning right-to-left, * false meaning left-to-right) or to <code>null</code> which means that * the character orientation mode should be derived from the current * language (incl. region) setting. * * After changing the character orientation mode, the framework tries * to update localization specific parts of the UI. See the documentation of * {@link #setLanguage} for details and restrictions. * * <b>Note</b>: See documentation of {@link #setLanguage} for restrictions. * * @param {boolean|null} bRTL new character orientation mode or <code>null</code> * @return {this} <code>this</code> to allow method chaining * @public */ setRTL : function(bRTL) { check(bRTL === null || typeof bRTL === "boolean", "bRTL must be null or a boolean"); var oldRTL = this.getRTL(), mChanges; this.rtl = bRTL; if ( oldRTL != this.getRTL() ) { // also take the derived RTL flag into account for the before/after comparison! mChanges = this._collect(); mChanges.rtl = this.getRTL(); this._endCollect(); } return this; }, /** * Returns whether the page runs in debug mode. * @return {boolean} whether the page runs in debug mode * @public */ getDebug : function () { return this.debug; }, /** * Returns whether the UI5 control inspector is displayed. * Has only an effect when the sap-ui-debug module has been loaded * @return {boolean} whether the UI5 control inspector is displayed * @public */ getInspect : function () { return this.inspect; }, /** * Returns whether the text origin information is collected. * @return {boolean} whether the text info is collected * @public */ getOriginInfo : function () { return this.originInfo; }, /** * Returns whether there should be an exception on any duplicate element IDs. * @return {boolean} whether there should be an exception on any duplicate element IDs * @public */ getNoDuplicateIds : function () { return this.noDuplicateIds; }, /** * Whether a trace view should be shown or not. * * Has only an effect when the sap-ui-debug module has been loaded * either by explicitly loading it or by setting the 'debug' option to true. * @return {boolean} whether a trace view should be shown */ getTrace : function () { return this.trace; }, /** * Prefix to be used for automatically generated control IDs. * Default is a double underscore "__". * * @returns {string} the prefix to be used * @public */ getUIDPrefix : function() { return this.uidPrefix; }, /** * Return whether the design mode is active or not. * * @returns {boolean} whether the design mode is active or not. * @since 1.13.2 * @private * @ui5-restricted sap.watt, com.sap.webide */ getDesignMode : function() { return this["xx-designMode"]; }, /** * Return whether the activation of the controller code is suppressed. * * @returns {boolean} whether the activation of the controller code is suppressed or not * @since 1.13.2 * @private * @ui5-restricted sap.watt, com.sap.webide */ getSuppressDeactivationOfControllerCode : function() { return this["xx-suppressDeactivationOfControllerCode"]; }, /** * Return whether the controller code is deactivated. During design mode the. * * @returns {boolean} whether the activation of the controller code is suppressed or not * @since 1.26.4 * @private * @ui5-restricted sap.watt, com.sap.webide */ getControllerCodeDeactivated : function() { return this.getDesignMode() && !this.getSuppressDeactivationOfControllerCode(); }, /** * The name of the application to start or empty. * * @returns {string} name of the application * @public * @deprecated Since 1.15.1. Please use the rootComponent configuration option {@link sap.ui.core.Configuration#getRootComponent}. */ getApplication : function() { return this.application; }, /** * The name of the root component to start or empty. * * @returns {string} name of the root component * @public * @experimental Since 1.15.1 */ getRootComponent : function() { return this.rootComponent; }, /** * Base URLs to AppCacheBuster ETag-Index files. * * @returns {string[]} array of base URLs * @public */ getAppCacheBuster : function() { return this.appCacheBuster; }, /** * The loading mode (sync|async|batch) of the AppCacheBuster (sync is default) * * @returns {string} "sync" | "async" * @public */ getAppCacheBusterMode : function() { return this["xx-appCacheBusterMode"]; }, /** * Object defining the callback hooks for the AppCacheBuster like e.g. * <code>handleURL</code>, <code>onIndexLoad</code> or <code>onIndexLoaded</code>. * * @returns {object} object containing the callback functions for the AppCacheBuster * @private * @ui5-restricted */ getAppCacheBusterHooks : function() { return this["xx-appCacheBusterHooks"]; }, /** * Flag, whether the customizing is disabled or not. * * @returns {boolean} true if customizing is disabled * @private * @ui5-restricted */ getDisableCustomizing : function() { return this["xx-disableCustomizing"]; }, /** * Flag, representing the status of the view cache. * @see {sap.ui.xmlview} * * @returns {boolean} true if view cache is enabled * @private * @experimental Since 1.44 */ getViewCache : function() { return this["xx-viewCache"]; }, /** * Currently active preload mode for libraries or falsy value. * * @returns {string} preload mode * @private * @since 1.16.3 */ getPreload : function() { return this.preload; }, /** * Whether dependency cache info files should be loaded instead of preload files. * * This is an experimental feature intended for HTTP/2 scenarios. * @private */ getDepCache : function() { return this["xx-depCache"]; }, /** * Flag whether a Component should load the manifest first. * * @returns {boolean} true if a Component should load the manifest first * @public * @since 1.33.0 */ getManifestFirst : function() { return this.manifestFirst; }, /** * Returns the URL from where the UI5 flexibility services are called; * if empty, the flexibility services are not called. * * @returns {string} URL from where the flexibility services are requested * @public * @since 1.60.0 */ getFlexibilityServices : function() { if (!this.flexibilityServices) { this.flexibilityServices = []; } if (typeof this.flexibilityServices === 'string') { if (this.flexibilityServices[0] === "/") { this.flexibilityServices = [{ url : this.flexibilityServices, layers : ["ALL"], connector : "LrepConnector" }]; } else { this.flexibilityServices = JSON.parse(this.flexibilityServices)