UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

267 lines (249 loc) 9.36 kB
/* eslint-disable max-nested-callbacks */ /*! * OpenUI5 * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ sap.ui.define([ "sap/ui/core/util/reflection/JsControlTreeModifier", "sap/ui/core/Component", "sap/ui/fl/util/ManagedObjectModel" // used implicitly by oModifier.createControl() function ], function ( JsControlTreeModifier, Component ) { "use strict"; /** * Change handler for splitting sap.m.MenuButton into sap.m.Button(s). * * @alias sap.m.changeHandler.SplitMenuButton * @author SAP SE * @version 1.117.4 * @experimental Since 1.48 */ var SplitMenuButton = {}; var SOURCE_CONTROL = "sourceControl"; /** * Split a MenuButton into separate Buttons * * @param {sap.ui.fl.Change} oChange Change wrapper object with instructions to be applied on the control map * @param {sap.m.IBar} oControl Bar control that matches the change selector for applying the change * @param {object} mPropertyBag Map of properties * @param {object} mPropertyBag.modifier Modifier for the controls * @return {Promise} Promise resolving when change was applied * * @public */ SplitMenuButton.applyChange = function(oChange, oControl, mPropertyBag) { if (mPropertyBag.modifier.targets !== "jsControlTree") { return Promise.reject(new Error("Split change can't be applied on XML tree")); } var oChangeContent = oChange.getContent(); var oModifier = mPropertyBag.modifier; var oView = mPropertyBag.view; var oAppComponent = mPropertyBag.appComponent; var oSourceControl = oChange.getDependentControl(SOURCE_CONTROL, mPropertyBag); var oMenu; var aMenuItems; var sParentAggregation; var iAggregationIndex; var aNewElementSelectors; var oRevertData; var sModelName; var oManagedObjectModel; var oParent; return Promise.resolve() .then(function() { return oModifier.getAggregation(oSourceControl, "menu"); }) .then(function(oRetrievedMenu) { oMenu = oRetrievedMenu; return oModifier.getAggregation(oMenu, "items"); }) .then(function(aReturnedMenuItems) { aMenuItems = aReturnedMenuItems; oParent = oModifier.getParent(oSourceControl); return oModifier.getParentAggregationName(oSourceControl, oParent); }) .then(function(sRetrievedParentAggregation) { sParentAggregation = sRetrievedParentAggregation; return oModifier.findIndexInParentAggregation(oSourceControl); }) .then(function(iRetrievedAggregationIndex) { iAggregationIndex = iRetrievedAggregationIndex; aNewElementSelectors = oChangeContent.newElementIds; oRevertData = { parentAggregation: sParentAggregation, insertIndex: iAggregationIndex, insertedButtons: [] }; return aMenuItems.reduce(function (oPreviousPromise, oMenuItem, index) { var oSelector; var iIndex; var oButton; return oPreviousPromise .then(function() { iIndex = index; oSelector = aNewElementSelectors[iIndex]; return oModifier.createControl("sap.m.Button", oAppComponent, oView, oSelector); }) .then(function(oCreatedButton){ oButton = oCreatedButton; oRevertData.insertedButtons.push(oSelector); sModelName = "$sap.m.flexibility.SplitButtonsModel"; return oModifier.createControl( "sap.ui.fl.util.ManagedObjectModel", oAppComponent, oView, Object.assign({}, oSelector, { id: oSelector.id + '-managedObjectModel' }), { object: oMenuItem, name: sModelName } ); }) .then(function(oCreatedManagedObjectModel) { oManagedObjectModel = oCreatedManagedObjectModel; // ManagedObjectModel should be placed in `dependents` aggregation of the Button return oModifier.insertAggregation(oButton, "dependents", oManagedObjectModel, 0, oView); }) .then(function(){ oModifier.bindProperty(oButton, "text", sModelName + ">/text"); oModifier.bindProperty(oButton, "icon", sModelName + ">/icon"); oModifier.bindProperty(oButton, "enabled", sModelName + ">/enabled"); oModifier.bindProperty(oButton, "visible", sModelName + ">/visible"); return oModifier.createControl( "sap.ui.core.CustomData", oAppComponent, oView, Object.assign({}, oSelector, { id: oSelector.id + '-customData' }), { key: { path: sModelName + ">key" }, value: { path: sModelName + ">value" } } ); }) .then(function(oTemplate){ return oModifier.bindAggregation(oButton, "customData", { path: sModelName + ">/customData", template: oTemplate, templateShareable: false }); }) .then(function(){ return oModifier.attachEvent( oButton, "press", "sap.m.changeHandler.SplitMenuButton.pressHandler", { selector: oModifier.getSelector(oMenuItem, oAppComponent), appComponentId: oAppComponent.getId(), menu: oMenu } ); }) .then(function(){ return oModifier.insertAggregation(oParent, sParentAggregation, oButton, iAggregationIndex + iIndex, oView); }); }, Promise.resolve()); }) .then(function() { return Promise.resolve() .then(oModifier.removeAggregation.bind(oModifier, oParent, sParentAggregation, oSourceControl)) .then(oModifier.insertAggregation.bind(oModifier, oParent, "dependents", oSourceControl, 0, oView)) .then(function() { oChange.setRevertData(oRevertData); }); }); }; /** * Reverts applied change * * @param {sap.ui.fl.Change} oChange Change wrapper object with instructions to be applied on the control map * @param {sap.m.IBar} oControl Bar control that matches the change selector for applying the change * @param {object} mPropertyBag Map of properties * @param {object} mPropertyBag.modifier Modifier for the controls * @return {Promise} Promise resolving when change was reverted * * @public */ SplitMenuButton.revertChange = function(oChange, oControl, mPropertyBag) { var oModifier = mPropertyBag.modifier; var oRevertData = oChange.getRevertData(); var oSourceControl = oChange.getDependentControl(SOURCE_CONTROL, mPropertyBag); var oAppComponent = mPropertyBag.appComponent; var oView = mPropertyBag.view; var oParent = oModifier.getParent(oSourceControl); var sParentAggregation = oRevertData.parentAggregation; var iAggregationIndex = oRevertData.insertIndex; var aInsertedButtons = []; return Promise.resolve() .then(function() { oRevertData.insertedButtons.forEach(function(oSelector) { aInsertedButtons.push(oModifier.bySelector(oSelector, oAppComponent, oView)); }); return aInsertedButtons.reduce(function(oPreviousPromise, oButton) { return oPreviousPromise .then(function() { return oModifier.removeAggregation(oParent, sParentAggregation, oButton); }) .then(function() { return oModifier.destroy(oButton); }); }, Promise.resolve()); }) .then(oModifier.insertAggregation.bind(oModifier, oParent, sParentAggregation, oSourceControl, iAggregationIndex, oView)) .then(function() { oChange.resetRevertData(); }); }; /** * Completes the change by adding change handler specific content * * @param {sap.ui.fl.Change} oChange change wrapper object to be completed * @param {object} oSpecificChangeInfo Specific change info containing parentId * @param {object} mPropertyBag Map of properties * * @public */ SplitMenuButton.completeChangeContent = function(oChange, oSpecificChangeInfo, mPropertyBag) { var oModifier = mPropertyBag.modifier; var oAppComponent = mPropertyBag.appComponent; if (!oSpecificChangeInfo.newElementIds) { throw new Error("Split of MenuButton cannot be applied : oSpecificChangeInfo.newElementIds attribute required"); } if (!oSpecificChangeInfo.sourceControlId) { throw new Error("Split of MenuButton cannot be applied : oSpecificChangeInfo.sourceControlId attribute required"); } oChange.addDependentControl(oSpecificChangeInfo.sourceControlId, SOURCE_CONTROL, mPropertyBag); var oContent = {}; oContent.sourceSelector = oModifier.getSelector(oSpecificChangeInfo.sourceControlId, oAppComponent); oContent.newElementIds = oSpecificChangeInfo.newElementIds.map(function (sElementId) { return oModifier.getSelector(sElementId, oAppComponent); }); oChange.setContent(oContent); }; /** * Callback function which is attached via modifier in applyChange * * @param {sap.ui.base.Event} oEvent Event object * @param {object} mParameters * @param {{id: string, idIsLocal: boolean}} mParameters.selector Selector describing the target of the flexibility change * @param {sap.ui.core.ID} mParameters.appComponentId * @param {sap.ui.core.Control} mParameters.menu */ SplitMenuButton.pressHandler = function (oEvent, mParameters) { var oMenuItem = JsControlTreeModifier.bySelector(mParameters.selector, Component.get(mParameters.appComponentId)); oMenuItem.firePress(); mParameters.menu.fireItemSelected({ item: oMenuItem }); }; return SplitMenuButton; }, /* bExport= */true);