@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
559 lines (524 loc) • 19.3 kB
JavaScript
/*!
* 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'> </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(" ");
}
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;
});