From b1027fcbbfbfd7d052f2dab62381f987d27420d9 Mon Sep 17 00:00:00 2001 From: Michael James Gratton Date: Fri, 2 Dec 2016 01:08:07 +1100 Subject: [PATCH] Implement getting HTML and plain text from ComposerWebView in WK2. * src/client/composer/composer-web-view.vala (ComposerWebView): Implement both ::get_html and ::get_text as async JS calls, make the methods async and update cal sites to handle that. * src/client/composer/composer-widget.vala: Make saving deafts and sending message async, to handle editor returning message body text async. Remove uneeded ::get_html and ::get_text functions, update call sites to call same directly on the on editor instead. * src/client/web-process/util-composer.vala: Remove obsolete ::get_html and ::get_text functions. * ui/composer-web-view.js (ComposerPageState): Initial implementation of getHtml and getText methods. --- src/client/composer/composer-web-view.vala | 14 +++-- src/client/composer/composer-widget.vala | 69 ++++++++++++---------- src/client/web-process/util-composer.vala | 14 ----- ui/composer-web-view.js | 8 +++ 4 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/client/composer/composer-web-view.vala b/src/client/composer/composer-web-view.vala index e3d06639..821ff0bd 100644 --- a/src/client/composer/composer-web-view.vala +++ b/src/client/composer/composer-web-view.vala @@ -201,15 +201,21 @@ public class ComposerWebView : ClientWebView { /** * Returns the editor content as an HTML string. */ - public string get_html() { - return ""; // XXX + public async string? get_html() throws Error { + WebKit.JavascriptResult result = yield this.run_javascript( + "geary.getHtml();", null + ); + return get_string_result(result); } /** * Returns the editor content as a plain text string. */ - public string get_text() { - return ""; // XXX + public async string? get_text() throws Error { + WebKit.JavascriptResult result = yield this.run_javascript( + "geary.getText();", null + ); + return get_string_result(result); } /** diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala index cf0409cf..b2d213f4 100644 --- a/src/client/composer/composer-widget.vala +++ b/src/client/composer/composer-widget.vala @@ -732,7 +732,7 @@ public class ComposerWidget : Gtk.EventBox { this.body_html = message.get_plain_body(true, null); } } catch (Error error) { - debug("Error getting message body: %s", error.message); + debug("Error getting draft message body: %s", error.message); } break; @@ -880,7 +880,7 @@ public class ComposerWidget : Gtk.EventBox { return true; } - public Geary.ComposedEmail get_composed_email(DateTime? date_override = null, + public async Geary.ComposedEmail get_composed_email(DateTime? date_override = null, bool only_html = false) { Geary.ComposedEmail email = new Geary.ComposedEmail( date_override ?? new DateTime.now_local(), from); @@ -907,10 +907,14 @@ public class ComposerWidget : Gtk.EventBox { email.img_src_prefix = this.editor.allow_prefix; - if (actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean() || only_html) - email.body_html = get_html(); - if (!only_html) - email.body_text = get_text(); + try { + if (actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean() || only_html) + email.body_html = yield this.editor.get_html(); + if (!only_html) + email.body_text = yield this.editor.get_text(); + } catch (Error error) { + debug("Error getting composer message body: %s", error.message); + } // User-Agent email.mailer = GearyApplication.PRGNAME + "/" + GearyApplication.VERSION; @@ -1207,10 +1211,16 @@ public class ComposerWidget : Gtk.EventBox { return false; } - private bool should_send() { + private async bool should_send() { bool has_subject = !Geary.String.is_empty(subject.strip()); - bool has_body = !Geary.String.is_empty(get_html()); bool has_attachment = this.attached_files.size > 0; + bool has_body = true; + + try { + has_body = !Geary.String.is_empty(yield this.editor.get_html()); + } catch (Error err) { + debug("Failed to get message body: %s", err.message); + } string? confirmation = null; if (!has_subject && !has_body && !has_attachment) { @@ -1232,8 +1242,11 @@ public class ComposerWidget : Gtk.EventBox { // Sends the current message. private void on_send(SimpleAction action, Variant? param) { - if (should_send()) - on_send_async.begin(); + this.should_send.begin((obj, res) => { + if (this.should_send.end(res)) { + on_send_async.begin(); + } + }); } // Used internally by on_send() @@ -1245,7 +1258,7 @@ public class ComposerWidget : Gtk.EventBox { // Perform send. try { - yield this.account.send_email_async(get_composed_email()); + yield this.account.send_email_async(yield get_composed_email()); } catch (Error e) { GLib.message("Error sending email: %s", e.message); } @@ -1337,20 +1350,24 @@ public class ComposerWidget : Gtk.EventBox { } // Note that drafts are NOT "linkified." - private Geary.Nonblocking.Semaphore? save_draft() { + private void save_draft() { // cancel timer in favor of just doing it now cancel_draft_timer(); - - try { - if (this.draft_manager != null) { - return this.draft_manager.update(get_composed_email(null, true).to_rfc822_message(), - this.draft_flags, null); - } - } catch (Error err) { - GLib.message("Unable to save draft: %s", err.message); + + if (this.draft_manager != null) { + this.get_composed_email.begin(null, true, (obj, res) => { + try { + Geary.ComposedEmail draft = this.get_composed_email.end(res); + this.draft_manager.update( + draft.to_rfc822_message(), + this.draft_flags, + null + ); + } catch (Error err) { + GLib.message("Unable to save draft: %s", err.message); + } + }); } - - return null; } private Geary.Nonblocking.Semaphore? discard_draft() { @@ -1778,14 +1795,6 @@ public class ComposerWidget : Gtk.EventBox { //Util.DOM.bind_event(this.editor,"a", "click", (Callback) on_link_clicked, this); } - private string get_html() { - return this.editor.get_html(); - } - - private string get_text() { - return this.editor.get_text(); - } - private void on_link_activated(ClientWebView view, string uri) { if (this.actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean()) link_dialog(uri); diff --git a/src/client/web-process/util-composer.vala b/src/client/web-process/util-composer.vala index 93442b16..15c41958 100644 --- a/src/client/web-process/util-composer.vala +++ b/src/client/web-process/util-composer.vala @@ -6,8 +6,6 @@ namespace Util.Composer { - private const string BODY_ID = "message-body"; - // HTML node names private const string BLOCKQUOTE_NAME = "BLOCKQUOTE"; private const string BODY_NAME = "BODY"; @@ -120,18 +118,6 @@ namespace Util.Composer { } } - public string get_html(WebKit.WebPage page) { - return ( - (WebKit.DOM.HTMLElement) page.get_dom_document().get_element_by_id(BODY_ID) - ).get_inner_html(); - } - - public string get_text(WebKit.WebPage page) { - return Util.DOM.html_to_flowed_text( - (WebKit.DOM.HTMLElement) page.get_dom_document().get_element_by_id(BODY_ID) - ); - } - public bool handle_key_press(WebKit.WebPage page, Gdk.EventKey event) { WebKit.DOM.Document document = page.get_dom_document(); if (event.keyval == Gdk.Key.Tab) { diff --git a/ui/composer-web-view.js b/ui/composer-web-view.js index 7c902ef8..db238ad0 100644 --- a/ui/composer-web-view.js +++ b/ui/composer-web-view.js @@ -12,6 +12,8 @@ var ComposerPageState = function() { this.init.apply(this, arguments); }; +ComposerPageState.BODY_ID = "message-body"; + ComposerPageState.prototype = { __proto__: PageState.prototype, init: function() { @@ -51,6 +53,12 @@ ComposerPageState.prototype = { PageState.prototype.loaded.apply(this, []); //Util.DOM.bind_event(view, "a", "click", (Callback) on_link_clicked, this); + }, + getHtml: function() { + return document.getElementById(ComposerPageState.BODY_ID).innerHTML; + }, + getText: function() { + return document.getElementById(ComposerPageState.BODY_ID).innerText; } // private static void on_link_clicked(WebKit.DOM.Element element, WebKit.DOM.Event event, // ComposerWidget composer) {