@saltcorn/mobile-app 0.9.1-beta.0 → 0.9.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/www/index.html
CHANGED
|
@@ -415,7 +415,7 @@
|
|
|
415
415
|
fullWrap: true,
|
|
416
416
|
alerts,
|
|
417
417
|
});
|
|
418
|
-
await replaceIframe(page.content);
|
|
418
|
+
if (page.content) await replaceIframe(page.content, page.isFile);
|
|
419
419
|
} else if (isPublicJwt(jwt)) {
|
|
420
420
|
const config = state.mobileConfig;
|
|
421
421
|
config.role_id = 100;
|
|
@@ -429,7 +429,7 @@
|
|
|
429
429
|
fullWrap: true,
|
|
430
430
|
alerts,
|
|
431
431
|
});
|
|
432
|
-
await replaceIframe(page.content);
|
|
432
|
+
if (page.content) await replaceIframe(page.content, page.isFile);
|
|
433
433
|
} else if (
|
|
434
434
|
(await isPublicEntryPoint(entryPoint)) &&
|
|
435
435
|
state.mobileConfig.autoPublicLogin
|
package/www/js/routes/common.js
CHANGED
|
@@ -158,5 +158,9 @@ const wrapContents = (contents, title, context, req) => {
|
|
|
158
158
|
alerts: prepareAlerts(context, req),
|
|
159
159
|
role: state.mobileConfig.role_id,
|
|
160
160
|
});
|
|
161
|
-
return {
|
|
161
|
+
return {
|
|
162
|
+
content: wrappedContent,
|
|
163
|
+
title: title,
|
|
164
|
+
replaceIframe: context.fullWrap,
|
|
165
|
+
};
|
|
162
166
|
};
|
package/www/js/routes/page.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*global MobileRequest, parseQuery, MobileResponse, wrapContents, saltcorn*/
|
|
1
|
+
/*global MobileRequest, parseQuery, MobileResponse, wrapContents, saltcorn, loadFileAsText*/
|
|
2
2
|
|
|
3
3
|
// post/page/:pagename/action/:rndid
|
|
4
4
|
const postPageAction = async (context) => {
|
|
@@ -37,6 +37,13 @@ const getPage = async (context) => {
|
|
|
37
37
|
const query = parseQuery(context.query);
|
|
38
38
|
const res = new MobileResponse();
|
|
39
39
|
const contents = await page.run(query, { res, req });
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
if (contents.html_file) {
|
|
41
|
+
if (state.mobileConfig?.isOfflineMode)
|
|
42
|
+
throw new Error(req.__("Offline mode: cannot load file"));
|
|
43
|
+
const content = await loadFileAsText(contents.html_file);
|
|
44
|
+
return { content, title: "title", replaceIframe: true, isFile: true };
|
|
45
|
+
} else {
|
|
46
|
+
const title = "title"; // TODO
|
|
47
|
+
return wrapContents(contents, title, context, req);
|
|
48
|
+
}
|
|
42
49
|
};
|
|
@@ -75,6 +75,7 @@ function showAlerts(alerts, toast = true) {
|
|
|
75
75
|
const area = iframe.contentWindow.document.getElementById(
|
|
76
76
|
toast ? "toasts-area" : "top-alert"
|
|
77
77
|
);
|
|
78
|
+
if (!area) return false;
|
|
78
79
|
const successIds = [];
|
|
79
80
|
area.innerHTML = "";
|
|
80
81
|
for (const { type, msg } of alerts) {
|
|
@@ -93,6 +94,7 @@ function showAlerts(alerts, toast = true) {
|
|
|
93
94
|
}, 5000);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
return true;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
function clearTopAlerts() {
|
|
@@ -103,6 +105,37 @@ function clearTopAlerts() {
|
|
|
103
105
|
if (topAlert) topAlert.innerHTML = "";
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
// TODO combine with loadEncodedFile
|
|
109
|
+
async function loadFileAsText(fileId) {
|
|
110
|
+
try {
|
|
111
|
+
const response = await apiCall({
|
|
112
|
+
method: "GET",
|
|
113
|
+
path: `/files/download/${fileId}`,
|
|
114
|
+
responseType: "blob",
|
|
115
|
+
});
|
|
116
|
+
return new Promise((resolve, reject) => {
|
|
117
|
+
const reader = new FileReader();
|
|
118
|
+
reader.onloadend = () => {
|
|
119
|
+
return resolve(reader.result);
|
|
120
|
+
};
|
|
121
|
+
reader.onerror = (error) => {
|
|
122
|
+
return reject(error);
|
|
123
|
+
};
|
|
124
|
+
reader.readAsText(response.data);
|
|
125
|
+
});
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (
|
|
128
|
+
!showAlerts([
|
|
129
|
+
{
|
|
130
|
+
type: "error",
|
|
131
|
+
msg: error.message ? error.message : "An error occured.",
|
|
132
|
+
},
|
|
133
|
+
])
|
|
134
|
+
);
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
106
139
|
async function loadEncodedFile(fileId) {
|
|
107
140
|
try {
|
|
108
141
|
const response = await apiCall({
|
|
@@ -141,11 +174,36 @@ function splitPathQuery(url) {
|
|
|
141
174
|
return { path, query };
|
|
142
175
|
}
|
|
143
176
|
|
|
144
|
-
async function replaceIframe(content) {
|
|
177
|
+
async function replaceIframe(content, isFile = false) {
|
|
178
|
+
const iframe = document.getElementById("content-iframe");
|
|
145
179
|
await write("content.html", `${cordova.file.dataDirectory}`, content);
|
|
146
180
|
const url = await getDirEntry(`${cordova.file.dataDirectory}content.html`);
|
|
147
|
-
const iframe = document.getElementById("content-iframe");
|
|
148
181
|
iframe.src = url.toURL();
|
|
182
|
+
if (isFile) {
|
|
183
|
+
iframe.setAttribute("is-html-file", true);
|
|
184
|
+
await new Promise((resolve, reject) => {
|
|
185
|
+
iframe.onload = () => {
|
|
186
|
+
try {
|
|
187
|
+
const _iframe = document.getElementById("content-iframe");
|
|
188
|
+
const iframeDoc = _iframe.contentWindow.document;
|
|
189
|
+
const baseEl = iframeDoc.createElement("base");
|
|
190
|
+
iframeDoc.head.appendChild(baseEl);
|
|
191
|
+
baseEl.href = "http://localhost";
|
|
192
|
+
const scriptEl = iframeDoc.createElement("script");
|
|
193
|
+
iframeDoc.body.appendChild(scriptEl);
|
|
194
|
+
scriptEl.onload = () => {
|
|
195
|
+
resolve();
|
|
196
|
+
};
|
|
197
|
+
scriptEl.src = "js/utils/iframe_view_utils.js";
|
|
198
|
+
} catch (e) {
|
|
199
|
+
reject(e);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
iframe.onerror = () => {
|
|
203
|
+
reject();
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
} else iframe.setAttribute("is-html-file", false);
|
|
149
207
|
}
|
|
150
208
|
|
|
151
209
|
function addScriptToIframeHead(iframeDoc, script) {
|
|
@@ -227,6 +285,11 @@ function handleOpenModal() {
|
|
|
227
285
|
return result;
|
|
228
286
|
}
|
|
229
287
|
|
|
288
|
+
function isHtmlFile() {
|
|
289
|
+
const iframe = document.getElementById("content-iframe");
|
|
290
|
+
return iframe.getAttribute("is-html-file") === "true";
|
|
291
|
+
}
|
|
292
|
+
|
|
230
293
|
async function handleRoute(route, query, files, data) {
|
|
231
294
|
const mobileConfig = saltcorn.data.state.getState().mobileConfig;
|
|
232
295
|
try {
|
|
@@ -249,6 +312,7 @@ async function handleRoute(route, query, files, data) {
|
|
|
249
312
|
files: files,
|
|
250
313
|
data: data,
|
|
251
314
|
alerts: [],
|
|
315
|
+
fullWrap: isHtmlFile(), // fullWrap when it's currently a fixed-html-file
|
|
252
316
|
});
|
|
253
317
|
if (page.redirect) {
|
|
254
318
|
const { moddalWasOpen, noSubmitReload } = handleOpenModal();
|
|
@@ -270,7 +334,7 @@ async function handleRoute(route, query, files, data) {
|
|
|
270
334
|
}
|
|
271
335
|
} else if (page.content) {
|
|
272
336
|
if (!page.replaceIframe) await replaceIframeInnerContent(page.content);
|
|
273
|
-
else await replaceIframe(page.content);
|
|
337
|
+
else await replaceIframe(page.content, page.isFile);
|
|
274
338
|
} else {
|
|
275
339
|
showAlerts([
|
|
276
340
|
{
|
|
@@ -222,7 +222,7 @@ async function login(e, entryPoint, isSignup) {
|
|
|
222
222
|
fullWrap: true,
|
|
223
223
|
alerts,
|
|
224
224
|
});
|
|
225
|
-
await parent.replaceIframe(page.content);
|
|
225
|
+
if (page.content) await parent.replaceIframe(page.content, page.isFile);
|
|
226
226
|
} else if (loginResult?.alerts) {
|
|
227
227
|
parent.showAlerts(loginResult?.alerts);
|
|
228
228
|
} else {
|
|
@@ -263,7 +263,7 @@ async function publicLogin(entryPoint) {
|
|
|
263
263
|
},
|
|
264
264
|
],
|
|
265
265
|
});
|
|
266
|
-
await parent.replaceIframe(page.content);
|
|
266
|
+
if (page.content) await parent.replaceIframe(page.content, page.isFile);
|
|
267
267
|
} else if (loginResult?.alerts) {
|
|
268
268
|
parent.showAlerts(loginResult?.alerts);
|
|
269
269
|
} else {
|
|
@@ -847,7 +847,7 @@ async function deleteOfflineData(noFeedback) {
|
|
|
847
847
|
}
|
|
848
848
|
|
|
849
849
|
function showLoadSpinner() {
|
|
850
|
-
if ($("#scspinner").length === 0) {
|
|
850
|
+
if (!parent.isHtmlFile() && $("#scspinner").length === 0) {
|
|
851
851
|
$("body").append(`
|
|
852
852
|
<div
|
|
853
853
|
id="scspinner"
|
|
@@ -883,7 +883,7 @@ function showLoadSpinner() {
|
|
|
883
883
|
}
|
|
884
884
|
|
|
885
885
|
function removeLoadSpinner() {
|
|
886
|
-
$("#scspinner").remove();
|
|
886
|
+
if (!parent.isHtmlFile()) $("#scspinner").remove();
|
|
887
887
|
}
|
|
888
888
|
|
|
889
889
|
/**
|