Skip to content

Commit 781a63e

Browse files
1 parent 576ca1c commit 781a63e

12 files changed

+1908
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<core:FragmentDefinition
2+
xmlns="sap.m"
3+
xmlns:mvc="sap.ui.core.mvc"
4+
xmlns:core="sap.ui.core"
5+
xmlns:html="http://www.w3.org/1999/xhtml"
6+
xmlns:ce="sap.ui.codeeditor"
7+
>
8+
<Dialog
9+
title="abap2UI5 - Debug Tool"
10+
stretch="true"
11+
>
12+
<IconTabHeader
13+
selectedKey="PLAIN"
14+
select="onItemSelect"
15+
>
16+
<items>
17+
<IconTabFilter
18+
text="Config"
19+
key="CONFIG"
20+
enabled="true"
21+
/>
22+
<IconTabFilter
23+
text="Previous Request"
24+
key="REQUEST"
25+
enabled="true"
26+
/>
27+
<IconTabFilter
28+
text="Response"
29+
key="PLAIN"
30+
/>
31+
<IconTabFilter
32+
text="Source Code"
33+
key="SOURCE"
34+
/>
35+
<IconTabFilter
36+
text="View"
37+
key="VIEW"
38+
/>
39+
<IconTabFilter
40+
text="View Model"
41+
key="MODEL"
42+
/>
43+
<IconTabFilter
44+
text="Popup"
45+
key="POPUP"
46+
enabled="{/activePopup}"
47+
/>
48+
<IconTabFilter
49+
text="Popup Model"
50+
key="POPUP_MODEL"
51+
enabled="{/activePopup}"
52+
/>
53+
<IconTabFilter
54+
text="Popover"
55+
key="POPOVER"
56+
enabled="{/activePopover}"
57+
/>
58+
<IconTabFilter
59+
text="Popover Model"
60+
key="POPOVER_MODEL"
61+
enabled="{/activePopover}"
62+
/>
63+
<IconTabFilter
64+
text="Nest1"
65+
key="NEST1"
66+
enabled="{/activeNest1}"
67+
/>
68+
<IconTabFilter
69+
text="Nest1 Model"
70+
key="NEST1_MODEL"
71+
enabled="{/activeNest1}"
72+
/>
73+
<IconTabFilter
74+
text="Nest2"
75+
key="NEST2"
76+
enabled="{/activeNest2}"
77+
/>
78+
<IconTabFilter
79+
text="Nest2 Model"
80+
key="NEST2_MODEL"
81+
enabled="{/activeNest2}"
82+
/>
83+
</items>
84+
</IconTabHeader>
85+
<VBox>
86+
<ToggleButton text="Source XML after Templating" visible="{/isTemplating}" pressed="{/templatingSource}" press="onTemplatingPress" />
87+
<ce:CodeEditor
88+
type="{/type}"
89+
value="{/value}"
90+
height="2000px"
91+
width="10000px"
92+
visible="{/editor_visible}"
93+
/></VBox>
94+
<VBox visible="{/source_visible}">
95+
<core:HTML/>
96+
</VBox>
97+
<endButton>
98+
<Button
99+
text="Close"
100+
press="onClose"
101+
/>
102+
</endButton>
103+
</Dialog>
104+
</core:FragmentDefinition>

