@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
211 lines (193 loc) • 7.85 kB
JavaScript
/*!
* 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/ui/base/ManagedObject", "sap/base/Log", "sap/base/assert"],
function(ManagedObject, Log, assert) {
"use strict";
const ManagedObjectRegistry = {
create(oOptions) {
/**
* Map (object) of objects keyed by their ID.
* @private
*/
const mInstances = Object.create(null);
/**
* Number of objects in <code>mInstances</code>.
* @private
*/
let iInstancesCount = 0;
oOptions ??= {};
const facade = {
init(FNClass) {
if ( typeof FNClass !== 'function' || !(FNClass.prototype instanceof ManagedObject) ) {
throw new TypeError("ManagedObjectRegistry mixin can only be applied to subclasses of sap.ui.base.ManagedObject");
}
var fnOnDuplicate = oOptions.onDuplicate || function(sId, oldInstance, newInstance) {
var sStereotype = FNClass.getMetadata().getStereotype();
Log.error("adding object \"" + sStereotype + "\" with duplicate id '" + sId + "'");
throw new Error("Error: adding object \"" + sStereotype + "\" with duplicate id '" + sId + "'");
};
var fnOnDeregister = oOptions.onDeregister || null;
FNClass.prototype.register = function register() {
var sId = this.getId(),
old = mInstances[sId];
if ( old && old !== this ) {
fnOnDuplicate(sId, old, this);
// executes only if duplicate check succeeds
iInstancesCount--;
}
mInstances[sId] = this;
iInstancesCount++;
};
FNClass.prototype.deregister = function deregister() {
var sId = this.getId();
if ( mInstances[sId] ) {
if ( fnOnDeregister ) {
fnOnDeregister(sId);
}
delete mInstances[sId];
iInstancesCount--;
}
};
delete facade.init;
Object.freeze(facade);
},
/**
* Returns the number of existing objects.
*
* @returns {int} Number of currently existing objects.
* @private
* @ui5-restricted sap.ui.core, sap.m.TablePersoController, sap.m.TablePersoDialog
*/
get size() {
return iInstancesCount;
},
/**
* Return an object with all registered object instances, keyed by their ID.
*
* Each call creates a new snapshot object. Depending on the size of the UI,
* this operation therefore might be expensive. Consider to use the <code>forEach</code>
* or <code>filter</code> method instead of executing the same operations on the returned
* object.
*
* <b>Note</b>: The returned object is created by a call to <code>Object.create(null)</code>,
* so it doesn't have a prototype and therefore no <code>toString</code> method.
*
* @returns {object} Object with all elements, keyed by their ID
* @private
* @ui5-restricted sap.ui.core, sap.m.TablePersoController, sap.m.TablePersoDialog
*/
all: function() {
var mResults = Object.create(null);
return Object.assign(mResults, mInstances);
},
/**
* Retrieves an object by its ID.
*
* @param {sap.ui.core.ID|null|undefined} ID of the object to retrieve.
* @returns {sap.ui.core.Element|undefined} Object with the given ID or <code>undefined</code>
* @private
* @ui5-restricted sap.ui.core, sap.m.TablePersoController, sap.m.TablePersoDialog
*/
get: function(id) {
assert(id == null || typeof id === "string", "id must be a string when defined");
// allow null, as this occurs frequently and it is easier to check whether there is a control in the end than
// first checking whether there is an ID and then checking for a control
return id == null ? undefined : mInstances[id];
},
/**
* Calls the given <code>callback</code> for each object.
*
* If objects are created or destroyed during the <code>forEach</code> loop, then the behavior
* is undefined. Newly added elements might or might not be visited. If an element is destroyed
* during the loop and was not visited yet, it won't be visited.
*
* <code>function callback(element, id)</code>
*
* If a <code>thisArg</code> is given, it will be provided as <code>this</code> context when calling
* <code>callback</code>. The <code>this</code> value that the implementation of <code>callback</code>
* sees, depends on the usual resolution mechanism. E.g. when <code>callback</code> was bound to some
* context object, that object wins over the given <code>thisArg</code>.
*
* @param {function(sap.ui.core.Element,sap.ui.core.ID)} callback
* Function to call for each element
* @param {Object} [thisArg=undefined]
* Context object to provide as <code>this</code> in each call of <code>callback</code>
* @throws {TypeError} If <code>callback</code> is not a function
* @private
* @ui5-restricted sap.ui.core, sap.m.TablePersoController, sap.m.TablePersoDialog
*/
forEach: function(callback, thisArg) {
if (typeof callback !== "function") {
throw new TypeError(callback + " is not a function");
}
if ( thisArg != null ) {
callback = callback.bind(thisArg);
}
for ( var id in mInstances ) {
callback(mInstances[id], id);
}
},
/**
* Collects all elements for which the given <code>callback</code> returns a value that coerces
* to <code>true</code>.
*
* If elements are created or destroyed within the <code>callback</code>, then the behavior is
* undefined. Newly added objects might or might not be visited. If an element is destroyed
* during the filtering and was not visited yet, it won't be visited.
*
* If a <code>thisArg</code> is given, it will be provided as <code>this</code> context when calling
* <code>callback</code>. The <code>this</code> value that the implementation of <code>callback</code>
* sees, depends on the usual resolution mechanism. E.g. when <code>callback</code> was bound to some
* context object, that object wins over the given <code>thisArg</code>.
*
* This function returns an array with all elements matching the given predicate. The order of the
* elements in the array is undefined and might change between calls (over time and across different
* versions of UI5).
*
* @param {function(sap.ui.core.Element,sap.ui.core.ID)} callback
* predicate against which each element is tested
* @param {Object} thisArg
* context object to provide as <code>this</code> in each call of <code>callback</code>
* @returns {sap.ui.core.Element[]}
* Array of elements matching the predicate; order is undefined and might change in newer versions of UI5
* @throws {TypeError} If <code>callback</code> is not a function
* @private
* @ui5-restricted sap.ui.core, sap.m.TablePersoController, sap.m.TablePersoDialog
*/
filter: function(callback, thisArg) {
if (typeof callback !== "function") {
throw new TypeError(callback + " is not a function");
}
if ( thisArg != null ) {
callback = callback.bind(thisArg);
}
var result = [],
id;
for ( id in mInstances ) {
if ( callback(mInstances[id], id) ) {
result.push(mInstances[id]);
}
}
return result;
}
};
return facade;
},
/**
*
* @param {sap.ui.base.ManagedObject} FNClass The class to create the registry
* @param {object} oOptions The create config options
* @private
* @deprecated
*/
apply(FNClass, oOptions) {
const registry = ManagedObjectRegistry.create(oOptions);
registry.init(FNClass);
FNClass.registry = registry;
}
};
return ManagedObjectRegistry;
});