UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

492 lines (425 loc) 14.7 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ /** * SemanticPage base classes * * @namespace * @name sap.m.semantic * */ // Provides class sap.m.semantic.ShareMenu sap.ui.define([ 'sap/ui/base/Object', 'sap/ui/base/ManagedObjectObserver', 'sap/m/library', "sap/ui/core/Lib", 'sap/ui/core/library', 'sap/m/Button', 'sap/m/OverflowToolbarLayoutData', 'sap/ui/core/IconPool', 'sap/m/OverflowToolbarButton', "sap/base/Log" ], function(BaseObject, ManagedObjectObserver, library, Library, coreLibrary, Button, OverflowToolbarLayoutData, IconPool, OverflowToolbarButton, Log) { "use strict"; // shortcut for sap.m.OverflowToolbarPriority var OverflowToolbarPriority = library.OverflowToolbarPriority; // shortcut for sap.ui.core.aria.HasPopup var AriaHasPopup = coreLibrary.aria.HasPopup; /** * Constructor for an sap.m.semantic.ShareMenu. * * @class * Encapsulates the functionality of a ShareMenu control. * ShareMenu is a special menu that is represented by (1) an actionSheet with the menu items and (2) a button that opens the actionSheet. * If the menu has only one item, then that item appears in place of the button that opens the actionSheet. * * @version 1.146.0 * @private * @since 1.30.0 * @alias sap.m.semantic.ShareMenu */ var ShareMenu = BaseObject.extend("sap.m.semantic.ShareMenu", { constructor : function(oActionSheet) { if (!oActionSheet) { Log.error("missing argumment: constructor expects an actionsheet reference", this); return; } this._oActionSheet = oActionSheet; this._oContentObserver = new ManagedObjectObserver(this._updateShareBtnVisibility.bind(this)); this._setMode(ShareMenu._Mode.initial); }, getInterface: function() { return this; // no facade } }); /* * static member */ ShareMenu._Mode = { /** * In "inital" mode, the menu is empty and hidden; */ initial: "initial", /** * In "button" mode, the menu consists of a single button, that represents the only menu-item */ button: "button", /** * In "actionSheet" mode, the menu consists of (1) an actionSheet containing all of the menu items and (2) a dedicated button that only opens the actionSheet. */ actionSheet: "actionSheet" }; /** * Getter for the shareMenu button * The functionality of this button depends on the ShareMenu mode: * (1) In actionSheet mode, it opens the menu * (2) In "button" mode (i.e. when the menu has a single menu-item) it represents the only menu-item * * @returns {sap.m.Button} the base button */ ShareMenu.prototype.getBaseButton = function () { return this._oBaseButton; }; ShareMenu.prototype.getAggregation = function (sName) { if (sName === "content") { return this.getContent(); } }; ShareMenu.prototype.addAggregation = function (sName, oButton, bSuppressInvalidate) { if (sName === "content") { return this.addContent(oButton, bSuppressInvalidate); } }; ShareMenu.prototype.insertAggregation = function (sName, oButton, iIndex, bSuppressInvalidate) { if (sName === "content") { return this.insertContent(oButton, iIndex, bSuppressInvalidate); } }; ShareMenu.prototype.indexOfAggregation = function (sName, oButton) { if (sName === "content") { return this.indexOfContent(oButton); } }; ShareMenu.prototype.removeAggregation = function (sName, oButton, bSuppressInvalidate) { if (sName === "content") { return this.removeContent(oButton, bSuppressInvalidate); } }; ShareMenu.prototype.removeAllAggregation = function (sName, bSuppressInvalidate) { if (sName === "content") { return this.removeAllContent(bSuppressInvalidate); } }; /** * Getter for the items of this menu * * @returns {Array} an array of controls that comprise the menu-items */ ShareMenu.prototype.getContent = function () { var sMode = this._getMode(); if (sMode === ShareMenu._Mode.initial) { return []; } else if (sMode === ShareMenu._Mode.button) { return [this._oBaseButton]; } else { return this._oActionSheet.getAggregation("buttons") || []; } }; /** * Adds an item to this menu * * @param {sap.m.Button} oButton - the new button to be added * @param {boolean} bSuppressInvalidate - if true, the menu as well as the added child are not marked as changed * @return {this} Returns <code>this</code> to allow method chaining */ ShareMenu.prototype.addContent = function (oButton, bSuppressInvalidate) { var sMode = this._getMode(); this._observeButton(oButton); if (sMode === ShareMenu._Mode.initial) { this._setMode(ShareMenu._Mode.button, bSuppressInvalidate, oButton); return this; } if (sMode === ShareMenu._Mode.button) { this._setMode(ShareMenu._Mode.actionSheet, bSuppressInvalidate); } this._preProcessOverflowToolbarButton(oButton); this._oActionSheet.addButton(oButton, bSuppressInvalidate); this._updateShareBtnVisibility(); return this; }; /** * Inserts an item to this menu * * @param {sap.m.Button} oButton - the new button to be inserted * @param {number} iIndex - the insert index * @param {boolean} bSuppressInvalidate - if true, the menu as well as the inserted child are not marked as changed * @return {this} Returns <code>this</code> to allow method chaining */ ShareMenu.prototype.insertContent = function (oButton, iIndex, bSuppressInvalidate) { var sMode = this._getMode(); this._observeButton(oButton); if (sMode === ShareMenu._Mode.initial) { this._setMode(ShareMenu._Mode.button, bSuppressInvalidate, oButton); return this; } if (sMode === ShareMenu._Mode.button) { this._setMode(ShareMenu._Mode.actionSheet, bSuppressInvalidate); } this._preProcessOverflowToolbarButton(oButton); this._oActionSheet.insertButton(oButton, iIndex, bSuppressInvalidate); this._updateShareBtnVisibility(); return this; }; /** * Provides the 0-based item-index of given menu-item * * @param {sap.m.Button} oButton - the menu-item * @returns {number} the item-index */ ShareMenu.prototype.indexOfContent = function (oButton) { if ((this._getMode() === ShareMenu._Mode.button) && (oButton === this._oBaseButton)) { return 0; } if (this._getMode() === ShareMenu._Mode.actionSheet) { return this._oActionSheet.indexOfAggregation("buttons", oButton); } return -1; }; /** * Removes the given item from the menu * * @param {sap.m.Button} oButton - the button to be removed * @param {boolean} bSuppressInvalidate - if true, the menu as well as the inserted child are not marked as changed * @return {sap.m.Button} - the removed button */ ShareMenu.prototype.removeContent = function (oButton, bSuppressInvalidate) { var result, sMode = this._getMode(); if (sMode === ShareMenu._Mode.actionSheet) { result = this._oActionSheet.removeButton(oButton, bSuppressInvalidate); this._postProcessOverflowToolbarButton(oButton); this._unobserveButton(oButton); if (result) { if (this._oActionSheet.getAggregation("buttons").length === 1) { this._setMode(ShareMenu._Mode.button, bSuppressInvalidate); } } this._updateShareBtnVisibility(); return result; } if (sMode === ShareMenu._Mode.button) { var oLastButton = this._oBaseButton; this._setMode(ShareMenu._Mode.initial, bSuppressInvalidate); return oLastButton; } return result; }; /** * Removes all of the items of the menu * * @param {boolean} bSuppressInvalidate - if true, the menu as well as the inserted child are not marked as changed * @return {array} - an array of the removed buttons */ ShareMenu.prototype.removeAllContent = function (bSuppressInvalidate) { var result; if (this._getMode() === ShareMenu._Mode.actionSheet) { result = this._oActionSheet.removeAllButtons(bSuppressInvalidate); result.forEach(function(oButton){ this._postProcessOverflowToolbarButton(oButton); this._unobserveButton(oButton); }, this); this._updateShareBtnVisibility(); } else if (this._getMode() === ShareMenu._Mode.button) { result = [this._oBaseButton]; } this._setMode(ShareMenu._Mode.initial, bSuppressInvalidate); return result; }; /** * Destroys the controls used internally for this menu * * @param {boolean} bSuppressInvalidate - if true, the menu as well as the inserted child are not marked as changed */ ShareMenu.prototype.destroy = function(bSuppressInvalidate) { this._oActionSheet.destroy(bSuppressInvalidate); if (this._oShareMenuBtn) { this._oShareMenuBtn.destroy(bSuppressInvalidate); this._oShareMenuBtn = null; } if (this._oContentObserver) { this._oContentObserver.disconnect(); this._oContentObserver = null; } }; /** * Sets a new button as a base button for this menu * The base button is part of the shareMenu and its functionality is dependent on the shareMenu mode: * (1) In actionSheet mode, it opens the menu * (2) In "button" mode (i.e. when the menu has a single menu-item) it represents the only menu-item * * @param {sap.m.Button} oButton - the new base button * @param {boolean} bSuppressInvalidate - if true, the menu as well as the inserted child are not marked as changed * @return {this} Returns <code>this</code> to allow method chaining */ ShareMenu.prototype._setBaseButton = function (oButton, bSuppressInvalidate) { if (this._oBaseButton === oButton) { return this; } var oOldBaseButton = this._oBaseButton; this._oBaseButton = oButton; if (oOldBaseButton) { //update parent aggregation var oParent = oOldBaseButton.getParent(), sParentAggregationName = oOldBaseButton.sParentAggregationName; if (oParent) { oParent.removeAggregation(sParentAggregationName, oOldBaseButton, bSuppressInvalidate); oParent.addAggregation(sParentAggregationName, this._oBaseButton, bSuppressInvalidate); } } return this; }; /** * Getter for the current menu mode * @returns {string} an item of the ShareMenu._Mode type * @private */ ShareMenu.prototype._getMode = function () { return this._mode; }; /** * Sets a new ShareMenu mode * @param {sap.m.semantic.ShareMenu._Mode} sMode - the new mode * @param {boolean} bSuppressInvalidate - flag to suppress control invalidation upon change * @param oBaseButton - when the new mode is ShareMenu._Mode.button, a reference to that button * * @return {this} Returns <code>this</code> to allow method chaining */ ShareMenu.prototype._setMode = function (sMode, bSuppressInvalidate, oBaseButton) { if (!ShareMenu._Mode[sMode]) { Log.error("unknown shareMenu mode " + sMode, this); return this; } if (this._mode === sMode) { return this; } if (ShareMenu._Mode.initial === sMode) { this._setBaseButton(this._getShareMenuButton().applySettings({visible: false})); this._mode = ShareMenu._Mode.initial; return this; } if (sMode === ShareMenu._Mode.button) { if (this._mode === ShareMenu._Mode.initial) { this._setBaseButton(oBaseButton); } else if (this._mode === ShareMenu._Mode.actionSheet) { var oLastButton = this._oActionSheet.getAggregation("buttons")[0]; this._oActionSheet.removeButton(oLastButton, bSuppressInvalidate); this._postProcessOverflowToolbarButton(oLastButton); this._setBaseButton(oLastButton); } this._mode = ShareMenu._Mode.button; return this; } if (sMode === ShareMenu._Mode.actionSheet) { var oOldBaseButton = this._oBaseButton; this._setBaseButton(this._getShareMenuButton().applySettings({visible: true})); if (oOldBaseButton) { this._preProcessOverflowToolbarButton(oOldBaseButton); this._oActionSheet.addButton(oOldBaseButton, bSuppressInvalidate); } this._mode = ShareMenu._Mode.actionSheet; } return this; }; /** * Creates the standard "share" button that will be used for opening the menu in "actionSheet" mode * @returns {sap.m.Button} * @private */ ShareMenu.prototype._getShareMenuButton = function() { if (!this._oShareMenuBtn) { var that = this; this._oShareMenuBtn = new Button(this._oActionSheet.getParent().getId() + "-shareButton", { ariaHasPopup: AriaHasPopup.Menu, icon: IconPool.getIconURI("action"), tooltip: Library.getResourceBundleFor("sap.m").getText("SEMANTIC_CONTROL_ACTION_SHARE"), layoutData: new OverflowToolbarLayoutData({ priority: OverflowToolbarPriority.NeverOverflow }), press: function () { that._oActionSheet.openBy(that._oShareMenuBtn); } }); } return this._oShareMenuBtn; }; /** * Retrieves the visible items of this menu. * * @returns {Array} an array of the visible menu items */ ShareMenu.prototype._getVisibleContent = function () { return this.getContent().filter(function(oButton) { return oButton.getVisible(); }); }; /** * Updates the share menu button visibility * in respect to the hare menu content count and visibility. * * If there is a single item - that button is the base button. * If there are two or more share menu buttons: * (a) at least one visible button - the share menu button is visible. * (b) no visible buttons - the share menu button is hidden. * * @returns {Array} an array of the visible menu items */ ShareMenu.prototype._updateShareBtnVisibility = function () { var aVisibleContent = this._getVisibleContent(), bToggle = aVisibleContent.length > 0; this._getShareMenuButton().setVisible(bToggle); }; /** * This function is run before adding a button to the action sheet * If the button is OverflowToolbarButton, it is made to show icon+text * @param oButton * @private */ ShareMenu.prototype._preProcessOverflowToolbarButton = function(oButton) { if (oButton instanceof OverflowToolbarButton) { oButton._bInOverflow = true; } }; /** * This function is run after a button has been removed from the action sheet * If the button is OverflowToolbarButton, it is made to only show an icon * @param oButton * @private */ ShareMenu.prototype._postProcessOverflowToolbarButton = function(oButton) { if (oButton instanceof OverflowToolbarButton) { delete oButton._bInOverflow; } }; /** * Starts observing the <code>visible</code> property. * * @param {sap.m.Button} oButton */ ShareMenu.prototype._observeButton = function(oButton) { this._oContentObserver.observe(oButton, { properties: ["visible"] }); }; /** * Stops observing the <code>visible</code> property. */ ShareMenu.prototype._unobserveButton = function(oButton) { this._oContentObserver.unobserve(oButton, { properties: ["visible"] }); }; return ShareMenu; });