UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

195 lines (170 loc) 6.77 kB
/*! * OpenUI5 * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides inactive support for controls sap.ui.define(["sap/base/assert"], function(assert) { "use strict"; /** * @class Mixin for Controls which enables stashing of controls declaratively in XMLViews * * NOTE: stashingh of <code>sap.ui.core.Fragments</code> and <code>sap.ui.core.mvc.View</code> is not supported! * * <code>stashed</code> Controls are created as placeholder control without any content and bindings * and added to the Control tree. That means it is available with <code>sap.ui.getCore().byId</code> * and as child in the parents aggregation. It is unstashable by calling <code>unstash</code>. * Currently this is a one-time operation. Once unstashed, a control cannot be re-stashed again. * * @name sap.ui.core.StashedControlSupport * @since 1.35 * @private */ var StashedControlSupport = {}, /** * inactive controls registry * @private */ stashedControls = {}; /** * Mixin function to enhance control functionality * * @name sap.ui.core.StashedControlSupport.mixInto * @param {function} fnClass the class to be enhanced * * @private */ StashedControlSupport.mixInto = function(fnClass) { assert(!fnClass.prototype.unstash, "StashedControlSupport: fnClass already has method 'unstash', sideeffects possible", fnClass.getMetadata().getName()); if (fnClass.getMetadata().isA("sap.ui.core.Fragment") || fnClass.getMetadata().isA("sap.ui.core.mvc.View")) { throw new Error("Stashing is not supported for sap.ui.coreFragment or sap.ui.core.mvc.View"); } mixInto(fnClass); }; // private function without validity checks function mixInto(fnClass) { // mix the required methods into the target fnClass fnClass.prototype.unstash = function() { if (this.isStashed()) { var oControl = unstash(this); // we need to set the property to the stashed control oControl.stashed = false; return oControl; } return this; }; fnClass.prototype.isStashed = function() { return !!stashedControls[this.getId()]; }; var fnClone = fnClass.prototype.clone; fnClass.prototype.clone = function() { if (this.isStashed()) { throw new Error("A stashed control cannot be cloned, id: '" + this.getId() + "'."); } return fnClone.apply(this, arguments); }; var fnDestroy = fnClass.prototype.destroy; fnClass.prototype.destroy = function() { delete stashedControls[this.getId()]; fnDestroy.apply(this, arguments); }; } function unstash(oWrapperControl) { var oWrapperParent; var iIndexInParent; var oTargetAggregation; var oStashedInfo = stashedControls[oWrapperControl.getId()]; // find parent of wrapper control oWrapperParent = oWrapperControl.getParent(); // the wrapper might have been removed from the control tree // in this case we can't find it in any aggregation and will not have an index for removal/insertation if (oWrapperParent) { oTargetAggregation = oWrapperParent.getMetadata().getAggregation(oWrapperControl.sParentAggregationName); iIndexInParent = oTargetAggregation.indexOf(oWrapperParent, oWrapperControl); // remove wrapper (removeAggregation does nothing if not in the aggregation) oTargetAggregation.remove(oWrapperParent, oWrapperControl); } // always: destroy wrapper and free the id for the actual control instance oWrapperControl.destroy(); // finally perform the real unstashing by starting the XMLTP again for the stashed part (scoped in XMLTP) var Component = sap.ui.require("sap/ui/core/Component"); var oOwnerComponent = Component && Component.getOwnerComponentFor(oWrapperParent); var aControls; var fnCreate = oStashedInfo.fnCreate; if (oOwnerComponent) { aControls = oOwnerComponent.runAsOwner(fnCreate); } else { aControls = fnCreate(); } // found an index: we can now insert the actual control instance if (iIndexInParent >= 0) { // call hook to create the actual control (multiple controls in case of fragment) aControls.forEach(function(c) { oTargetAggregation.insert(oWrapperParent, c, iIndexInParent); }); } delete stashedControls[oWrapperControl.getId()]; //TemplateProcessor returns an array. Should contain only one control in the stashed scenario. return aControls[0]; } function getStashedControls(bAsInstance, sParentId) { var aStashedChildren = []; for (var sId in stashedControls) { // get placeholder for stashed-control var oPlaceholder = sap.ui.getCore().byId(stashedControls[sId].wrapperId); var vInstanceOrId = bAsInstance ? oPlaceholder : sId; // A stashed-control without a placeholder can happen if the placeholder was already destroyed. // In this case we also don't have a parent. var oPlaceholderParent = oPlaceholder && oPlaceholder.getParent(); if (!sParentId || (oPlaceholderParent && oPlaceholderParent.getId() === sParentId)) { aStashedChildren.push(vInstanceOrId); } } return aStashedChildren; } /** * Gets the ids of StashedControls * * @name sap.ui.core.StashedControlSupport.getStashedControlIds * @param {string} [sParentId] if set only StashedControlIds for a specific parent are returned * @return {string[]} array with the ids of the StashedControls * * @private */ StashedControlSupport.getStashedControlIds = function(sParentId) { return getStashedControls(false, sParentId); }; /** * Gets the instances of StashedControls * * @name sap.ui.core.StashedControlSupport.getStashedControlIds * @param {string} [sParentId] if set only StashedControls for a specific parent are returned * @return {Control[]} array with the StashedControls * * @private */ StashedControlSupport.getStashedControls = function(sParentId) { return getStashedControls(true, sParentId); }; /** * StashedControl factory function * * @name sap.ui.core.StashedControlSupport.createStashedControl * @param {object} mSettings the settings object * @param {string} mSettings.wrapperId the ID for the placeholder control * @param {string} mSettings.fnCreate hook for the later creation, which should return the actual control * @return {sap.ui.core._StashedControl} the StashedControl * * @private */ StashedControlSupport.createStashedControl = function(mSettings) { var oStashedInfo = { wrapperId: mSettings.wrapperId, fnCreate: mSettings.fnCreate }; stashedControls[mSettings.wrapperId] = oStashedInfo; return oStashedInfo; }; return StashedControlSupport; });