diff options
Diffstat (limited to 'platform/javascript/js/libs/library_godot_os.js')
-rw-r--r-- | platform/javascript/js/libs/library_godot_os.js | 127 |
1 files changed, 124 insertions, 3 deletions
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js index 0f189b013c..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 */ @@ -59,6 +59,8 @@ const GodotConfig = { canvas: null, locale: 'en', canvas_resize_policy: 2, // Adaptive + virtual_keyboard: false, + persistent_drops: false, on_execute: null, on_exit: null, @@ -66,8 +68,13 @@ const GodotConfig = { GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy']; GodotConfig.canvas = p_opts['canvas']; GodotConfig.locale = p_opts['locale'] || GodotConfig.locale; + GodotConfig.virtual_keyboard = p_opts['virtualKeyboard']; + GodotConfig.persistent_drops = !!p_opts['persistentDrops']; GodotConfig.on_execute = p_opts['onExecute']; GodotConfig.on_exit = p_opts['onExit']; + if (p_opts['focusCanvas']) { + GodotConfig.canvas.focus(); + } }, locate_file: function (file) { @@ -77,6 +84,8 @@ const GodotConfig = { GodotConfig.canvas = null; GodotConfig.locale = 'en'; GodotConfig.canvas_resize_policy = 2; + GodotConfig.virtual_keyboard = false; + GodotConfig.persistent_drops = false; GodotConfig.on_execute = null; GodotConfig.on_exit = null; }, @@ -97,7 +106,7 @@ autoAddDeps(GodotConfig, '$GodotConfig'); mergeInto(LibraryManager.library, GodotConfig); const GodotFS = { - $GodotFS__deps: ['$FS', '$IDBFS', '$GodotRuntime'], + $GodotFS__deps: ['$ERRNO_CODES', '$FS', '$IDBFS', '$GodotRuntime'], $GodotFS__postset: [ 'Module["initFS"] = GodotFS.init;', 'Module["copyToFS"] = GodotFS.copy_to_fs;', @@ -298,7 +307,119 @@ const GodotOS = { godot_js_os_hw_concurrency_get: function () { return navigator.hardwareConcurrency || 1; }, + + godot_js_os_download_buffer__sig: 'viiii', + godot_js_os_download_buffer: function (p_ptr, p_size, p_name, p_mime) { + const buf = GodotRuntime.heapSlice(HEAP8, p_ptr, p_size); + const name = GodotRuntime.parseString(p_name); + const mime = GodotRuntime.parseString(p_mime); + const blob = new Blob([buf], { type: mime }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = name; + a.style.display = 'none'; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }, }; autoAddDeps(GodotOS, '$GodotOS'); mergeInto(LibraryManager.library, GodotOS); + +/* + * Godot event listeners. + * Keeps track of registered event listeners so it can remove them on shutdown. + */ +const GodotEventListeners = { + $GodotEventListeners__deps: ['$GodotOS'], + $GodotEventListeners__postset: 'GodotOS.atexit(function(resolve, reject) { GodotEventListeners.clear(); resolve(); });', + $GodotEventListeners: { + handlers: [], + + has: function (target, event, method, capture) { + return GodotEventListeners.handlers.findIndex(function (e) { + return e.target === target && e.event === event && e.method === method && e.capture === capture; + }) !== -1; + }, + + add: function (target, event, method, capture) { + if (GodotEventListeners.has(target, event, method, capture)) { + return; + } + function Handler(p_target, p_event, p_method, p_capture) { + this.target = p_target; + this.event = p_event; + this.method = p_method; + this.capture = p_capture; + } + GodotEventListeners.handlers.push(new Handler(target, event, method, capture)); + target.addEventListener(event, method, capture); + }, + + clear: function () { + GodotEventListeners.handlers.forEach(function (h) { + h.target.removeEventListener(h.event, h.method, h.capture); + }); + GodotEventListeners.handlers.length = 0; + }, + }, +}; +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); |