UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

739 lines (635 loc) 26.2 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ sap.ui.define([ "sap/base/i18n/Formatting", "sap/base/i18n/Localization", "sap/ui/VersionInfo", "sap/ui/core/AnimationMode", "sap/ui/core/Configuration", "sap/ui/core/ControlBehavior", "sap/ui/core/Core", "sap/ui/core/Element", "sap/ui/core/ElementMetadata", "sap/ui/core/Lib", "sap/ui/core/Locale", "sap/ui/core/Supportability", "sap/ui/core/Theming", "sap/base/util/LoaderExtensions", "sap/ui/thirdparty/jquery" ], function( Formatting, Localization, VersionInfo, AnimationMode, Configuration, ControlBehavior, Core, Element, ElementMetadata, Lib, Locale, Supportability, Theming, LoaderExtensions, jQuery ) { 'use strict'; // ================================================================================ // Technical Information // ================================================================================ /** * Creates an object with the libraries and their version from the version info file. * @returns {Object} * @private */ function _getLibraries() { var libraries = VersionInfo._content ? VersionInfo._content.libraries : undefined; var formattedLibraries = Object.create(null); if (libraries !== undefined) { libraries.forEach(function (element, index, array) { formattedLibraries[element.name] = element.version; }); } return formattedLibraries; } /** * Creates an object with the loaded libraries and their version. * @returns {Object} * @private */ function _getLoadedLibraries() { var libraries = Lib.all(); var formattedLibraries = Object.create(null); Object.keys(Lib.all()).forEach(function (element, index, array) { formattedLibraries[element] = libraries[element].version; }); return formattedLibraries; } /** * Creates a simple object with all URL parameters. * @returns {Object<string,string[]>} Map of parameter value arrays keyed by parameter names */ function getURLParameters() { var oParams = new URLSearchParams(window.location.search); return Array.from(oParams.keys()).reduce(function(oResult, sKey) { oResult[sKey] = oParams.getAll(sKey); return oResult; }, {}); } /** * Gets all the relevant information for the framework. * @returns {Object} * @private */ function _getFrameworkInformation() { return { commonInformation: { version: Core.version, buildTime: Core.buildinfo.buildtime, lastChange: Core.buildinfo.lastchange, jquery: jQuery.fn.jquery, userAgent: navigator.userAgent, applicationHREF: window.location.href, documentTitle: document.title, documentMode: document.documentMode || '', debugMode: Supportability.isDebugModeEnabled(), statistics: Supportability.isStatisticsEnabled() }, configurationBootstrap: window['sap-ui-config'] || Object.create(null), configurationComputed: { theme: Theming.getTheme(), language: Localization.getLanguage(), formatLocale: new Locale(Formatting.getLanguageTag()), accessibility: ControlBehavior.isAccessibilityEnabled(), animation: (ControlBehavior.getAnimationMode() !== AnimationMode.minimal && ControlBehavior.getAnimationMode() !== AnimationMode.none), rtl: Localization.getRTL(), debug: Supportability.isDebugModeEnabled(), inspect: Supportability.isControlInspectorEnabled(), originInfo: Supportability.collectOriginInfo(), /** * @deprecated */ noDuplicateIds: Configuration.getNoDuplicateIds() }, libraries: _getLibraries(), loadedLibraries: _getLoadedLibraries(), loadedModules: LoaderExtensions.getAllRequiredModules().sort(), URLParameters: getURLParameters() }; } // ================================================================================ // Control tree Information // ================================================================================ /** * Represents a node in the UI5 rendered control tree structure. * * @typedef {object} sap.ui.core.support.ToolsAPI.ControlTreeNode * @property {string} id - The control's unique identifier * @property {string} name - The fully qualified control class name (e.g., "sap.m.Button") or "sap-ui-area" for UI areas * @property {string} type - Node type: "sap-ui-control" for controls, "data-sap-ui" for UI areas * @property {Array<sap.ui.core.support.ToolsAPI.ControlTreeNode>} content - Child nodes (recursive) * @property {Object<string, *>} [data] - Optional key-value map of control properties/associations * @private */ /** * Name space for all methods related to control trees */ var controlTree = { /** * Creates data model of the rendered controls as a tree. * @param {Element} nodeElement - HTML DOM element from which the function will star searching. * @param {Array} resultArray - Array that will contains all the information. * @param {Object} [oOptions] - Optional settings for enriching tree nodes. * @param {boolean} [oOptions.includeAssignedProperties] - Whether to include assigned properties in each node. * @param {boolean} [oOptions.includeAssignedAssociations] - Whether to include assigned associations in each node. * @param {boolean} [oOptions.includeTooltipText] - Whether to include tooltip text in each node. * @private */ _createRenderedTreeModel: function (nodeElement, resultArray, oOptions) { var node = nodeElement; var childNode = node.firstElementChild; var results = resultArray; var subResult = results; var related = node.getAttribute('data-sap-ui-related'); var id = related ? related : node.id; var control = Element.getElementById(id); if ((node.getAttribute('data-sap-ui') || node.getAttribute('data-sap-ui-related')) && control) { var oControlNode = { id: control.getId(), name: control.getMetadata().getName(), type: 'sap-ui-control', content: [] }; // Enrich node with data if options are provided var oData = this._getControlData(control, oOptions); if (Object.keys(oData).length > 0) { oControlNode.data = oData; } results.push(oControlNode); subResult = results[results.length - 1].content; } else if (node.getAttribute('data-sap-ui-area')) { results.push({ id: node.id, name: 'sap-ui-area', type: 'data-sap-ui', content: [] }); subResult = results[results.length - 1].content; } while (childNode) { this._createRenderedTreeModel(childNode, subResult, oOptions); childNode = childNode.nextElementSibling; } }, /** * Retrieves runtime data for a control based on the provided options. * @param {sap.ui.core.Element} oControl - The UI5 control. * @param {Object} [oOptions] - Optional settings. * @param {boolean} [oOptions.includeAssignedProperties] - Whether to include assigned properties. * @param {boolean} [oOptions.includeAssignedAssociations] - Whether to include assigned associations. * @param {boolean} [oOptions.includeTooltipText] - Whether to include tooltip text. * @returns {Object} An object containing the requested data. * @private */ _getControlData: function (oControl, oOptions) { var oData = {}; if (!oOptions || !oControl) { return oData; } if (oOptions.includeAssignedProperties && oControl.mProperties) { Object.assign(oData, _filterEmptyValues(oControl.mProperties)); } if (oOptions.includeAssignedAssociations && oControl.mAssociations) { Object.assign(oData, _filterEmptyValues(oControl.mAssociations)); } if (oOptions.includeTooltipText && typeof oControl.getTooltip_Text === 'function') { var sTooltipText = (oControl.getTooltip_Text() || "").trim(); if (sTooltipText) { oData.tooltip = sTooltipText; } } return oData; } }; function _filterEmptyValues(oMap) { return Object.fromEntries( Object.entries(oMap).filter(function(aEntry) { var vValue = aEntry[1]; var bIsEmptyString = vValue === ""; var bIsEmptyArray = Array.isArray(vValue) && vValue.length === 0; return !bIsEmptyString && !bIsEmptyArray; }) ); } // ================================================================================ // Control Information // ================================================================================ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.ControlInfoMeta * @property {string} controlName - Fully qualified class name of the control that defines this group * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.PropertyInfo * @property {*} value - Current runtime value of the property * @property {string} type - Data type name (e.g. "string", "boolean") * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.PropertyInfoContainer * @property {sap.ui.core.support.ToolsAPI.ControlInfoMeta} meta * @property {Object.<string, sap.ui.core.support.ToolsAPI.PropertyInfo>} properties - Map of property name to property info * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.AggregationInfo * @property {string} type - Fully qualified class name of the aggregated objects (e.g. "sap.ui.core.Control") * @property {number} count - Number of items currently in the aggregation (1 for non-multiple aggregations) * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.AggregationInfoContainer * @property {sap.ui.core.support.ToolsAPI.ControlInfoMeta} meta * @property {Object.<string, sap.ui.core.support.ToolsAPI.AggregationInfo>} aggregations - Map of aggregation name to aggregation info * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.AssociationInfo * @property {string} type - Fully qualified class name of the associated objects (e.g. "sap.ui.core.Control") * @property {string|string[]|object|null} value - Current association value: an ID string, array of ID strings, an object, or null when unset * @private */ /** * @typedef {Object} sap.ui.core.support.ToolsAPI.AssociationInfoContainer * @property {sap.ui.core.support.ToolsAPI.ControlInfoMeta} meta * @property {Object.<string, sap.ui.core.support.ToolsAPI.AssociationInfo>} associations - Map of association name to association info * @private */ /** * Name space for all information relevant for UI5 control */ var controlInformation = { // Control Properties Info // ================================================================================ /** * Creates an object with the control properties that are not inherited. * @param {Object} control - UI5 control. * @returns {sap.ui.core.support.ToolsAPI.PropertyInfoContainer} * @private */ _getOwnProperties: function (control) { var result = Object.create(null); var controlPropertiesFromMetadata = control.getMetadata().getProperties(); result.meta = Object.create(null); result.meta.controlName = control.getMetadata().getName(); result.properties = Object.create(null); Object.keys(controlPropertiesFromMetadata).forEach(function (key) { result.properties[key] = Object.create(null); result.properties[key].value = control.getProperty(key); result.properties[key].type = controlPropertiesFromMetadata[key].getType().getName ? controlPropertiesFromMetadata[key].getType().getName() : ''; }); return result; }, /** * Copies the inherited properties of a UI5 control from the metadata. * @param {Object} control - UI5 Control. * @param {Object} inheritedMetadata - UI5 control metadata. * @returns {sap.ui.core.support.ToolsAPI.PropertyInfoContainer} * @private */ _copyInheritedProperties: function (control, inheritedMetadata) { var inheritedMetadataProperties = inheritedMetadata.getProperties(); var result = Object.create(null); result.meta = Object.create(null); result.meta.controlName = inheritedMetadata.getName(); result.properties = Object.create(null); Object.keys(inheritedMetadataProperties).forEach(function (key) { result.properties[key] = Object.create(null); result.properties[key].value = inheritedMetadataProperties[key].get(control); result.properties[key].type = inheritedMetadataProperties[key].getType().getName ? inheritedMetadataProperties[key].getType().getName() : ''; }); return result; }, /** * Creates an array with the control properties that are inherited. * @param {Object} control - UI5 control. * @returns {Array<sap.ui.core.support.ToolsAPI.PropertyInfoContainer>} * @private */ _getInheritedProperties: function (control) { var result = []; var inheritedMetadata = control.getMetadata().getParent(); while (inheritedMetadata instanceof ElementMetadata) { result.push(this._copyInheritedProperties(control, inheritedMetadata)); inheritedMetadata = inheritedMetadata.getParent(); } return result; }, /** * Creates an object with all control properties. * @param {string} controlId * @returns {{ own: sap.ui.core.support.ToolsAPI.PropertyInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.PropertyInfoContainer> }} * @private */ _getProperties: function (controlId) { var control = Element.getElementById(controlId); var properties = Object.create(null); if (control) { properties.own = this._getOwnProperties(control); properties.inherited = this._getInheritedProperties(control); } return properties; }, // Control Aggregations Info // ================================================================================ /** * Creates an object with the control aggregations that are not inherited. * @param {Object} oControl - UI5 control. * @returns {sap.ui.core.support.ToolsAPI.AggregationInfoContainer} * @private */ _getOwnAggregations: function (oControl) { var oResult = Object.create(null); var mAggregations = oControl.getMetadata().getAggregations(); oResult.meta = Object.create(null); oResult.meta.controlName = oControl.getMetadata().getName(); oResult.aggregations = Object.create(null); Object.keys(mAggregations).forEach(function (sKey) { var oAggregation = mAggregations[sKey]; var vItems = oControl[oAggregation._sGetter](); oResult.aggregations[sKey] = Object.create(null); oResult.aggregations[sKey].type = oAggregation.type; oResult.aggregations[sKey].count = oAggregation.multiple ? vItems.length : 1; }); return oResult; }, /** * Copies the inherited aggregations of a UI5 control from the metadata. * @param {Object} oControl - UI5 control. * @param {Object} oInheritedMetadata - UI5 control metadata. * @returns {sap.ui.core.support.ToolsAPI.AggregationInfoContainer} * @private */ _copyInheritedAggregations: function (oControl, oInheritedMetadata) { var mAggregations = oInheritedMetadata.getAggregations(); var oResult = Object.create(null); oResult.meta = Object.create(null); oResult.meta.controlName = oInheritedMetadata.getName(); oResult.aggregations = Object.create(null); Object.keys(mAggregations).forEach(function (sKey) { var oAggregation = mAggregations[sKey]; var vItems = oControl[oAggregation._sGetter](); oResult.aggregations[sKey] = Object.create(null); oResult.aggregations[sKey].type = oAggregation.type; oResult.aggregations[sKey].count = oAggregation.multiple ? vItems.length : 1; }); return oResult; }, /** * Creates an array with the control aggregations that are inherited. * @param {Object} oControl - UI5 control. * @returns {Array<sap.ui.core.support.ToolsAPI.AggregationInfoContainer>} * @private */ _getInheritedAggregations: function (oControl) { var aResult = []; var oInheritedMetadata = oControl.getMetadata().getParent(); while (oInheritedMetadata instanceof ElementMetadata) { aResult.push(this._copyInheritedAggregations(oControl, oInheritedMetadata)); oInheritedMetadata = oInheritedMetadata.getParent(); } return aResult; }, /** * Creates an object with all control aggregations. * @param {string} sControlId * @returns {{ own: sap.ui.core.support.ToolsAPI.AggregationInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.AggregationInfoContainer> }} * @private */ _getAggregations: function (sControlId) { var oControl = Element.getElementById(sControlId); var oAggregations = Object.create(null); if (oControl) { oAggregations.own = this._getOwnAggregations(oControl); oAggregations.inherited = this._getInheritedAggregations(oControl); } return oAggregations; }, // Control Associations Info // ================================================================================ /** * Creates an object with the control associations that are not inherited. * @param {Object} oControl - UI5 control. * @returns {sap.ui.core.support.ToolsAPI.AssociationInfoContainer} * @private */ _getOwnAssociations: function (oControl) { var oResult = Object.create(null); var mAssociations = oControl.getMetadata().getAssociations(); oResult.meta = Object.create(null); oResult.meta.controlName = oControl.getMetadata().getName(); oResult.associations = Object.create(null); Object.keys(mAssociations).forEach(function (sKey) { var oAssociation = mAssociations[sKey]; oResult.associations[sKey] = Object.create(null); oResult.associations[sKey].type = oAssociation.type; oResult.associations[sKey].value = oControl[oAssociation._sGetter](); }); return oResult; }, /** * Copies the inherited associations of a UI5 control from the metadata. * @param {Object} oControl - UI5 control. * @param {Object} oInheritedMetadata - UI5 control metadata. * @returns {sap.ui.core.support.ToolsAPI.AssociationInfoContainer} * @private */ _copyInheritedAssociations: function (oControl, oInheritedMetadata) { var mAssociations = oInheritedMetadata.getAssociations(); var oResult = Object.create(null); oResult.meta = Object.create(null); oResult.meta.controlName = oInheritedMetadata.getName(); oResult.associations = Object.create(null); Object.keys(mAssociations).forEach(function (sKey) { var oAssociation = mAssociations[sKey]; oResult.associations[sKey] = Object.create(null); oResult.associations[sKey].type = oAssociation.type; oResult.associations[sKey].value = oControl[oAssociation._sGetter](); }); return oResult; }, /** * Creates an array with the control associations that are inherited. * @param {Object} oControl - UI5 control. * @returns {Array<sap.ui.core.support.ToolsAPI.AssociationInfoContainer>} * @private */ _getInheritedAssociations: function (oControl) { var aResult = []; var oInheritedMetadata = oControl.getMetadata().getParent(); while (oInheritedMetadata instanceof ElementMetadata) { aResult.push(this._copyInheritedAssociations(oControl, oInheritedMetadata)); oInheritedMetadata = oInheritedMetadata.getParent(); } return aResult; }, /** * Creates an object with all control associations. * @param {string} sControlId * @returns {{ own: sap.ui.core.support.ToolsAPI.AssociationInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.AssociationInfoContainer> }} * @private */ _getAssociations: function (sControlId) { var oControl = Element.getElementById(sControlId); var oAssociations = Object.create(null); if (oControl) { oAssociations.own = this._getOwnAssociations(oControl); oAssociations.inherited = this._getInheritedAssociations(oControl); } return oAssociations; }, // Binding Info // ================================================================================ /** * Creates an object with the context model of a UI5 control. * @param {Object} control * @param {string} controlProperty * @returns {Object} * @private */ _getModelFromContext: function (control, controlProperty) { var bindingContext = control.getBinding(controlProperty); var bindingContextModel = bindingContext.getModel(); var bindingInfoParts = (control.getBindingInfo(controlProperty).parts) ? control.getBindingInfo(controlProperty).parts : []; var modelNames = []; for (var i = 0; i < bindingInfoParts.length; i++) { modelNames.push(bindingInfoParts[i].model); } var model = { names: modelNames, path: bindingContext.getPath() }; if (bindingContextModel) { model.mode = bindingContextModel.getDefaultBindingMode(); model.type = bindingContextModel.getMetadata().getName(); model.data = bindingContextModel.getData ? bindingContextModel.getData('/') : undefined; } return model; }, /** * Creates an object with the properties bindings of a UI5 control. * @param {Object} control * @returns {Object} * @private */ _getBindDataForProperties: function (control) { var properties = control.getMetadata().getAllProperties(); var propertiesBindingData = Object.create(null); for (var key in properties) { if (properties.hasOwnProperty(key) && control.getBinding(key)) { propertiesBindingData[key] = Object.create(null); propertiesBindingData[key].path = control.getBinding(key).getPath(); propertiesBindingData[key].value = control.getBinding(key).getValue(); propertiesBindingData[key].type = control.getMetadata().getProperty(key).getType().getName ? control.getMetadata().getProperty(key).getType().getName() : ''; propertiesBindingData[key].mode = control.getBinding(key).getBindingMode(); propertiesBindingData[key].model = this._getModelFromContext(control, key); } } return propertiesBindingData; }, /** * Creates an object with the agregations bindings of a UI5 control. * @param {Object} control * @returns {Object} * @private */ _getBindDataForAggregations: function (control) { var aggregations = control.getMetadata().getAllAggregations(); var aggregationsBindingData = Object.create(null); for (var key in aggregations) { if (aggregations.hasOwnProperty(key) && control.getBinding(key)) { aggregationsBindingData[key] = Object.create(null); aggregationsBindingData[key].model = this._getModelFromContext(control, key); } } return aggregationsBindingData; } }; // ================================================================================ // Public API // ================================================================================ /** * Global object that provide common information for all support tools * @type {{getFrameworkInformation: Function, getRenderedControlTree: Function, getControlProperties: Function, getControlBindingInformation: Function}} */ return { /** * Common information about the framework * @returns {*} */ getFrameworkInformation: _getFrameworkInformation, /** * Array model of the rendered control as a tree. * * @param {Object} [oOptions] - Optional settings for enriching tree nodes. * @param {boolean} [oOptions.includeAssignedProperties] - Whether to include assigned properties in each node's data. * @param {boolean} [oOptions.includeAssignedAssociations] - Whether to include assigned associations in each node's data. * @param {boolean} [oOptions.includeTooltipText] - Whether to include tooltip text in each node's data. * @returns {Array<sap.ui.core.support.ToolsAPI.ControlTreeNode>} Array of root control tree nodes */ getRenderedControlTree: function (oOptions) { oOptions = oOptions || {}; var renderedControlTreeModel = []; controlTree._createRenderedTreeModel(document.body, renderedControlTreeModel, oOptions); return renderedControlTreeModel; }, /** * Gets all control properties. * @param {string} controlId * @returns {{ own: sap.ui.core.support.ToolsAPI.PropertyInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.PropertyInfoContainer> }} */ getControlProperties: function (controlId) { return controlInformation._getProperties(controlId); }, /** * Gets control binding information. * @param {string} controlId * @returns {Object} */ getControlBindings: function (controlId) { var result = Object.create(null); var control = Element.getElementById(controlId); var bindingContext; if (!control) { return result; } bindingContext = control.getBindingContext(); result.meta = Object.create(null); result.contextPath = bindingContext ? bindingContext.getPath() : null; result.aggregations = controlInformation._getBindDataForAggregations(control); result.properties = controlInformation._getBindDataForProperties(control); return result; }, /** * Gets all control aggregations. * @param {string} controlId - The ID of the control. * @returns {{ own: sap.ui.core.support.ToolsAPI.AggregationInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.AggregationInfoContainer> }} */ getControlAggregations: function (controlId) { return controlInformation._getAggregations(controlId); }, /** * Gets all control associations. * @param {string} controlId - The ID of the control. * @returns {{ own: sap.ui.core.support.ToolsAPI.AssociationInfoContainer, inherited: Array<sap.ui.core.support.ToolsAPI.AssociationInfoContainer> }} */ getControlAssociations: function (controlId) { return controlInformation._getAssociations(controlId); } }; });