UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

559 lines (524 loc) 19.3 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 a (modifiable) list of properties for a given control sap.ui.define('sap/ui/debug/PropertyList', [ 'sap/ui/base/DataType', 'sap/ui/base/EventProvider', 'sap/ui/core/Element', 'sap/ui/core/ElementMetadata', 'sap/base/util/isEmptyObject', 'sap/base/util/ObjectPath', 'sap/base/strings/capitalize', 'sap/base/security/encodeXML', 'sap/ui/thirdparty/jquery', 'sap/ui/dom/jquery/rect' // jQuery Plugin "rect" ], function( DataType, EventProvider, Element, ElementMetadata, isEmptyObject, ObjectPath, capitalize, encodeXML, jQuery ) { "use strict"; /** * Constructs the class <code>sap.ui.debug.PropertyList</code>. * * @class HTML Property list for a <code>sap.ui.core.Control</code> in the * Debug Environment * * @extends sap.ui.base.EventProvider * @author Martin Schaus * @version 1.87.1 * * @param {sap.ui.core.Core} * oCore the core instance to use for analysis * @param {Window} * oWindow reference to the window object * @param {object} * oParentDomRef reference to the parent DOM element * * @alias sap.ui.debug.PropertyList * @private */ var PropertyList = EventProvider.extend("sap.ui.debug.PropertyList", /** @lends sap.ui.debug.PropertyList.prototype */ { constructor: function(oCore, oWindow, oParentDomRef) { EventProvider.apply(this,arguments); this.oWindow = oWindow; this.oParentDomRef = oParentDomRef; // this.oCore = oWindow.sap.ui.getCore(); this.oCore = oCore; this.bEmbedded = top.window == oWindow; // check only with ==, not === as the test otherwise fails on IE8 this.mProperties = {}; this.onclick = PropertyList.prototype.onclick.bind(this); oParentDomRef.addEventListener("click", this.onclick); this.onfocus = PropertyList.prototype.onfocus.bind(this); oParentDomRef.addEventListener("focusin", this.onfocus); this.onkeydown = PropertyList.prototype.onkeydown.bind(this); oParentDomRef.addEventListener("keydown", this.onkeydown); if ( !this.bEmbedded ) { this.onmouseover = PropertyList.prototype.onmouseover.bind(this); oParentDomRef.addEventListener("mouseover", this.onmouseover); this.onmouseout = PropertyList.prototype.onmouseout.bind(this); oParentDomRef.addEventListener("mouseout", this.onmouseout); } //this.oParentDomRef.style.backgroundColor = "#e0e0e0"; //this.oParentDomRef.style.border = "solid 1px gray"; //this.oParentDomRef.style.padding = "2px"; } }); /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.exit = function() { this.oParentDomRef.removeEventListener("click", this.onclick); this.oParentDomRef.removeEventListener("focusin", this.onfocus); this.oParentDomRef.removeEventListener("keydown", this.onkeydown); if ( !this.bEmbedded ) { this.oParentDomRef.removeEventListener("mouseover", this.onmouseover); this.oParentDomRef.removeEventListener("mouseout", this.onmouseout); } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.update = function(oParams) { var sControlId = oParams.getParameter("controlId"); this.oParentDomRef.innerHTML = ""; var oControl = this.oCore.byId(sControlId); if (!oControl) { this.oParentDomRef.innerHTML = "Please select a valid control"; return; } if (!oControl.getMetadata || !oControl.getMetadata()) { this.oParentDomRef.innerHTML = "Control does not provide Metadata."; return; } this.mProperties = {}; var oMetadata = oControl.getMetadata(), aHTML = []; aHTML.push("<span data-sap-ui-quickhelp='" + this._calcHelpId(oMetadata) + "'>Type : " + oMetadata.getName() + "</span><br >"); aHTML.push("Id : " + oControl.getId() + "<br >"); aHTML.push("<button id='sap-debug-propertylist-apply' data-id='" + sControlId + "' style='border:solid 1px gray;background-color:#d0d0d0;font-size:8pt;'>Apply Changes</button>"); if ( !this.bEmbedded ) { aHTML.push("<div id='sap-ui-quickhelp' style='position:fixed;display:none;padding:5px;background-color:rgb(200,220,231);border:1px solid gray;overflow:hidden'>Help</div>"); } aHTML.push("<div style='border-bottom:1px solid gray'>&nbsp;</div><table cellspacing='1' style='font-size:8pt;width:100%;table-layout:fixed'>"); while ( oMetadata instanceof ElementMetadata ) { var mProperties = oMetadata.getProperties(); var bHeaderCreated = false; if ( !isEmptyObject(mProperties) ) { if ( !bHeaderCreated && oMetadata !== oControl.getMetadata() ) { aHTML.push("<tr><td colspan=\"2\">BaseType: "); aHTML.push(oMetadata.getName()); aHTML.push("</td></tr>"); bHeaderCreated = true; } this.printProperties(aHTML, oControl, mProperties); } var mProperties = this.getAggregationsAsProperties(oMetadata); if ( !isEmptyObject(mProperties) ) { if ( !bHeaderCreated && oMetadata !== oControl.getMetadata() ) { aHTML.push("<tr><td colspan=\"2\">BaseType: "); aHTML.push(oMetadata.getName()); aHTML.push("</td></tr>"); bHeaderCreated = true; } this.printProperties(aHTML, oControl, mProperties); } oMetadata = oMetadata.getParent(); } aHTML.push("</table>"); this.oParentDomRef.innerHTML = aHTML.join(""); this.mHelpDocs = {}; }; PropertyList.prototype.getAggregationsAsProperties = function(oMetadata) { function isSimpleType(sType) { if ( !sType ) { return false; } while ( sType.endsWith("[]") ) { sType = sType.slice(0, -"[]".length); } if ( sType === "boolean" || sType === "string" || sType === "int" || sType === "float" ) { return true; } if ( sType === "void" ) { return false; } // TODO check for enum return false; } var oResult = {}; for (var sAggrName in oMetadata.getAggregations() ) { var oAggr = oMetadata.getAggregations()[sAggrName]; if ( oAggr.altTypes && oAggr.altTypes[0] && isSimpleType(oAggr.altTypes[0]) ) { oResult[sAggrName] = { name : sAggrName, type : oAggr.altTypes[0], _oParent : oAggr._oParent }; } } return oResult; }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.printProperties = function(aHTML, oControl, mProperties, bAggregation) { for (var i in mProperties) { var sName = i, sType = mProperties[i].type, oMethod = oControl["get" + sName]; if (!oMethod) { sName = capitalize(sName,0); } var oValue = oControl["get" + sName](); aHTML.push("<tr><td>"); this.mProperties[sName] = sType; aHTML.push("<span data-sap-ui-quickhelp='", this._calcHelpId(mProperties[i]._oParent, i), "' >", sName, '</span>'); aHTML.push("</td><td>"); var sTitle = ""; if (sType == "string" || sType == "int" || sType == "float" || sType.endsWith("[]")) { var sColor = ''; if ( oValue === null ) { sColor = 'color:#a5a5a5;'; oValue = '(null)'; } else if ( oValue instanceof Element ) { sColor = 'color:#a5a5a5;'; if (Array.isArray(oValue)) { // array type (copied from primitive values above and modified the value to string / comma separated) oValue = oValue.join(", "); } else { oValue = oValue.toString(); } sTitle = ' title="This aggregation currently references an Element. You can set a ' + sType + ' value instead"'; } aHTML.push("<input type='text' style='width:100%;font-size:8pt;background-color:#f5f5f5;" + sColor + "' value='" + encodeXML("" + oValue) + "'" + sTitle + " data-name='" + sName + "'>"); } else if (sType == "boolean") { aHTML.push("<input type='checkbox' data-name='" + sName + "' "); if (oValue == true) { aHTML.push("checked='checked'"); } aHTML.push(">"); } else if (sType != "void") { //Enum or Custom Type var oEnum = ObjectPath.get(sType || ""); if (!oEnum || oEnum instanceof DataType) { aHTML.push("<input type='text' style='width:100%;font-size:8pt;background-color:#f5f5f5;' value='" + encodeXML("" + oValue) + "'" + sTitle + " data-name='" + sName + "'>"); } else { aHTML.push("<select style='width:100%;font-size:8pt;background-color:#f5f5f5;' data-name='" + sName + "'>"); sType = sType.replace("/","."); for (var n in oEnum) { aHTML.push("<option "); if (n == oValue) { aHTML.push(" selected "); } aHTML.push("value='" + sType + "." + n + "'>"); aHTML.push(n); aHTML.push("</option>"); } aHTML.push("</select>"); } } else { aHTML.push("&nbsp;"); } aHTML.push("</td></tr>"); } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.onkeydown = function(oEvent) { if (oEvent.keyCode == 13) { this.applyChanges("sap-debug-propertylist-apply"); } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.onclick = function(oEvent) { var oSource = oEvent.target; if (oSource.id == "sap-debug-propertylist-apply") { this.applyChanges("sap-debug-propertylist-apply"); } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.onfocus = function(oEvent) { var oSource = oEvent.target; if (oSource.tagName === "INPUT" && oSource.dataset.name ) { if ( oSource.style.color === '#a5a5a5' /* && oSource.value === '(null)' */ ) { oSource.style.color = ''; oSource.value = ''; } } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.applyChanges = function(sId) { var oSource = this.oParentDomRef.ownerDocument.getElementById(sId), sControlId = oSource.dataset.id, oControl = this.oCore.byId(sControlId), aInput = oSource.parentNode.getElementsByTagName("INPUT"), aSelect = oSource.parentNode.getElementsByTagName("SELECT"), oMethod; for (var i = 0; i < aInput.length; i++) { var oInput = aInput[i], sName = oInput.dataset.name; oMethod = oControl["set" + sName]; if (!oMethod) { sName = capitalize(sName,0); } if (oControl["set" + sName]) { var oType = DataType.getType(this.mProperties[sName]); var vValue = this.mProperties[sName] === "boolean" ? oInput.checked : oType.parseValue(oInput.value); if (oType.isValid(vValue) && vValue !== "(null)" ) { oControl["set" + sName](vValue); } } } for (var i = 0; i < aSelect.length; i++) { var oSelect = aSelect[i], sName = oSelect.dataset.name; oMethod = oControl["set" + sName]; if (!oMethod) { sName = capitalize(sName,0); } var oValue = null; if (oSelect.value) { /*eslint-disable no-eval */ eval("oValue = " + oSelect.value); oControl["set" + sName](oValue); /*eslint-enable no-eval */ } } this.oCore.applyChanges(); }; PropertyList.prototype.showQuickHelp = function(oSource) { if ( this.oQuickHelpTimer ) { clearTimeout(this.oQuickHelpTimer); this.oQuickHelpTimer = undefined; } var oTooltipDomRef = this.oParentDomRef.ownerDocument.getElementById("sap-ui-quickhelp"); if ( oTooltipDomRef ) { this.sCurrentHelpId = oSource.getAttribute("data-sap-ui-quickhelp"); var oRect = jQuery(oSource).rect(); oTooltipDomRef.style.left = (oRect.left + 40 + 10) + "px"; oTooltipDomRef.style.top = (oRect.top - 40) + "px"; oTooltipDomRef.style.display = 'block'; oTooltipDomRef.style.opacity = '0.2'; oTooltipDomRef.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=20)'; if ( this.mHelpDocs[this.sCurrentHelpId] ) { this.updateQuickHelp(this.mHelpDocs[this.sCurrentHelpId], 2000); } else { oTooltipDomRef.innerHTML = "<b>Quickhelp</b> for " + this.sCurrentHelpId + " is being retrieved..."; this.sCurrentHelpDoc = this.sCurrentHelpId; this.sCurrentHelpDocPart = undefined; if ( this.sCurrentHelpId.indexOf('#') >= 0 ) { this.sCurrentHelpDoc = this.sCurrentHelpId.substring(0, this.sCurrentHelpId.indexOf('#')); this.sCurrentHelpDocPart = this.sCurrentHelpId.substring(this.sCurrentHelpId.indexOf('#') + 1); } var sUrl = this.oWindow.jQuery.sap.getModulePath(this.sCurrentHelpDoc, ".control"); var that = this; jQuery.ajax({ url : sUrl, dataType : 'xml', error : function(xhr,status) { that.receiveQuickHelp(undefined); }, success : function(data) { that.receiveQuickHelp(data); } }); this.oQuickHelpTimer = setTimeout(function () { that.hideQuickHelp(); }, 2000); } } }; // ---- Quickhelp ---- PropertyList.prototype.receiveQuickHelp = function(oDocument) { if ( oDocument ) { var oControlNode = oDocument.getElementsByTagName("control")[0]; if ( oControlNode ) { var get = function(oXMLNode, sName) { var result = []; var oCandidate = oXMLNode.firstChild; while ( oCandidate ) { if ( sName === oCandidate.nodeName ) { result.push(oCandidate); } oCandidate = oCandidate.nextSibling; } return result; }; var aName = get(oControlNode, "name"); var sName = ''; if ( aName[0] ) { sName = aName[0].text || aName[0].textContent; } var aDocumentation = get(oControlNode, "documentation"); if ( aDocumentation[0] ) { if ( sName && aDocumentation[0] ) { var doc = []; doc.push("<div style='font-size:10pt;font-weight:bold;padding:5px 0px;margin-bottom:5px;border-bottom:1px solid gray'>", sName.replace('/', '.'), "</div>"); doc.push("<div style='padding:2px 0px;'>", aDocumentation[0].text || aDocumentation[0].textContent, "</div>"); this.mHelpDocs[this.sCurrentHelpDoc] = doc.join(""); } } var aProperties = get(oControlNode, "properties"); if ( aProperties[0] ) { aProperties = get(aProperties[0], "property"); } for (var i = 0, l = aProperties.length; i < l; i++) { var oProperty = aProperties[i]; var sName = oProperty.getAttribute("name"); var sType = oProperty.getAttribute("type") || "string"; var sDefaultValue = oProperty.getAttribute("defaultValue") || "empty/undefined"; var aDocumentation = get(oProperty, "documentation"); if ( sName && aDocumentation[0] ) { var doc = []; doc.push("<div style='font-size:10pt;font-weight:bold;padding:3px 0px;margin-bottom:3px;border-bottom:1px solid gray'>", sName, "</div>"); doc.push("<div style='padding:2px 0px;'><i><strong>Type</strong></i>: ", sType, "</div>"); doc.push("<div style='padding:2px 0px;'>", aDocumentation[0].text || aDocumentation[0].textContent, "</div>"); doc.push("<div style='padding:2px 0px;'><i><strong>Default Value</strong></i>: ", sDefaultValue, "</div>"); this.mHelpDocs[this.sCurrentHelpDoc + "#" + sName] = doc.join(""); } } var aProperties = get(oControlNode, "aggregations"); if ( aProperties[0] ) { aProperties = get(aProperties[0], "aggregation"); } for (var i = 0, l = aProperties.length; i < l; i++) { var oProperty = aProperties[i]; var sName = oProperty.getAttribute("name"); var sType = oProperty.getAttribute("type") || "sap.ui.core/Control"; var sDefaultValue = oProperty.getAttribute("defaultValue") || "empty/undefined"; var aDocumentation = get(oProperty, "documentation"); if ( sName && aDocumentation[0] && !this.mHelpDocs[this.sCurrentHelpDoc + "#" + sName]) { var doc = []; doc.push("<div style='font-size:10pt;font-weight:bold;padding:3px 0px;margin-bottom:3px;border-bottom:1px solid gray'>", sName, "</div>"); doc.push("<div style='padding:2px 0px;'><i><strong>Type</strong></i>: ", sType, "</div>"); doc.push("<div style='padding:2px 0px;'>", aDocumentation[0].text || aDocumentation[0].textContent, "</div>"); doc.push("<div style='padding:2px 0px;'><i><strong>Default Value</strong></i>: ", sDefaultValue, "</div>"); this.mHelpDocs[this.sCurrentHelpDoc + "#" + sName] = doc.join(""); } } } if ( this.mHelpDocs[this.sCurrentHelpId] ) { this.updateQuickHelp(this.mHelpDocs[this.sCurrentHelpId], 2000); } else { this.updateQuickHelp(undefined, 0); } } else { this.updateQuickHelp(undefined, 0); } }; PropertyList.prototype.updateQuickHelp = function(sNewContent, iTimeout) { if ( this.oQuickHelpTimer ) { clearTimeout(this.oQuickHelpTimer); this.oQuickHelpTimer = undefined; } var oTooltipDomRef = this.oParentDomRef.ownerDocument.getElementById("sap-ui-quickhelp"); if ( oTooltipDomRef ) { if ( !sNewContent ) { oTooltipDomRef.innerHTML = "<i>No quick help...</i>"; oTooltipDomRef.style.display = 'none'; } else { oTooltipDomRef.innerHTML = sNewContent; var that = this; this.oQuickHelpTimer = setTimeout(function () { that.hideQuickHelp(); }, iTimeout); } } }; PropertyList.prototype.hideQuickHelp = function() { var oTooltipDomRef = this.oParentDomRef.ownerDocument.getElementById("sap-ui-quickhelp"); if ( oTooltipDomRef ) { oTooltipDomRef.style.display = 'none'; } this.bMovedOverTooltip = false; }; PropertyList.prototype._calcHelpId = function(oMetadata, sName) { var sHelpId = oMetadata.getName(); if ( sName ) { sHelpId = sHelpId + "#" + sName; } return sHelpId; }; PropertyList.prototype._isChildOfQuickHelp = function(oDomRef) { while ( oDomRef ) { if ( oDomRef.id === "sap-ui-quickhelp" ) { return true; } oDomRef = oDomRef.parentNode; } return false; }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.onmouseover = function(oEvent) { var oSource = oEvent.target; if ( this._isChildOfQuickHelp(oSource) ) { // if the user enteres the tooltip with the mouse, we don't close it automatically if ( this.oQuickHelpTimer ) { clearTimeout(this.oQuickHelpTimer); this.oQuickHelpTimer = undefined; } this.bMovedOverTooltip = true; var oTooltipDomRef = this.oParentDomRef.ownerDocument.getElementById("sap-ui-quickhelp"); if ( oTooltipDomRef ) { oTooltipDomRef.style.opacity = ''; oTooltipDomRef.style.filter = ''; } } else if ( oSource.getAttribute("data-sap-ui-quickhelp") ) { this.showQuickHelp(oSource); } }; /** * TODO: missing internal JSDoc... @author please update * @private */ PropertyList.prototype.onmouseout = function(oEvent) { var oSource = oEvent.target; if ( this._isChildOfQuickHelp(oSource) ) { if ( this.oQuickHelpTimer ) { clearTimeout(this.oQuickHelpTimer); this.oQuickHelpTimer = undefined; } this.bMovedOverTooltip = false; var that = this; this.oQuickHelpTimer = setTimeout(function () { that.hideQuickHelp(); }, 50); } else if (oSource.getAttribute("data-sap-ui-quickhelp")) { if ( this.oQuickHelpTimer ) { clearTimeout(this.oQuickHelpTimer); this.oQuickHelpTimer = undefined; } if ( !this.bMovedOverTooltip ) { var that = this; this.oQuickHelpTimer = setTimeout(function () { that.hideQuickHelp(); }, 800); } } }; return PropertyList; });