@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
366 lines (325 loc) • 14.5 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
/**
* @overview Initialization for the SAP UI Library
*
* This module creates the main SAP namespaces {@link sap} and automatically
* registers it to the OpenAjax hub if that exists.
*
* This class provides method {@link #namespace} to register namespaces to the
* SAP UI Library.
*
* @sample
* Ensures a control can be used afterwards but does not load immediately
* sap.ui.lazyRequire("sap.ui.core.Control");
* sap.ui.lazyRequire("sap.m.Button");
*
* @version 1.111.5
* @author SAP SE
* @public
*/
/*global OpenAjax */
sap.ui.define([
'sap/ui/VersionInfo',
'sap/ui/core/Configuration',
'sap/base/Log',
'sap/base/assert',
'sap/base/util/ObjectPath'
],
function(VersionInfo, Configuration, Log, assert, ObjectPath) {
"use strict";
// Register to the OpenAjax Hub if it exists
if (window.OpenAjax && window.OpenAjax.hub) {
OpenAjax.hub.registerLibrary("sap", "http://www.sap.com/", "0.1", {});
}
// soft dependency to sap/ui/base/Object
var BaseObject;
/**
* Root namespace for JavaScript functionality provided by SAP SE.
*
* The <code>sap</code> namespace is automatically registered with the
* OpenAjax hub if it exists.
*
* @version 1.111.5
* @namespace
* @public
* @name sap
*/
if ( typeof window.sap !== "object" && typeof window.sap !== "function" ) {
window.sap = {};
}
/**
* The <code>sap.ui</code> namespace is the central OpenAjax compliant entry
* point for UI related JavaScript functionality provided by SAP.
*
* @version 1.111.5
* @namespace
* @name sap.ui
* @public
*/
if ( typeof window.sap.ui !== "object") {
window.sap.ui = {};
}
sap.ui = Object.assign(sap.ui, {
/**
* The version of the SAP UI Library
* @type string
*/
version: "1.111.5",
// buildinfo.lastchange is deprecated and is therefore defaulted to empty string
buildinfo : { lastchange : "", buildtime : "${buildtime}" }
});
var syncCallBehavior = Configuration.getSyncCallBehavior();
/**
* Loads the version info file (resources/sap-ui-version.json) and returns
* it or if a library name is specified then the version info of the individual
* library will be returned.
*
* In case of the version info file is not available an error will occur when
* calling this function.
*
* @param {string|object} [mOptions] name of the library (e.g. "sap.ui.core") or an object map (see below)
* @param {boolean} [mOptions.library] name of the library (e.g. "sap.ui.core")
* @param {boolean} [mOptions.async=false] whether "sap-ui-version.json" should be loaded asynchronously
* @param {boolean} [mOptions.failOnError=true] whether to propagate load errors or not (not relevant for async loading)
* @return {object|undefined|Promise} the full version info, the library specific one,
* undefined (if library is not listed or there was an error and "failOnError" is set to "false")
* or a Promise which resolves with one of them
* @deprecated since 1.56: Use {@link module:sap/ui/VersionInfo.load} instead
* @public
* @static
*/
sap.ui.getVersionInfo = function(mOptions) {
if (mOptions && mOptions.async) {
Log.info("Do not use deprecated function 'sap.ui.getVersionInfo'. Use" +
" 'sap/ui/VersionInfo' module's asynchronous .load function instead");
} else {
Log.warning("Do not use deprecated function 'sap.ui.getVersionInfo' synchronously! Use" +
" 'sap/ui/VersionInfo' module's asynchronous .load function instead", "Deprecation", null, function() {
return {
type: "sap.ui.getVersionInfo",
name: "Global"
};
});
}
return VersionInfo._load(mOptions); // .load() is async only!
};
/**
* Ensures that a given a namespace or hierarchy of nested namespaces exists in the
* current <code>window</code>.
*
* @param {string} sNamespace
* @return {object} the innermost namespace of the hierarchy
* @public
* @static
* @deprecated As of version 1.1, see {@link topic:c78c07c094e04ccfaab659378a1707c7 Creating Control and Class Modules}.
*/
sap.ui.namespace = function(sNamespace){
assert(false, "sap.ui.namespace is long time deprecated and shouldn't be used");
return ObjectPath.create(sNamespace);
};
/**
* Creates a lazy loading stub for a given class <code>sClassName</code>.
*
* If the class has been loaded already, nothing is done. Otherwise a stub object
* or constructor and - optionally - a set of stub methods are created.
* All created stubs will load the corresponding module on execution
* and then delegate to their counterpart in the loaded module.
*
* When no methods are given or when the list of methods contains the special name
* "new" (which is an operator can't be used as method name in JavaScript), then a
* stub <b>constructor</b> for class <code>sClassName</code> is created.
* Otherwise, a plain object is created.
*
* <b>Note</b>: Accessing any stub as a plain object without executing it (no matter
* whether it is a function or an object) won't load the module and therefore most likely
* won't work as expected. This is a fundamental restriction of the lazy loader approach.
*
* <b>Note</b>: As a side effect of this method, the namespace containing the given
* class is created <b>immediately</b>.
*
* @param {string} sClassName Fully qualified name (dot notation) of the class that should be prepared
* @param {string} [sMethods='new'] Space separated list of additional (static) methods that should be created as stubs
* @param {string} [sModuleName] Name of the module to load, defaults to the class name
* @public
* @static
* @deprecated since 1.56 Lazy loading enforces synchronous requests and therefore has been deprecated
* without a replacement. Instead of loading classes via lazy stubs, they should be required as
* dependencies of an AMD module (using {@link sap.ui.define}) or on demand with a call to {@link
* sap.ui.require}.
*/
sap.ui.lazyRequire = function(sClassName, sMethods, sModuleName) {
assert(typeof sClassName === "string" && sClassName, "lazyRequire: sClassName must be a non-empty string");
assert(!sMethods || typeof sMethods === "string", "lazyRequire: sMethods must be empty or a string");
if ( syncCallBehavior === 2 ) {
Log.error("[nosync] lazy stub creation ignored for '" + sClassName + "'");
return;
}
var sFullClass = sClassName.replace(/\//gi,"\."),
iLastDotPos = sFullClass.lastIndexOf("."),
sPackage = sFullClass.substr(0, iLastDotPos),
sClass = sFullClass.substr(iLastDotPos + 1),
oPackage = ObjectPath.create(sPackage),
oClass = oPackage[sClass],
aMethods = (sMethods || "new").split(" "),
iConstructor = aMethods.indexOf("new");
sModuleName = sModuleName || sFullClass;
if (!oClass) {
if ( iConstructor >= 0 ) {
// Create dummy constructor which loads the class on demand
oClass = function() {
if ( syncCallBehavior ) {
if ( syncCallBehavior === 1 ) {
Log.error("[nosync] lazy stub for constructor '" + sFullClass + "' called");
}
} else {
Log.debug("lazy stub for constructor '" + sFullClass + "' called.");
}
sap.ui.requireSync(sModuleName.replace(/\./g, "/")); // legacy-relevant: 'sap.ui.lazyRequire' is deprecated
var oRealClass = oPackage[sClass];
assert(typeof oRealClass === "function", "lazyRequire: oRealClass must be a function after loading");
if ( oRealClass._sapUiLazyLoader ) {
throw new Error("lazyRequire: stub '" + sFullClass + "'has not been replaced by module '" + sModuleName + "'");
}
// create a new instance and invoke the constructor
var oInstance = Object.create(oRealClass.prototype);
if ( !(this instanceof oClass) ) {
// sap.ui.base.Object and its subclasses throw an error when the constructor is called as a function.
// Lazy stubs for those classes should behave consistently, but for compatibility with older
// releases (< 1.63), only a log entry can be written.
// To facilitate a support rule, the log entry provides a stack trace on demand ("support info")
BaseObject = BaseObject || sap.ui.require("sap/ui/base/Object");
if ( BaseObject && oInstance instanceof BaseObject ) {
Log.error("Constructor " + sClassName + " has been called without \"new\" operator!", null, null, function() {
try {
throw new Error();
} catch (e) {
return e;
}
});
}
}
var oResult = oRealClass.apply(oInstance, arguments);
if (oResult && (typeof oResult === "function" || typeof oResult === "object")) {
oInstance = oResult;
}
return oInstance;
};
// mark the stub as lazy loader
oClass._sapUiLazyLoader = true;
aMethods.splice(iConstructor,1);
} else {
// Create dummy object
oClass = {};
}
// remember the stub
oPackage[sClass] = oClass;
}
// add stub methods to it
aMethods.forEach( function(sMethod) {
// check whether method is already available
if (!oClass[sMethod]) {
oClass[sMethod] = function() {
if ( syncCallBehavior ) {
if ( syncCallBehavior === 1 ) {
Log.error("[no-sync] lazy stub for method '" + sFullClass + "." + sMethod + "' called");
}
} else {
Log.debug("lazy stub for method '" + sFullClass + "." + sMethod + "' called.");
}
sap.ui.requireSync(sModuleName.replace(/\./g, "/")); // legacy-relevant: 'sap.ui.lazyRequire' is deprecated
var oRealClass = oPackage[sClass];
assert(typeof oRealClass === "function" || typeof oRealClass === "object", "lazyRequire: oRealClass must be a function or object after loading");
assert(typeof oRealClass[sMethod] === "function", "lazyRequire: method must be a function");
if (oRealClass[sMethod]._sapUiLazyLoader ) {
throw new Error("lazyRequire: stub '" + sFullClass + "." + sMethod + "' has not been replaced by loaded module '" + sModuleName + "'");
}
return oRealClass[sMethod].apply(oRealClass, arguments);
};
oClass[sMethod]._sapUiLazyLoader = true;
}
});
};
/**
* Note: this method only works when sClassName has been stubbed itself, not when
* it has been stubbed as a static utility class with individual stubs for its methods.
* (e.g. might not work for 'sap.ui.core.BusyIndicator').
* Must not be used outside the core, e.g. not by controls, apps, tests etc.
* @private
* @deprecated since 1.56
*/
sap.ui.lazyRequire._isStub = function(sClassName) {
assert(typeof sClassName === "string" && sClassName, "lazyRequire._isStub: sClassName must be a non-empty string");
var iLastDotPos = sClassName.lastIndexOf("."),
sContext = sClassName.slice(0, iLastDotPos),
sProperty = sClassName.slice(iLastDotPos + 1),
oContext = ObjectPath.get(sContext || "");
return !!(oContext && typeof oContext[sProperty] === "function" && oContext[sProperty]._sapUiLazyLoader);
};
/**
* Returns the URL of a resource that belongs to the given library and has the given relative location within the library.
* This is mainly meant for static resources like images that are inside the library.
* It is NOT meant for access to JavaScript modules or anything for which a different URL has been registered with
* sap.ui.loader.config({paths:...}). For these cases use sap.ui.require.toUrl().
* It DOES work, however, when the given sResourcePath starts with "themes/" (= when it is a theme-dependent resource). Even when for this theme a different
* location outside the normal library location is configured.
*
* @param {string} sLibraryName the name of a library, like "sap.ui.layout"
* @param {string} sResourcePath the relative path of a resource inside this library, like "img/mypic.png" or "themes/my_theme/img/mypic.png"
* @returns {string} the URL of the requested resource
*
* @static
* @public
* @deprecated since 1.56.0, use <code>sap.ui.require.toUrl</code> instead.
*/
sap.ui.resource = function(sLibraryName, sResourcePath) {
assert(typeof sLibraryName === "string", "sLibraryName must be a string");
assert(typeof sResourcePath === "string", "sResourcePath must be a string");
return sap.ui.require.toUrl((String(sLibraryName).replace(/\./g, "/") + '/' + sResourcePath).replace(/^\/*/, ""));
};
/**
* Redirects access to resources that are part of the given namespace to a location
* relative to the assumed <b>application root folder</b>.
*
* Any UI5 managed resource (view, controller, control, JavaScript module, CSS file, etc.)
* whose resource name starts with <code>sNamespace</code>, will be loaded from an
* equally named subfolder of the <b>application root folder</b>.
* If the resource name consists of multiple segments (separated by a dot), each segment
* is assumed to represent an individual folder. In other words: when a resource name is
* converted to a URL, any dots ('.') are converted to slashes ('/').
*
* <b>Note:</b> The <b>application root folder</b> is assumed to be the same as the folder
* where the current page resides in.
*
* Usage sample:
* <pre>
* // Let UI5 know that resources, whose name starts with "com.mycompany.myapp"
* // should be loaded from the URL location "./com/mycompany/myapp"
* sap.ui.localResources("com.mycompany.myapp");
*
* // The following call implicitly will use the mapping done by the previous line
* // It will load a view from ./com/mycompany/myapp/views/Main.view.xml
* View.create({ viewName : "com.mycompany.myapp.views.Main", type : ViewType.XML}).then(function(oView) {
* // do stuff
* });
* </pre>
*
* When applications need a more flexible mapping between resource names and their location,
* they can use {@link sap.ui.loader.config} with option <code>paths</code>.
*
* @param {string} sNamespace Namespace prefix for which to load resources relative to the application root folder
* @public
* @static
* @deprecated since 1.56, use <code>sap.ui.loader.config</code> instead.
*/
sap.ui.localResources = function(sNamespace) {
assert(sNamespace, "sNamespace must not be empty");
var mPaths = {};
mPaths[sNamespace.replace(/\./g, "/")] = "./" + sNamespace.replace(/\./g, "/");
sap.ui.loader.config({paths:mPaths});
};
return sap.ui;
});