html2apk 0.4.0 → 0.5.0
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/README.md +88 -10
- package/examples/minimal/dist/MeuApp-1.0.0-debug.apk +0 -0
- package/package.json +1 -1
- package/src/core/build-apk.js +18 -7
- package/src/desktop/renderer/renderer.js +93 -8
- package/src/templates/cordova-plugin-html2apk-bridge/plugin.xml +2 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/Html2ApkBridge.java +176 -32
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/NotificationClickReceiver.java +28 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/NotificationReceiver.java +1 -1
- package/src/templates/cordova-plugin-html2apk-bridge/www/html2apk-bridge.js +278 -11
- package/src/templates/html2apk-early-bridge.js +860 -0
package/src/templates/cordova-plugin-html2apk-bridge/src/android/NotificationClickReceiver.java
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package dev.html2apk.bridge;
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
|
|
7
|
+
import androidx.core.app.NotificationManagerCompat;
|
|
8
|
+
|
|
9
|
+
import org.json.JSONObject;
|
|
10
|
+
|
|
11
|
+
public class NotificationClickReceiver extends BroadcastReceiver {
|
|
12
|
+
@Override
|
|
13
|
+
public void onReceive(Context context, Intent intent) {
|
|
14
|
+
if (intent == null || !intent.getBooleanExtra(Html2ApkBridge.EXTRA_NOTIFICATION_CLICKED, false)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
JSONObject detail;
|
|
19
|
+
try {
|
|
20
|
+
detail = new JSONObject(intent.getStringExtra(Html2ApkBridge.EXTRA_NOTIFICATION_DETAIL));
|
|
21
|
+
} catch (Exception ignored) {
|
|
22
|
+
detail = new JSONObject();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Html2ApkBridge.handleNotificationClickBroadcast(context, detail);
|
|
26
|
+
NotificationManagerCompat.from(context).cancel(detail.optInt("id", 0));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -58,7 +58,7 @@ public class NotificationReceiver extends BroadcastReceiver {
|
|
|
58
58
|
.setContentText(text)
|
|
59
59
|
.setStyle(new NotificationCompat.BigTextStyle().bigText(text))
|
|
60
60
|
.setAutoCancel(true)
|
|
61
|
-
.setContentIntent(Html2ApkBridge.
|
|
61
|
+
.setContentIntent(Html2ApkBridge.createNotificationClickIntent(context, id, detail))
|
|
62
62
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
|
63
63
|
|
|
64
64
|
Html2ApkBridge.addNotificationActions(builder, context, id, displayOptions);
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var exec = require("cordova/exec");
|
|
4
|
+
var channel = require("cordova/channel");
|
|
4
5
|
|
|
5
6
|
var notificationListeners = [];
|
|
6
7
|
var eventListeners = {};
|
|
7
8
|
var initialNotification = null;
|
|
8
9
|
var initialLink = null;
|
|
9
10
|
var scheduledNotificationCounter = 0;
|
|
11
|
+
var notificationActionCounter = 0;
|
|
12
|
+
var notificationActionCallbacks = {};
|
|
10
13
|
var deviceReady = typeof document === "undefined";
|
|
11
14
|
var deviceReadyCallbacks = [];
|
|
12
15
|
var eventAliases = {
|
|
@@ -48,14 +51,186 @@ if (typeof document !== "undefined") {
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
function call(action, args) {
|
|
51
|
-
return
|
|
54
|
+
return whenCordovaBridgeReady().then(function () {
|
|
52
55
|
return new Promise(function (resolve, reject) {
|
|
53
|
-
|
|
56
|
+
try {
|
|
57
|
+
exec(resolve, reject, "Html2ApkBridge", action, args || []);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
reject(error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function whenCordovaBridgeReady() {
|
|
66
|
+
var timer;
|
|
67
|
+
|
|
68
|
+
if (!channel || !channel.onCordovaReady || channel.onCordovaReady.state === 2) {
|
|
69
|
+
return Promise.resolve();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return new Promise(function (resolve, reject) {
|
|
73
|
+
timer = setTimeout(function () {
|
|
74
|
+
reject(new Error("html2apk native bridge is not ready. Make sure cordova.js finished loading."));
|
|
75
|
+
}, 10000);
|
|
76
|
+
|
|
77
|
+
channel.onCordovaReady.subscribe(function () {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
resolve();
|
|
54
80
|
});
|
|
55
81
|
});
|
|
56
82
|
}
|
|
57
83
|
|
|
84
|
+
function asyncThrow(error) {
|
|
85
|
+
setTimeout(function () {
|
|
86
|
+
throw error;
|
|
87
|
+
}, 0);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function cloneSerializable(value) {
|
|
91
|
+
var output;
|
|
92
|
+
|
|
93
|
+
if (typeof value === "function" || typeof value === "undefined") {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
if (value === null || typeof value !== "object") {
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
output = [];
|
|
101
|
+
value.forEach(function (item) {
|
|
102
|
+
var cloned = cloneSerializable(item);
|
|
103
|
+
if (typeof cloned !== "undefined") {
|
|
104
|
+
output.push(cloned);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return output;
|
|
108
|
+
}
|
|
109
|
+
if (value instanceof Date) {
|
|
110
|
+
return value.toISOString();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
output = {};
|
|
114
|
+
Object.keys(value).forEach(function (key) {
|
|
115
|
+
var cloned = cloneSerializable(value[key]);
|
|
116
|
+
if (typeof cloned !== "undefined") {
|
|
117
|
+
output[key] = cloned;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return output;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function registerNotificationAction(handler, source) {
|
|
124
|
+
var id = "html2apk-click-" + Date.now() + "-" + (++notificationActionCounter);
|
|
125
|
+
notificationActionCallbacks[id] = function (detail) {
|
|
126
|
+
return handler(detail, source || {});
|
|
127
|
+
};
|
|
128
|
+
return id;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function normalizeNotificationClick(click) {
|
|
132
|
+
var normalized;
|
|
133
|
+
var callbackId;
|
|
134
|
+
var actionHandler;
|
|
135
|
+
var functionName;
|
|
136
|
+
|
|
137
|
+
if (typeof click === "function") {
|
|
138
|
+
callbackId = registerNotificationAction(click);
|
|
139
|
+
return {
|
|
140
|
+
action: "run-function",
|
|
141
|
+
acao: "executar-funcao",
|
|
142
|
+
callbackId: callbackId
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!click || typeof click !== "object") {
|
|
147
|
+
return {
|
|
148
|
+
action: "open-app",
|
|
149
|
+
acao: "abrir-app"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
normalized = cloneSerializable(click) || {};
|
|
154
|
+
actionHandler = click.acao || click.action;
|
|
155
|
+
if (typeof actionHandler === "function") {
|
|
156
|
+
callbackId = registerNotificationAction(actionHandler, click);
|
|
157
|
+
normalized.callbackId = callbackId;
|
|
158
|
+
normalized.action = normalized.action || "run-function";
|
|
159
|
+
normalized.acao = normalized.acao || "executar-funcao";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
functionName = normalized.funcao || normalized.functionName || normalized.function || normalized.fn || normalized.nomeFuncao;
|
|
163
|
+
if (typeof functionName === "string" && functionName.trim()) {
|
|
164
|
+
normalized.funcao = functionName.trim();
|
|
165
|
+
normalized.functionName = normalized.funcao;
|
|
166
|
+
normalized.action = normalized.action || "run-function";
|
|
167
|
+
normalized.acao = normalized.acao || "executar-funcao";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (normalized.action && !normalized.acao) {
|
|
171
|
+
normalized.acao = normalized.action;
|
|
172
|
+
}
|
|
173
|
+
if (normalized.acao && !normalized.action) {
|
|
174
|
+
normalized.action = normalized.acao;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return normalized;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function notificationOpenValue(source) {
|
|
181
|
+
if (!source || typeof source !== "object") {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
if (Object.prototype.hasOwnProperty.call(source, "open")) {
|
|
185
|
+
return source.open !== false;
|
|
186
|
+
}
|
|
187
|
+
if (Object.prototype.hasOwnProperty.call(source, "abrir")) {
|
|
188
|
+
return source.abrir !== false;
|
|
189
|
+
}
|
|
190
|
+
if (Object.prototype.hasOwnProperty.call(source, "abrirApp")) {
|
|
191
|
+
return source.abrirApp !== false;
|
|
192
|
+
}
|
|
193
|
+
if (Object.prototype.hasOwnProperty.call(source, "openApp")) {
|
|
194
|
+
return source.openApp !== false;
|
|
195
|
+
}
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function normalizeNotificationActions(actions) {
|
|
200
|
+
if (!Array.isArray(actions)) {
|
|
201
|
+
return actions;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return actions.map(function (action) {
|
|
205
|
+
var normalized = cloneSerializable(action) || {};
|
|
206
|
+
var click = action && (action.aoClicar || action.onClick);
|
|
207
|
+
if (!click && action && (
|
|
208
|
+
typeof action.funcao === "string" ||
|
|
209
|
+
typeof action.functionName === "string" ||
|
|
210
|
+
typeof action.fn === "string"
|
|
211
|
+
)) {
|
|
212
|
+
click = action;
|
|
213
|
+
}
|
|
214
|
+
if (click) {
|
|
215
|
+
normalized.aoClicar = normalizeNotificationClick(click);
|
|
216
|
+
normalized.onClick = normalized.aoClicar;
|
|
217
|
+
}
|
|
218
|
+
if (typeof notificationOpenValue(action) !== "undefined") {
|
|
219
|
+
normalized.open = notificationOpenValue(action);
|
|
220
|
+
if (normalized.aoClicar && typeof normalized.aoClicar.open === "undefined") {
|
|
221
|
+
normalized.aoClicar.open = normalized.open;
|
|
222
|
+
normalized.onClick = normalized.aoClicar;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return normalized;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
58
229
|
function normalizeNotificationOptions(messageOrOptions) {
|
|
230
|
+
var options;
|
|
231
|
+
var click;
|
|
232
|
+
var actions;
|
|
233
|
+
|
|
59
234
|
if (typeof messageOrOptions === "string") {
|
|
60
235
|
return {
|
|
61
236
|
title: "Notificacao",
|
|
@@ -66,12 +241,23 @@ function normalizeNotificationOptions(messageOrOptions) {
|
|
|
66
241
|
};
|
|
67
242
|
}
|
|
68
243
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
244
|
+
options = cloneSerializable(messageOrOptions || {}) || {};
|
|
245
|
+
click = messageOrOptions && (messageOrOptions.aoClicar || messageOrOptions.onClick);
|
|
246
|
+
options.onClick = normalizeNotificationClick(click);
|
|
247
|
+
options.aoClicar = options.onClick;
|
|
248
|
+
if (typeof notificationOpenValue(messageOrOptions) !== "undefined") {
|
|
249
|
+
options.open = notificationOpenValue(messageOrOptions);
|
|
250
|
+
options.abrir = options.open;
|
|
251
|
+
options.onClick.open = options.open;
|
|
252
|
+
options.aoClicar.open = options.open;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
actions = normalizeNotificationActions(messageOrOptions && (messageOrOptions.acoes || messageOrOptions.actions));
|
|
256
|
+
if (Array.isArray(actions)) {
|
|
257
|
+
options.acoes = actions;
|
|
258
|
+
options.actions = actions;
|
|
74
259
|
}
|
|
260
|
+
|
|
75
261
|
return options;
|
|
76
262
|
}
|
|
77
263
|
|
|
@@ -183,17 +369,98 @@ function normalizeEventType(type) {
|
|
|
183
369
|
}
|
|
184
370
|
|
|
185
371
|
function emitNotificationClick(detail) {
|
|
372
|
+
var notification = detail || null;
|
|
186
373
|
initialNotification = detail || null;
|
|
187
374
|
|
|
188
375
|
notificationListeners.slice().forEach(function (listener) {
|
|
189
376
|
try {
|
|
190
|
-
listener(
|
|
377
|
+
listener(notification);
|
|
191
378
|
} catch (error) {
|
|
192
|
-
|
|
193
|
-
throw error;
|
|
194
|
-
}, 0);
|
|
379
|
+
asyncThrow(error);
|
|
195
380
|
}
|
|
196
381
|
});
|
|
382
|
+
|
|
383
|
+
executeNotificationClickAction(notification);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function notificationActionFromDetail(detail) {
|
|
387
|
+
var action;
|
|
388
|
+
|
|
389
|
+
if (!detail || typeof detail !== "object") {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
action = detail.action || detail.acao;
|
|
394
|
+
if (action && typeof action === "object") {
|
|
395
|
+
if (action.callbackId || action.functionName || action.funcao || action.fn || action.nomeFuncao) {
|
|
396
|
+
return action;
|
|
397
|
+
}
|
|
398
|
+
if (action.aoClicar || action.onClick) {
|
|
399
|
+
return action.aoClicar || action.onClick;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return detail.aoClicar || detail.onClick || null;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function notificationActionArgs(action, detail) {
|
|
407
|
+
var args = action && (
|
|
408
|
+
action.argumentos ||
|
|
409
|
+
action.args ||
|
|
410
|
+
action.parametros ||
|
|
411
|
+
action.params ||
|
|
412
|
+
action.parameters
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
if (typeof args === "undefined") {
|
|
416
|
+
return action && (action.passarEvento === false || action.passEvent === false) ? [] : [detail];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return Array.isArray(args) ? args : [args];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function handleActionResult(result) {
|
|
423
|
+
if (result && typeof result.then === "function") {
|
|
424
|
+
result.catch(asyncThrow);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function executeNotificationClickAction(detail) {
|
|
429
|
+
var action = notificationActionFromDetail(detail);
|
|
430
|
+
var callbackId = action && (action.callbackId || action.idCallback || action.callback);
|
|
431
|
+
var functionName;
|
|
432
|
+
var handler;
|
|
433
|
+
var args;
|
|
434
|
+
|
|
435
|
+
if (!action || typeof action !== "object") {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (detail && detail.__html2apkActionHandled) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (callbackId && notificationActionCallbacks[callbackId]) {
|
|
443
|
+
detail.__html2apkActionHandled = true;
|
|
444
|
+
handleActionResult(notificationActionCallbacks[callbackId](detail));
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
functionName = action.funcao || action.functionName || action.function || action.fn || action.nomeFuncao;
|
|
449
|
+
if (!functionName) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
handler = api && api[functionName];
|
|
454
|
+
if (typeof handler !== "function" && typeof window !== "undefined") {
|
|
455
|
+
handler = window[functionName];
|
|
456
|
+
}
|
|
457
|
+
if (typeof handler !== "function") {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
args = notificationActionArgs(action, detail);
|
|
462
|
+
detail.__html2apkActionHandled = true;
|
|
463
|
+
handleActionResult(handler.apply(typeof window === "undefined" ? null : window, args));
|
|
197
464
|
}
|
|
198
465
|
|
|
199
466
|
function emitEvent(type, detail) {
|