Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] [HTML5] Add easy to use download API. #48929

Merged
merged 1 commit into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doc/classes/JavaScript.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@
Creates a new JavaScript object using the [code]new[/code] constructor. The [code]object[/code] must a valid property of the JavaScript [code]window[/code]. See [JavaScriptObject] for usage.
</description>
</method>
<method name="download_buffer">
<return type="void">
</return>
<argument index="0" name="buffer" type="PoolByteArray">
</argument>
<argument index="1" name="name" type="String">
</argument>
<argument index="2" name="mime" type="String" default="&quot;application/octet-stream&quot;">
</argument>
<description>
Prompts the user to download a file containing the specified [code]buffer[/code]. The file will have the given [code]name[/code] and [code]mime[/code] type.
[b]Note:[/b] The browser may override the [url=https://en.wikipedia.org/wiki/Media_type]MIME type[/url] provided based on the file [code]name[/code]'s extension.
[b]Note:[/b] Browsers might block the download if [method download_buffer] is not being called from a user interaction (e.g. button click).
[b]Note:[/b] Browsers might ask the user for permission or block the download if multiple download requests are made in a quick succession.
</description>
</method>
<method name="eval">
<return type="Variant">
</return>
Expand Down
2 changes: 0 additions & 2 deletions platform/javascript/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ sys_env.AddJSLibraries(
]
)

if env["tools"]:
sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
if env["javascript_eval"]:
sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"])

Expand Down
5 changes: 5 additions & 0 deletions platform/javascript/api/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void JavaScript::_bind_methods() {
mi.arguments.push_back(PropertyInfo(Variant::STRING, "object"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "create_object", &JavaScript::_create_object_bind, mi);
}
ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScript::download_buffer, DEFVAL("application/octet-stream"));
}

#if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED)
Expand Down Expand Up @@ -100,3 +101,7 @@ Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount,
return Ref<JavaScriptObject>();
}
#endif
#if !defined(JAVASCRIPT_ENABLED)
void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) {
}
#endif
1 change: 1 addition & 0 deletions platform/javascript/api/javascript_singleton.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class JavaScript : public Object {
Ref<JavaScriptObject> get_interface(const String &p_interface);
Ref<JavaScriptObject> create_callback(Object *p_ref, const StringName &p_method);
Variant _create_object_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream");

static JavaScript *get_singleton();
JavaScript();
Expand Down
9 changes: 7 additions & 2 deletions platform/javascript/api/javascript_tools_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

// JavaScript functions defined in library_godot_editor_tools.js
extern "C" {
extern void godot_js_editor_download_file(const char *p_path, const char *p_name, const char *p_mime);
extern int godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime);
}

static void _javascript_editor_init_callback() {
Expand Down Expand Up @@ -70,7 +70,12 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) {
String base_path = resource_path.substr(0, resource_path.rfind("/")) + "/";
_zip_recursive(resource_path, base_path, zip);
zipClose(zip, NULL);
godot_js_editor_download_file("/tmp/project.zip", "project.zip", "application/zip");
FileAccess *f = FileAccess::open("/tmp/project.zip", FileAccess::READ);
ERR_FAIL_COND_MSG(!f, "Unable to create zip file");
Vector<uint8_t> buf;
buf.resize(f->get_len());
f->get_buffer(buf.ptrw(), buf.size());
godot_js_os_download_buffer(buf.ptr(), buf.size(), "project.zip", "application/zip");
}

void JavaScriptToolsEditorPlugin::_bind_methods() {
Expand Down
5 changes: 5 additions & 0 deletions platform/javascript/javascript_singleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ union js_eval_ret {
};

extern int godot_js_eval(const char *p_js, int p_use_global_ctx, union js_eval_ret *p_union_ptr, void *p_byte_arr, void *p_byte_arr_write, void *(*p_callback)(void *p_ptr, void *p_ptr2, int p_len));
extern int godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime);
}

void *resize_poolbytearray_and_open_write(void *p_arr, void *r_write, int p_len) {
Expand Down Expand Up @@ -338,3 +339,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
}

#endif // JAVASCRIPT_EVAL_ENABLED

void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) {
godot_js_os_download_buffer(p_arr.ptr(), p_arr.size(), p_name.utf8().get_data(), p_mime.utf8().get_data());
}
57 changes: 0 additions & 57 deletions platform/javascript/js/libs/library_godot_editor_tools.js

This file was deleted.

17 changes: 17 additions & 0 deletions platform/javascript/js/libs/library_godot_os.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,23 @@ 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');
Expand Down