summaryrefslogtreecommitdiff
path: root/platform/javascript/js
diff options
context:
space:
mode:
Diffstat (limited to 'platform/javascript/js')
-rw-r--r--platform/javascript/js/engine/config.js10
-rw-r--r--platform/javascript/js/engine/engine.js3
-rw-r--r--platform/javascript/js/libs/audio.worklet.js4
-rw-r--r--platform/javascript/js/libs/library_godot_audio.js4
-rw-r--r--platform/javascript/js/libs/library_godot_display.js95
-rw-r--r--platform/javascript/js/libs/library_godot_fetch.js4
-rw-r--r--platform/javascript/js/libs/library_godot_input.js32
-rw-r--r--platform/javascript/js/libs/library_godot_javascript_singleton.js4
-rw-r--r--platform/javascript/js/libs/library_godot_os.js59
-rw-r--r--platform/javascript/js/libs/library_godot_runtime.js4
10 files changed, 196 insertions, 23 deletions
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
index ba61b14eb7..2e5e1ed0d1 100644
--- a/platform/javascript/js/engine/config.js
+++ b/platform/javascript/js/engine/config.js
@@ -107,6 +107,13 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
*/
experimentalVK: false,
/**
+ * The progressive web app service worker to install.
+ * @memberof EngineConfig
+ * @default
+ * @type {string}
+ */
+ serviceWorker: '',
+ /**
* @ignore
* @type {Array.<string>}
*/
@@ -225,6 +232,8 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
*/
Config.prototype.update = function (opts) {
const config = opts || {};
+ // NOTE: We must explicitly pass the default, accessing it via
+ // the key will fail due to closure compiler renames.
function parse(key, def) {
if (typeof (config[key]) === 'undefined') {
return def;
@@ -247,6 +256,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
this.persistentDrops = parse('persistentDrops', this.persistentDrops);
this.experimentalVK = parse('experimentalVK', this.experimentalVK);
this.focusCanvas = parse('focusCanvas', this.focusCanvas);
+ this.serviceWorker = parse('serviceWorker', this.serviceWorker);
this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
this.fileSizes = parse('fileSizes', this.fileSizes);
this.args = parse('args', this.args);
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 17a8df9e29..d2ba595083 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -189,6 +189,9 @@ const Engine = (function () {
preloader.preloadedFiles.length = 0; // Clear memory
me.rtenv['callMain'](me.config.args);
initPromise = null;
+ if (me.config.serviceWorker && 'serviceWorker' in navigator) {
+ navigator.serviceWorker.register(me.config.serviceWorker);
+ }
resolve();
});
});
diff --git a/platform/javascript/js/libs/audio.worklet.js b/platform/javascript/js/libs/audio.worklet.js
index 52b3aedf8c..ea4d8cb221 100644
--- a/platform/javascript/js/libs/audio.worklet.js
+++ b/platform/javascript/js/libs/audio.worklet.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js
index 6cbb0567f4..756c1ac595 100644
--- a/platform/javascript/js/libs/library_godot_audio.js
+++ b/platform/javascript/js/libs/library_godot_audio.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 2689f1c22c..5997631bf8 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -330,6 +330,91 @@ const GodotDisplay = {
return 0;
},
+ godot_js_tts_is_speaking__sig: 'i',
+ godot_js_tts_is_speaking: function () {
+ return window.speechSynthesis.speaking;
+ },
+
+ godot_js_tts_is_paused__sig: 'i',
+ godot_js_tts_is_paused: function () {
+ return window.speechSynthesis.paused;
+ },
+
+ godot_js_tts_get_voices__sig: 'vi',
+ godot_js_tts_get_voices: function (p_callback) {
+ const func = GodotRuntime.get_func(p_callback);
+ try {
+ const arr = [];
+ const voices = window.speechSynthesis.getVoices();
+ for (let i = 0; i < voices.length; i++) {
+ arr.push(`${voices[i].lang};${voices[i].name}`);
+ }
+ const c_ptr = GodotRuntime.allocStringArray(arr);
+ func(arr.length, c_ptr);
+ GodotRuntime.freeStringArray(c_ptr, arr.length);
+ } catch (e) {
+ // Fail graciously.
+ }
+ },
+
+ godot_js_tts_speak__sig: 'viiiffii',
+ godot_js_tts_speak: function (p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback) {
+ const func = GodotRuntime.get_func(p_callback);
+
+ function listener_end(evt) {
+ evt.currentTarget.cb(1 /*TTS_UTTERANCE_ENDED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_start(evt) {
+ evt.currentTarget.cb(0 /*TTS_UTTERANCE_STARTED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_error(evt) {
+ evt.currentTarget.cb(2 /*TTS_UTTERANCE_CANCELED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_bound(evt) {
+ evt.currentTarget.cb(3 /*TTS_UTTERANCE_BOUNDARY*/, evt.currentTarget.id, evt.charIndex);
+ }
+
+ const utterance = new SpeechSynthesisUtterance(GodotRuntime.parseString(p_text));
+ utterance.rate = p_rate;
+ utterance.pitch = p_pitch;
+ utterance.volume = p_volume / 100.0;
+ utterance.addEventListener('end', listener_end);
+ utterance.addEventListener('start', listener_start);
+ utterance.addEventListener('error', listener_error);
+ utterance.addEventListener('boundary', listener_bound);
+ utterance.id = p_utterance_id;
+ utterance.cb = func;
+ const voice = GodotRuntime.parseString(p_voice);
+ const voices = window.speechSynthesis.getVoices();
+ for (let i = 0; i < voices.length; i++) {
+ if (voices[i].name === voice) {
+ utterance.voice = voices[i];
+ break;
+ }
+ }
+ window.speechSynthesis.resume();
+ window.speechSynthesis.speak(utterance);
+ },
+
+ godot_js_tts_pause__sig: 'v',
+ godot_js_tts_pause: function () {
+ window.speechSynthesis.pause();
+ },
+
+ godot_js_tts_resume__sig: 'v',
+ godot_js_tts_resume: function () {
+ window.speechSynthesis.resume();
+ },
+
+ godot_js_tts_stop__sig: 'v',
+ godot_js_tts_stop: function () {
+ window.speechSynthesis.cancel();
+ window.speechSynthesis.resume();
+ },
+
godot_js_display_alert__sig: 'vi',
godot_js_display_alert: function (p_text) {
window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
@@ -377,6 +462,7 @@ const GodotDisplay = {
GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32');
},
+ godot_js_display_window_size_get__sig: 'vii',
godot_js_display_window_size_get: function (p_width, p_height) {
GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32');
GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32');
@@ -625,6 +711,11 @@ const GodotDisplay = {
return GodotDisplayVK.available();
},
+ godot_js_display_tts_available__sig: 'i',
+ godot_js_display_tts_available: function () {
+ return 'speechSynthesis' in window;
+ },
+
godot_js_display_vk_cb__sig: 'vi',
godot_js_display_vk_cb: function (p_input_cb) {
const input_cb = GodotRuntime.get_func(p_input_cb);
diff --git a/platform/javascript/js/libs/library_godot_fetch.js b/platform/javascript/js/libs/library_godot_fetch.js
index 615f9de8b0..285e50a035 100644
--- a/platform/javascript/js/libs/library_godot_fetch.js
+++ b/platform/javascript/js/libs/library_godot_fetch.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js
index 587c320f35..1e64c260f8 100644
--- a/platform/javascript/js/libs/library_godot_input.js
+++ b/platform/javascript/js/libs/library_godot_input.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -87,7 +87,7 @@ const GodotInputGamepads = {
},
init: function (onchange) {
- GodotEventListeners.samples = [];
+ GodotInputGamepads.samples = [];
function add(pad) {
const guid = GodotInputGamepads.get_guid(pad);
const c_id = GodotRuntime.allocString(pad.id);
@@ -104,10 +104,14 @@ const GodotInputGamepads = {
}
}
GodotEventListeners.add(window, 'gamepadconnected', function (evt) {
- add(evt.gamepad);
+ if (evt.gamepad) {
+ add(evt.gamepad);
+ }
}, false);
GodotEventListeners.add(window, 'gamepaddisconnected', function (evt) {
- onchange(evt.gamepad.index, 0);
+ if (evt.gamepad) {
+ onchange(evt.gamepad.index, 0);
+ }
}, false);
},
@@ -258,7 +262,7 @@ const GodotInputDragDrop = {
const DROP = `/tmp/drop-${parseInt(Math.random() * (1 << 30), 10)}/`;
const drops = [];
const files = [];
- FS.mkdir(DROP);
+ FS.mkdir(DROP.slice(0, -1)); // Without trailing slash
GodotInputDragDrop.pending_files.forEach((elem) => {
const path = elem['path'];
GodotFS.copy_to_fs(DROP + path, elem['data']);
@@ -389,6 +393,11 @@ const GodotInput = {
const rect = canvas.getBoundingClientRect();
const pos = GodotInput.computePosition(evt, rect);
const modifiers = GodotInput.getModifiers(evt);
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (p_pressed) {
+ GodotConfig.canvas.focus();
+ }
if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) {
evt.preventDefault();
}
@@ -405,14 +414,19 @@ const GodotInput = {
const func = GodotRuntime.get_func(callback);
const canvas = GodotConfig.canvas;
function touch_cb(type, evt) {
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (type === 0) {
+ GodotConfig.canvas.focus();
+ }
const rect = canvas.getBoundingClientRect();
const touches = evt.changedTouches;
for (let i = 0; i < touches.length; i++) {
const touch = touches[i];
const pos = GodotInput.computePosition(touch, rect);
- GodotRuntime.setHeapValue(coords + (i * 2), pos[0], 'double');
- GodotRuntime.setHeapValue(coords + (i * 2 + 8), pos[1], 'double');
- GodotRuntime.setHeapValue(ids + i, touch.identifier, 'i32');
+ GodotRuntime.setHeapValue(coords + (i * 2) * 8, pos[0], 'double');
+ GodotRuntime.setHeapValue(coords + (i * 2 + 1) * 8, pos[1], 'double');
+ GodotRuntime.setHeapValue(ids + i * 4, touch.identifier, 'i32');
}
func(type, touches.length);
if (evt.cancelable) {
diff --git a/platform/javascript/js/libs/library_godot_javascript_singleton.js b/platform/javascript/js/libs/library_godot_javascript_singleton.js
index 22ce003cd2..692f27676a 100644
--- a/platform/javascript/js/libs/library_godot_javascript_singleton.js
+++ b/platform/javascript/js/libs/library_godot_javascript_singleton.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index c552e99415..12d06a8d51 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -368,3 +368,58 @@ const GodotEventListeners = {
},
};
mergeInto(LibraryManager.library, GodotEventListeners);
+
+const GodotPWA = {
+
+ $GodotPWA__deps: ['$GodotRuntime', '$GodotEventListeners'],
+ $GodotPWA: {
+ hasUpdate: false,
+
+ updateState: function (cb, reg) {
+ if (!reg) {
+ return;
+ }
+ if (!reg.active) {
+ return;
+ }
+ if (reg.waiting) {
+ GodotPWA.hasUpdate = true;
+ cb();
+ }
+ GodotEventListeners.add(reg, 'updatefound', function () {
+ const installing = reg.installing;
+ GodotEventListeners.add(installing, 'statechange', function () {
+ if (installing.state === 'installed') {
+ GodotPWA.hasUpdate = true;
+ cb();
+ }
+ });
+ });
+ },
+ },
+
+ godot_js_pwa_cb__sig: 'vi',
+ godot_js_pwa_cb: function (p_update_cb) {
+ if ('serviceWorker' in navigator) {
+ const cb = GodotRuntime.get_func(p_update_cb);
+ navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb));
+ }
+ },
+
+ godot_js_pwa_update__sig: 'i',
+ godot_js_pwa_update: function () {
+ if ('serviceWorker' in navigator && GodotPWA.hasUpdate) {
+ navigator.serviceWorker.getRegistration().then(function (reg) {
+ if (!reg || !reg.waiting) {
+ return;
+ }
+ reg.waiting.postMessage('update');
+ });
+ return 0;
+ }
+ return 1;
+ },
+};
+
+autoAddDeps(GodotPWA, '$GodotPWA');
+mergeInto(LibraryManager.library, GodotPWA);
diff --git a/platform/javascript/js/libs/library_godot_runtime.js b/platform/javascript/js/libs/library_godot_runtime.js
index 3da1ed8f06..e2f7c8dca6 100644
--- a/platform/javascript/js/libs/library_godot_runtime.js
+++ b/platform/javascript/js/libs/library_godot_runtime.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */