Composer.WebView: Convert to using messages for JS → client comms

This commit is contained in:
Michael Gratton 2020-08-28 11:38:06 +10:00 committed by Michael James Gratton
parent fb96676fbd
commit 3655f4896f
2 changed files with 42 additions and 45 deletions

View file

@ -33,8 +33,8 @@ public class Composer.WebView : Components.WebView {
private const string SPACER = "<div><br /></div>";
// WebKit message handler names
private const string CURSOR_CONTEXT_CHANGED = "cursorContextChanged";
private const string DRAG_DROP_RECEIVED = "dragDropReceived";
private const string CURSOR_CONTEXT_CHANGED = "cursor_context_changed";
private const string DRAG_DROP_RECEIVED = "drag_drop_received";
/**
* Encapsulates editing-related state for a specific DOM node.
@ -152,8 +152,8 @@ public class Composer.WebView : Components.WebView {
this.user_content_manager.add_style_sheet(WebView.app_style);
this.user_content_manager.add_script(WebView.app_script);
register_message_handler(CURSOR_CONTEXT_CHANGED, on_cursor_context_changed);
register_message_handler(DRAG_DROP_RECEIVED, on_drag_drop_received);
register_message_callback(CURSOR_CONTEXT_CHANGED, on_cursor_context_changed);
register_message_callback(DRAG_DROP_RECEIVED, on_drag_drop_received);
// XXX this is a bit of a hack given the docs for is_empty,
// above
@ -530,50 +530,43 @@ public class Composer.WebView : Components.WebView {
return ret;
}
private void on_cursor_context_changed(WebKit.JavascriptResult result) {
try {
cursor_context_changed(
new EditContext(Util.JS.to_string(result.get_js_value()))
);
} catch (Util.JS.Error err) {
debug("Could not get text cursor style: %s", err.message);
private void on_cursor_context_changed(GLib.Variant? parameters) {
if (parameters != null && parameters.classify() == STRING) {
cursor_context_changed(new EditContext(parameters as string));
} else {
warning("Could not get text cursor style");
}
}
/**
* Handle a dropped image
*/
private void on_drag_drop_received(WebKit.JavascriptResult result) {
private void on_drag_drop_received(GLib.Variant? parameters) {
var dict = new GLib.VariantDict(parameters);
string file_name = dict.lookup_value(
"fileName", GLib.VariantType.STRING
).get_string();
string file_name_unescaped = GLib.Uri.unescape_string(file_name);
try {
JSC.Value object = result.get_js_value();
string filename = Util.JS.to_string(
Util.JS.get_property(object, "fileName")
);
string filename_unescaped = GLib.Uri.unescape_string(filename);
string file_type = dict.lookup_value(
"fileType", GLib.VariantType.STRING
).get_string();
string file_type = Util.JS.to_string(
Util.JS.get_property(object, "fileType")
);
string content_base64 = dict.lookup_value(
"content", GLib.VariantType.STRING
).get_string();
uint8[] image = GLib.Base64.decode(content_base64);
string content_base64 = Util.JS.to_string(
Util.JS.get_property(object, "content")
);
uint8[] image = GLib.Base64.decode(content_base64);
if (image.length == 0) {
warning("%s is empty", file_name);
return;
}
if (image.length == 0) {
warning("%s is empty", filename);
return;
}
// A simple check to see if the file looks like an image. A problem here
// will be this accepting types which won't be supported by WebKit
// or recipients.
if (file_type.index_of("image/") == 0) {
image_file_dropped(filename_unescaped, file_type, image);
}
} catch (Util.JS.Error err) {
debug("Could not get deceptive link param: %s", err.message);
// A simple check to see if the file looks like an image. A problem here
// will be this accepting types which won't be supported by WebKit
// or recipients.
if (file_type.index_of("image/") == 0) {
image_file_dropped(file_name_unescaped, file_type, image);
}
}
}

View file

@ -1,6 +1,6 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
* Copyright 2016 Michael Gratton <mike@vee.net>
* Copyright © 2016 Software Freedom Conservancy Inc.
* Copyright © 2016-2020 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
@ -35,6 +35,9 @@ ComposerPageState.prototype = {
this.nextSelectionId = 0;
this.cursorContext = null;
this._cursorContextChanged = MessageSender("cursor_context_changed");
this._dragDropReceived = MessageSender("drag_drop_received");
document.addEventListener("click", function(e) {
if (e.target.tagName == "A") {
e.preventDefault();
@ -99,7 +102,9 @@ ComposerPageState.prototype = {
}, true);
// Handle file drag & drop
document.body.addEventListener("drop", state.handleFileDrop, true);
document.body.addEventListener("drop", function(e) {
state.handleFileDrop(e);
}, true);
document.body.addEventListener("allowDrop", function(e) {
ev.preventDefault();
}, true);
@ -346,9 +351,7 @@ ComposerPageState.prototype = {
let newContext = new EditContext(cursor);
if (!newContext.equals(this.cursorContext)) {
this.cursorContext = newContext;
window.webkit.messageHandlers.cursorContextChanged.postMessage(
newContext.encode()
);
this._cursorContextChanged(newContext.encode());
}
}
@ -396,13 +399,14 @@ ComposerPageState.prototype = {
continue;
const reader = new FileReader();
const state = this;
reader.onload = (function(filename, imageType) { return function(loadEvent) {
// Remove prefixed file type and encoding type
var parts = loadEvent.target.result.split(",");
if (parts.length < 2)
return;
window.webkit.messageHandlers.dragDropReceived.postMessage({
state._dragDropReceived({
fileName: encodeURIComponent(filename),
fileType: imageType,
content: parts[1]