[geary/wip/728002-webkit2: 38/43] Initial pass at getting the HTML document's height from the web process.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/728002-webkit2: 38/43] Initial pass at getting the HTML document's height from the web process.
- Date: Fri, 25 Nov 2016 11:20:26 +0000 (UTC)
commit b98569151016cf456fa6d8836d1f54a275fb98b9
Author: Michael James Gratton <mike vee net>
Date: Wed Nov 23 23:55:54 2016 +1100
Initial pass at getting the HTML document's height from the web process.
* bindings/vapi/javascriptcore-4.0.vapi: Add some methods to
GlobalContext for accessing JSValues as ints.
* src/client/components/client-web-view.vala
(ClientWebView): Hook up UserContentManager script messages handler and
handler implementation for "preferredHeightChanged", update the new
preferred_height prop on the class, and queue a resize. Hook those
values up to the GTK allocation machinery.
(ClientWebView::get_int_result): Convenience method for getting an int
from a JavascriptResult.
(ClientWebView::get_preferred_height): Report back values as reported
by messages from the script handler.
(ClientWebView::register_message_handler): Convenience method for
registering script messages handlers.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView): Remove now-redundant GTK allocation machinery.
* ui/client-web-view.js: Post a message to preferredHeightChanged when
the page is sorta-kinda loaded.
bindings/vapi/javascriptcore-4.0.vapi | 7 +++
src/client/components/client-web-view.vala | 52 ++++++++++++++++++++
.../conversation-viewer/conversation-web-view.vala | 34 -------------
ui/client-web-view.js | 3 +
4 files changed, 62 insertions(+), 34 deletions(-)
---
diff --git a/bindings/vapi/javascriptcore-4.0.vapi b/bindings/vapi/javascriptcore-4.0.vapi
index 5d535a3..430c353 100644
--- a/bindings/vapi/javascriptcore-4.0.vapi
+++ b/bindings/vapi/javascriptcore-4.0.vapi
@@ -6,6 +6,13 @@ namespace JS {
[CCode (cname = "JSGlobalContextRef")]
[SimpleType]
public struct GlobalContext {
+
+ [CCode (cname = "JSValueIsNumber")]
+ public bool isNumber(JS.Value value);
+
+ [CCode (cname = "JSValueToNumber")]
+ public double toNumber(JS.Value value, out JS.Value err);
+
}
[CCode (cname = "JSValueRef")]
diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala
index 99911ae..46aed75 100644
--- a/src/client/components/client-web-view.vala
+++ b/src/client/components/client-web-view.vala
@@ -6,11 +6,15 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+protected errordomain JSError { TYPE }
+
public class ClientWebView : WebKit.WebView {
+ /** URI Scheme and delimiter for images loaded by Content-ID. */
public const string CID_PREFIX = "cid:";
+ private const string PREFERRED_HEIGHT_MESSAGE = "preferredHeightChanged";
private const double ZOOM_DEFAULT = 1.0;
private const double ZOOM_FACTOR = 0.1;
@@ -70,6 +74,17 @@ public class ClientWebView : WebKit.WebView {
);
}
+ protected static int get_int_result(WebKit.JavascriptResult result)
+ throws JSError {
+ JS.GlobalContext context = result.get_global_context();
+ JS.Value value = result.get_value();
+ if (!context.isNumber(value)) {
+ throw new JSError.TYPE("Value is not a number");
+ }
+ JS.Value? err = null;
+ return (int) context.toNumber(value, out err);
+ }
+
private static inline uint to_wk2_font_size(Pango.FontDescription font) {
Gdk.Screen? screen = Gdk.Screen.get_default();
double dpi = screen != null ? screen.get_resolution() : 96.0;
@@ -82,6 +97,7 @@ public class ClientWebView : WebKit.WebView {
public bool is_loaded { get; private set; default = false; }
+
public string allow_prefix { get; private set; default = ""; }
private string _document_font;
@@ -117,6 +133,8 @@ public class ClientWebView : WebKit.WebView {
private Gee.Map<string,Geary.Memory.Buffer> cid_resources =
new Gee.HashMap<string,Geary.Memory.Buffer>();
+ private int preferred_height = 0;
+
/** Emitted when a user clicks a link in this web view. */
public signal void link_activated(string uri);
@@ -156,6 +174,18 @@ public class ClientWebView : WebKit.WebView {
}
});
+ content_manager.script_message_received[PREFERRED_HEIGHT_MESSAGE].connect(
+ (result) => {
+ try {
+ this.preferred_height = get_int_result(result);
+ queue_resize();
+ } catch (JSError err) {
+ debug("Could not get preferred height: %s", err.message);
+ }
+ });
+
+ register_message_handler(PREFERRED_HEIGHT_MESSAGE);
+
GearyApplication.instance.config.bind(Configuration.CONVERSATION_VIEWER_ZOOM_KEY, this,
"zoom_level");
this.scroll_event.connect(on_scroll_event);
@@ -214,6 +244,22 @@ public class ClientWebView : WebKit.WebView {
this.zoom_level -= (this.zoom_level * ZOOM_FACTOR);
}
+ // XXX Surely since we are doing height-for-width, we should be
+ // overriding get_preferred_height_for_width here, but that
+ // doesn't seem to work.
+ public override void get_preferred_height(out int minimum_height,
+ out int natural_height) {
+ minimum_height = natural_height = this.preferred_height;
+ }
+
+ // Overridden since we always what the view to be sized according
+ // to the available space in the parent, not by the width of the
+ // web view.
+ public override void get_preferred_width(out int minimum_height,
+ out int natural_height) {
+ minimum_height = natural_height = 0;
+ }
+
internal void handle_cid_request(WebKit.URISchemeRequest request) {
string cid = request.get_uri().substring(CID_PREFIX.length);
Geary.Memory.Buffer? buf = this.cid_resources[cid];
@@ -227,6 +273,12 @@ public class ClientWebView : WebKit.WebView {
}
}
+ protected inline void register_message_handler(string name) {
+ if (!get_user_content_manager().register_script_message_handler(name)) {
+ debug("Failed to register script message handler: %s", name);
+ }
+ }
+
// Only allow string-based page loads, and notify but ignore if
// the user attempts to click on a link. Deny everything else.
private bool on_decide_policy(WebKit.WebView view,
diff --git a/src/client/conversation-viewer/conversation-web-view.vala
b/src/client/conversation-viewer/conversation-web-view.vala
index cda1da5..9994867 100644
--- a/src/client/conversation-viewer/conversation-web-view.vala
+++ b/src/client/conversation-viewer/conversation-web-view.vala
@@ -73,38 +73,4 @@ public class ConversationWebView : ClientWebView {
// XXX
}
- // Overridden since WebKitGTK+ 2.4.10 at least doesn't want to
- // report a useful height. In combination with the rules from
- // ui/conversation-web-view.css we can get an accurate idea of
- // the actual height of the content from the BODY element, but
- // only once loaded.
- public override void get_preferred_height(out int minimum_height,
- out int natural_height) {
- // Silence the "How does the code know the size to allocate?"
- // warning in GTK 3.20-ish.
- base.get_preferred_height(out minimum_height, out natural_height);
-
- long offset_height = 0; // XXX set me
-
- if (offset_height > 0) {
- // Avoid multiple notify signals?
- if (!this.is_height_valid) {
- this.is_height_valid = true;
- }
- }
-
- minimum_height = natural_height = (int) offset_height;
- }
-
- // Overridden since we always what the view to be sized according
- // to the available space in the parent, not by the width of the
- // web view.
- public override void get_preferred_width(out int minimum_height,
- out int natural_height) {
- // Silence the "How does the code know the size to allocate?"
- // warning in GTK 3.20-ish.
- base.get_preferred_width(out minimum_height, out natural_height);
- minimum_height = natural_height = 0;
- }
-
}
diff --git a/ui/client-web-view.js b/ui/client-web-view.js
index e417aeb..a49b113 100644
--- a/ui/client-web-view.js
+++ b/ui/client-web-view.js
@@ -5,3 +5,6 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+window.webkit.messageHandlers.preferredHeightChanged.postMessage(
+ window.document.documentElement.offsetHeight
+);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]