src/02/z2ui5.wapa.cc_-debugtool.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
sap.ui.define(["sap/ui/core/Control", "sap/ui/core/Fragment", "sap/ui/model/json/JSONModel"], (Control, Fragment, JSONModel) => {
2+
"use strict";
3+
4+
return Control.extend("z2ui5.cc.DebugTool", {
5+
6+
prettifyXml: function (sourceXml) {
7+
const xmlDoc = new DOMParser().parseFromString(sourceXml, 'application/xml');
8+
var sParse = `&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
9+
&lt;xsl:strip-space elements="*" /&gt;
10+
&lt;xsl:template match="para[content-style][not(text())]"&gt;
11+
&lt;xsl:value-of select="normalize-space(.)" /&gt;
12+
&lt;/xsl:template&gt;
13+
&lt;xsl:template match="node()|@*"&gt;
14+
&lt;xsl:copy&gt;
15+
&lt;xsl:apply-templates select="node()|@*" /&gt;
16+
&lt;/xsl:copy&gt;
17+
&lt;/xsl:template&gt;
18+
&lt;xsl:output indent="yes" /&gt;
19+
&lt;/xsl:stylesheet&gt;`;
20+
sParse = sParse.replace(/&gt;/g, unescape("%3E")).replace(/&lt;/g, unescape("%3C"));
21+
const xsltDoc = new DOMParser().parseFromString(sParse, 'application/xml');
22+
23+
const xsltProcessor = new XSLTProcessor();
24+
xsltProcessor.importStylesheet(xsltDoc);
25+
const resultDoc = xsltProcessor.transformToDocument(xmlDoc);
26+
const resultXml = new XMLSerializer().serializeToString(resultDoc);
27+
return resultXml.replace(/&gt;/g, ">").replace(/&lt;/g, "<");
28+
}, onItemSelect: function (oEvent) {
29+
const selItem = oEvent.getSource().getSelectedKey();
30+
const oView = z2ui5?.oView;
31+
const oResponse = z2ui5?.oResponse;
32+
const displayEditor = this.displayEditor.bind(this);
33+
34+
switch (selItem) {
35+
case 'CONFIG':
36+
displayEditor(oEvent, JSON.stringify(z2ui5.oConfig, null, 3), 'json');
37+
break;
38+
case 'MODEL':
39+
displayEditor(oEvent, JSON.stringify(oView?.getModel()?.getData(), null, 3), 'json');
40+
break;
41+
case 'VIEW':
42+
const viewContent = oView?.mProperties?.viewContent || z2ui5.responseData.S_FRONT.PARAMS.S_VIEW.XML;
43+
displayEditor(oEvent, this.prettifyXml(viewContent), 'xml', this.prettifyXml(oView?._xContent.outerHTML));
44+
break;
45+
case 'PLAIN':
46+
displayEditor(oEvent, JSON.stringify(z2ui5.responseData, null, 3), 'json');
47+
break;
48+
case 'REQUEST':
49+
displayEditor(oEvent, JSON.stringify(z2ui5.oBody, null, 3), 'json');
50+
break;
51+
case 'POPUP':
52+
displayEditor(oEvent, this.prettifyXml(oResponse?.PARAMS?.S_POPUP?.XML), 'xml');
53+
break;
54+
case 'POPUP_MODEL':
55+
displayEditor(oEvent, JSON.stringify(z2ui5.oViewPopup.getModel().getData(), null, 3), 'json');
56+
break;
57+
case 'POPOVER':
58+
displayEditor(oEvent, oResponse?.PARAMS?.S_POPOVER?.XML, 'xml');
59+
break;
60+
case 'POPOVER_MODEL':
61+
displayEditor(oEvent, JSON.stringify(z2ui5?.oViewPopover?.getModel()?.getData(), null, 3), 'json');
62+
break;
63+
case 'NEST1':
64+
displayEditor(oEvent, this.prettifyXml(z2ui5?.oViewNest?.mProperties?.viewContent), 'xml', this.prettifyXml(z2ui5?.oViewNest?._xContent.outerHTML));
65+
break;
66+
case 'NEST1_MODEL':
67+
displayEditor(oEvent, JSON.stringify(z2ui5?.oViewNest?.getModel()?.getData(), null, 3), 'json');
68+
break;
69+
case 'NEST2':
70+
displayEditor(oEvent, this.prettifyXml(z2ui5?.oViewNest2?.mProperties?.viewContent), 'xml', this.prettifyXml(z2ui5?.oViewNest2?._xContent.outerHTML));
71+
break;
72+
case 'NEST2_MODEL':
73+
displayEditor(oEvent, JSON.stringify(z2ui5?.oViewNest2?.getModel()?.getData(), null, 3), 'json');
74+
break;
75+
case 'SOURCE':
76+
const parent = oEvent.getSource().getParent();
77+
const contentControl = parent.getContent()[2].getItems()[0];
78+
const url = `${window.location.origin}/sap/bc/adt/oo/classes/${z2ui5.responseData.S_FRONT.APP}/source/main`;
79+
const content = atob('PGlmcmFtZSBpZD0idGVzdCIgc3JjPSInICsgdXJsICsgJyIgaGVpZ2h0PSI4MDBweCIgd2lkdGg9IjEyMDBweCIgLz4=').replace("' + url + '", url);
80+
contentControl.setProperty("content", content);
81+
const modelData = oEvent.getSource().getModel().oData;
82+
modelData.editor_visible = false;
83+
modelData.source_visible = true;
84+
oEvent.getSource().getModel().refresh();
85+
break;
86+
}
87+
},
88+
89+
displayEditor: function (oEvent, content, type, xcontent = "") {
90+
const modelData = oEvent.getSource().getModel().oData;
91+
modelData.editor_visible = true;
92+
modelData.source_visible = false;
93+
modelData.isTemplating = content.includes("xmlns:template");
94+
modelData.value = content;
95+
modelData.previousValue = content;
96+
modelData.xContent = xcontent;
97+
modelData.type = type;
98+
oEvent.getSource().getModel().refresh();
99+
},
100+
101+
onTemplatingPress: function (oEvent) {
102+
const modelData = oEvent.getSource().getModel().oData;
103+
modelData.value = oEvent.getSource().getPressed() ? modelData.xContent : modelData.previousValue;
104+
oEvent.getSource().getModel().refresh();
105+
},
106+
107+
onClose: function () {
108+
this.oDialog.close();
109+
},
110+
111+
async show() {
112+
if (!this.oDialog) {
113+
this.oDialog = await Fragment.load({
114+
name: "z2ui5.cc.DebugTool",
115+
controller: this,
116+
});
117+
}
118+
119+
const value = JSON.stringify(z2ui5.responseData, null, 3);
120+
const oData = {
121+
type: 'json',
122+
source_visible: false,
123+
editor_visible: true,
124+
value: value,
125+
xContent: '',
126+
previousValue: value,
127+
isTemplating: false,
128+
templatingSource: false,
129+
activeNest1: z2ui5?.oViewNest?.mProperties?.viewContent !== undefined,
130+
activeNest2: z2ui5?.oViewNest2?.mProperties?.viewContent !== undefined,
131+
activePopup: z2ui5?.oResponse?.PARAMS?.S_POPUP?.XML !== undefined,
132+
activePopover: z2ui5?.oResponse?.PARAMS?.S_POPOVER?.XML !== undefined,
133+
};
134+
const oModel = new JSONModel(oData);
135+
136+
this.oDialog.addStyleClass('dbg-ltr');
137+
this.oDialog.setModel(oModel);
138+
this.oDialog.open();
139+
}
140+
});
141+
});

src/02/z2ui5.wapa.cc_-server.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
sap.ui.define(["sap/ui/core/BusyIndicator", "sap/m/MessageBox"
2+
],
3+
function (BusyIndicator, MessageBox) {
4+
"use strict";
5+
6+
return {
7+
8+
endSession: function () {
9+
10+
if (z2ui5.contextId) {
11+
fetch(z2ui5.oConfig.pathname, {
12+
method: 'HEAD',
13+
keepalive: true,
14+
headers: {
15+
'sap-terminate': 'session',
16+
'sap-contextid': z2ui5.contextId,
17+
'sap-contextid-accept': 'header'
18+
}
19+
});
20+
delete z2ui5.contextId;
21+
}
22+
23+
},
24+
Roundtrip() {
25+
z2ui5.checkTimerActive = false;
26+
z2ui5.checkNestAfter = false;
27+
z2ui5.checkNestAfter2 = false;
28+
let event = (args) => {
29+
if (args != undefined) {
30+
return args[0][0];
31+
}
32+
};
33+
34+
z2ui5.oBody ??= {};
35+
z2ui5.oBody.S_FRONT = {
36+
ID: z2ui5?.oBody?.ID,
37+
CONFIG: z2ui5.oConfig,
38+
XX: z2ui5?.oBody?.XX,
39+
ORIGIN: window.location.origin,
40+
PATHNAME: window.location.pathname,
41+
SEARCH: (z2ui5.search) ? z2ui5.search : window.location.search,
42+
VIEW: z2ui5.oBody?.VIEWNAME,
43+
EVENT: event(z2ui5.oBody?.ARGUMENTS),
44+
HASH: window.location.hash,
45+
};
46+
if (z2ui5.oBody?.ARGUMENTS != undefined) {
47+
if (z2ui5.oBody?.ARGUMENTS.length > 0) {
48+
z2ui5.oBody?.ARGUMENTS.shift();
49+
}
50+
}
51+
z2ui5.oBody.S_FRONT.T_EVENT_ARG = z2ui5.oBody?.ARGUMENTS;
52+
delete z2ui5.oBody.ID;
53+
delete z2ui5.oBody?.VIEWNAME;
54+
delete z2ui5.oBody?.S_FRONT.XX;
55+
delete z2ui5.oBody?.ARGUMENTS;
56+
if (!z2ui5.oBody.S_FRONT.T_EVENT_ARG) {
57+
delete z2ui5.oBody.S_FRONT.T_EVENT_ARG;
58+
}
59+
if (z2ui5.oBody.S_FRONT.T_EVENT_ARG) {
60+
if (z2ui5.oBody.S_FRONT.T_EVENT_ARG.length == 0) {
61+
delete z2ui5.oBody.S_FRONT.T_EVENT_ARG;
62+
}
63+
}
64+
if (z2ui5.oBody.S_FRONT.T_STARTUP_PARAMETERS == undefined) {
65+
delete z2ui5.oBody.S_FRONT.T_STARTUP_PARAMETERS;
66+
}
67+
if (z2ui5.oBody.S_FRONT.SEARCH == '') {
68+
delete z2ui5.oBody.S_FRONT.SEARCH;
69+
}
70+
if (!z2ui5.oBody.XX) {
71+
delete z2ui5.oBody.XX;
72+
}
73+
this.readHttp();
74+
},
75+
76+
async readHttp() {
77+
const response = await fetch(z2ui5.oConfig.pathname, {
78+
method: 'POST',
79+
headers: {
80+
'Content-Type': 'application/json',
81+
'sap-contextid-accept': 'header',
82+
'sap-contextid': z2ui5.contextId
83+
},
84+
body: JSON.stringify(z2ui5.oBody)
85+
});
86+
z2ui5.contextId = response.headers.get("sap-contextid");
87+
if (!response.ok) {
88+
const responseText = await response.text();
89+
this.responseError(responseText);
90+
} else {
91+
const responseData = await response.json();
92+
z2ui5.responseData = responseData;
93+
this.responseSuccess({
94+
ID: responseData.S_FRONT.ID,
95+
PARAMS: responseData.S_FRONT.PARAMS,
96+
OVIEWMODEL: responseData.MODEL,
97+
});
98+
}
99+
},
100+
async responseSuccess(response) {
101+
try {
102+
z2ui5.oResponse = response;
103+
if (z2ui5.oResponse.PARAMS?.S_VIEW?.CHECK_DESTROY) {
104+
z2ui5.oController.ViewDestroy();
105+
}
106+
; if (z2ui5.oResponse.PARAMS?.S_FOLLOW_UP_ACTION?.CUSTOM_JS) {
107+
setTimeout(() => {
108+
let mParams = z2ui5.oResponse?.PARAMS.S_FOLLOW_UP_ACTION.CUSTOM_JS.split("'");
109+
let mParamsEF = mParams.filter((val, index) => index % 2)
110+
if (mParamsEF.length) {
111+
z2ui5.oController.eF.apply(undefined, mParamsEF);
112+
} else {
113+
Function("return " + mParams[0])();
114+
}
115+
}, 100);
116+
};
117+
z2ui5.oController.showMessage('S_MSG_TOAST', z2ui5.oResponse.PARAMS);
118+
z2ui5.oController.showMessage('S_MSG_BOX', z2ui5.oResponse.PARAMS);
119+
if (z2ui5.oResponse.PARAMS?.S_VIEW?.XML) {
120+
if (z2ui5.oResponse.PARAMS?.S_VIEW?.XML !== '') {
121+
z2ui5.oController.ViewDestroy();
122+
await z2ui5.oController.displayView(z2ui5.oResponse.PARAMS.S_VIEW.XML, z2ui5.oResponse.OVIEWMODEL);
123+
return;
124+
}
125+
}
126+
z2ui5.oController.updateModelIfRequired('S_VIEW', z2ui5.oView);
127+
z2ui5.oController.updateModelIfRequired('S_VIEW_NEST', z2ui5.oViewNest);
128+
z2ui5.oController.updateModelIfRequired('S_VIEW_NEST2', z2ui5.oViewNest2);
129+
z2ui5.oController.updateModelIfRequired('S_POPUP', z2ui5.oViewPopup);
130+
z2ui5.oController.updateModelIfRequired('S_POPOVER', z2ui5.oViewPopover);
131+
z2ui5.oController.onAfterRendering();
132+
} catch (e) {
133+
BusyIndicator.hide();
134+
if (e.message.includes("openui5")) {
135+
if (e.message.includes("script load error")) {
136+
z2ui5.oController.checkSDKcompatibility(e)
137+
}
138+
} else {
139+
MessageBox.error(e.toLocaleString());
140+
}
141+
}
142+
},
143+
responseError(response) {
144+
document.write(response);
145+
},
146+
};
147+
});

0 commit comments

Comments
 (0)