From cc9d58c1029638e0e2c82661aa6a529ee3b6f06b Mon Sep 17 00:00:00 2001 From: Christiam Dywan Date: Mon, 10 Jun 2019 18:33:03 +0200 Subject: [PATCH] Remove uses of WebKit in public API - Expose `Tab` through the new `Viewable` interface - Omit downloads and context exposure - Create tabs through a new `add_tab` method - Expose incognito state through `is_incognito` Fixes: #303 --- core/CMakeLists.txt | 2 +- core/app.vala | 10 ++++----- core/browser.vala | 38 +++++++++++++++++++++++----------- core/download-button.vala | 4 ++-- core/tab.vala | 33 ++++++++++++++++++++++++----- core/tally.vala | 6 ++++-- core/urlbar.vala | 2 +- extensions/bookmarks.vala | 2 +- extensions/colorful-tabs.vala | 2 +- extensions/session.vala | 23 +++++++++----------- extensions/web-extensions.vala | 7 +++---- 11 files changed, 82 insertions(+), 47 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 0fb9d09fb..25f7e09d5 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,6 +1,6 @@ # Copyright (C) 2013-2018 Christian Dywan -set(LIBCORE_VERSION 0.6) +set(LIBCORE_VERSION 0.9) set(LIBCORE_SOVERSION 0) set(LIBCORE_GIR Midori-${LIBCORE_VERSION}) diff --git a/core/app.vala b/core/app.vala index 8b5a4b389..f61630636 100644 --- a/core/app.vala +++ b/core/app.vala @@ -210,7 +210,7 @@ namespace Midori { request.unref (); } - void request_finish_pixbuf (WebKit.URISchemeRequest request, Gdk.Pixbuf pixbuf) throws Error { + static void request_finish_pixbuf (WebKit.URISchemeRequest request, Gdk.Pixbuf pixbuf) throws Error { var output = new MemoryOutputStream (null, realloc, free); pixbuf.save_to_stream (output, "png"); output.close (); @@ -237,7 +237,7 @@ namespace Midori { request.unref (); } - async void stock_scheme (WebKit.URISchemeRequest request) { + async static void stock_scheme (WebKit.URISchemeRequest request) { string icon_name = request.get_path ().substring (1, -1); int icon_size = 48; Gtk.icon_size_lookup ((Gtk.IconSize)Gtk.IconSize.DIALOG, out icon_size, null); @@ -251,7 +251,7 @@ namespace Midori { request.unref (); } - void apply_proxy_settings (CoreSettings settings, WebKit.WebContext context) { + static void apply_proxy_settings (CoreSettings settings, WebKit.WebContext context) { switch (settings.proxy_type) { case ProxyType.AUTOMATIC: context.set_network_proxy_settings (WebKit.NetworkProxyMode.DEFAULT, null); @@ -268,7 +268,7 @@ namespace Midori { } } - internal WebKit.WebContext ephemeral_context () { + internal static WebKit.WebContext ephemeral_context () { var context = new WebKit.WebContext.ephemeral (); context.register_uri_scheme ("internal", (request) => { request.ref (); @@ -312,7 +312,7 @@ namespace Midori { return context; } - async void private_scheme (WebKit.URISchemeRequest request) { + async static void private_scheme (WebKit.URISchemeRequest request) { string[] suggestions = { _("No history or web cookies are being saved."), _("HTML5 storage, local database and application caches are disabled."), diff --git a/core/browser.vala b/core/browser.vala index 275587159..6cbee8e47 100644 --- a/core/browser.vala +++ b/core/browser.vala @@ -18,14 +18,15 @@ namespace Midori { [GtkTemplate (ui = "/ui/browser.ui")] public class Browser : Gtk.ApplicationWindow { - public WebKit.WebContext web_context { get; construct set; } + internal WebKit.WebContext web_context { get; protected set; } internal bool idle { get; protected set; default = false; } public bool is_loading { get; protected set; default = false; } public string? uri { get; protected set; } - public Tab? tab { get; protected set; } + public Viewable? tab { get; protected set; } public ListStore trash { get; protected set; } public bool is_fullscreen { get; protected set; default = false; } public bool is_locked { get; construct set; default = false; } + public bool is_incognito { get; construct set; default = false; } internal bool is_small { get; protected set; default = false; } Menu zoom_menu = new Menu (); internal double zoom_level { get; protected set; default = 1.0f; } @@ -84,6 +85,7 @@ namespace Midori { uint focus_timeout = 0; construct { + web_context = is_incognito ? App.ephemeral_context () : WebKit.WebContext.get_default (); overlay.add_events (Gdk.EventMask.ENTER_NOTIFY_MASK | Gdk.EventMask.POINTER_MOTION_MASK); overlay.enter_notify_event.connect ((event) => { if (is_fullscreen && !tab.pinned) { @@ -272,7 +274,7 @@ namespace Midori { navigationbar.urlbar.notify["uri"].connect ((pspec) => { string uri = navigationbar.urlbar.uri; if (uri.has_prefix ("javascript:")) { - tab.run_javascript.begin (uri.substring (11, -1), null); + tab.run_javascript.begin (uri.substring (11, -1)); } else if (uri != tab.display_uri) { tab.load_uri (uri); } @@ -312,7 +314,7 @@ namespace Midori { focus_timeout = Timeout.add (500, () => { focus_timeout = 0; tab.grab_focus (); - search_entry.text = tab.get_find_controller ().get_search_text () ?? ""; + search_entry.text = ((Tab)tab).get_find_controller ().get_search_text () ?? ""; search.visible = search_entry.text != ""; search.search_mode_enabled = search.visible; if (navigationbar.urlbar.blank) { @@ -440,12 +442,12 @@ namespace Midori { public Browser (App app, bool is_locked=false) { Object (application: app, is_locked: is_locked, - web_context: WebKit.WebContext.get_default ()); + is_incognito: false); } public Browser.incognito (App app) { Object (application: app, - web_context: app.ephemeral_context ()); + is_incognito: true); } public override bool key_press_event (Gdk.EventKey event) { @@ -490,7 +492,7 @@ namespace Midori { } void tab_close_activated () { - tab.try_close (); + ((Tab)tab).try_close (); } void close_activated () { @@ -618,11 +620,11 @@ namespace Midori { if (backwards) { options |= WebKit.FindOptions.BACKWARDS; } - tab.get_find_controller ().search (search_entry.text, options, int.MAX); + ((Tab)tab).get_find_controller ().search (search_entry.text, options, int.MAX); } void view_source_activated () { - view_source.begin (tab); + view_source.begin ((Tab)tab); } async void view_source (Tab tab) { @@ -646,7 +648,7 @@ namespace Midori { } void print_activated () { - tab.print (new WebKit.PrintOperation (tab)); + ((Tab)tab).print (new WebKit.PrintOperation ((Tab)tab)); } internal string? prompt (string title, string message, string confirm, string? text=null) { @@ -690,10 +692,22 @@ namespace Midori { } void show_inspector_activated () { - tab.get_inspector ().show (); + ((Tab)tab).get_inspector ().show (); } - public new void add (Tab tab) { + public Viewable add_tab (Viewable? related, Browser? browser, + string? uri = null, string? title = null) { + var tab = new Tab (related, browser.web_context, uri, title); + add (tab); + return tab; + } + + public override void add (Gtk.Widget widget) { + var tab = widget as Tab; + if (tab == null) { + base.add (widget); + return; + } tab.popover.relative_to = navigationbar.urlbar; if (is_locked) { tab.decide_policy.connect ((decision, type) => { diff --git a/core/download-button.vala b/core/download-button.vala index 943197925..87b96d99c 100644 --- a/core/download-button.vala +++ b/core/download-button.vala @@ -80,7 +80,7 @@ namespace Midori { public string? filename { get; protected set; default = null; } public string? basename { get; protected set; default = null; } public double progress { get; protected set; default = 0.0; } - public WebKit.Download? download { get; protected set; default = null; } + internal WebKit.Download? download { get; protected set; default = null; } public bool loading { get; protected set; default = false; } public string? error { get; protected set; default = null; } public void cancel () { @@ -109,7 +109,7 @@ namespace Midori { Object (filename: filename); } - public DownloadItem.with_download (WebKit.Download download) { + internal DownloadItem.with_download (WebKit.Download download) { Object (download: download, loading: true); download.bind_property ("destination", this, "filename", BindingFlags.SYNC_CREATE); download.bind_property ("estimated-progress", this, "progress", BindingFlags.SYNC_CREATE); diff --git a/core/tab.vala b/core/tab.vala index 5e3baa1fe..b41d55f47 100644 --- a/core/tab.vala +++ b/core/tab.vala @@ -11,14 +11,37 @@ namespace Midori { public interface TabActivatable : Peas.ExtensionBase { - public abstract Tab tab { owned get; set; } + public abstract Viewable tab { owned get; set; } public abstract void activate (); public signal void deactivate (); } - [GtkTemplate (ui = "/ui/tab.ui")] - public class Tab : WebKit.WebView { + public interface Viewable : Gtk.Widget { public string id { owned get { return "%p".printf (this); } } + public abstract double progress { get; protected set; } + public abstract double zoom_level { get; set; } + public abstract bool can_go_back { get; protected set; } + public abstract bool can_go_forward { get; protected set; } + public abstract string uri { get; } + public abstract string display_uri { get; protected set; } + public abstract string title { get; } + public abstract string display_title { get; protected set; } + public abstract string? color { get; set; default = null; } + public abstract bool pinned { get; set; } + public abstract bool secure { get; protected set; } + internal abstract TlsCertificate? tls { get; protected set; default = null; } + public abstract string link_uri { get; protected set; } + public abstract void load_uri (string uri); + public abstract void reload (); + public abstract void stop_loading (); + public abstract void go_back (); + public abstract void go_forward (); + public abstract signal void close (); + public async abstract void run_javascript (string script, Cancellable? cancellable = null); + } + + [GtkTemplate (ui = "/ui/tab.ui")] + internal class Tab : WebKit.WebView, Viewable { public double progress { get; protected set; } public new bool can_go_back { get; protected set; } public new bool can_go_forward { get; protected set; } @@ -55,7 +78,7 @@ namespace Midori { }); } - public Tab (Tab? related, WebKit.WebContext web_context, + public Tab (Viewable? related, WebKit.WebContext web_context, string? uri = null, string? title = null) { // One content manager per web context @@ -65,7 +88,7 @@ namespace Midori { web_context.set_data ("user-content-manager", content); } - Object (related_view: related, web_context: web_context, user_content_manager: content, visible: true); + Object (related_view: (Tab?)related, web_context: web_context, user_content_manager: content, visible: true); var settings = get_settings (); settings.user_agent += " %s".printf (Config.CORE_USER_AGENT_VERSION); diff --git a/core/tally.vala b/core/tally.vala index a5f70aeb6..beeb7664b 100644 --- a/core/tally.vala +++ b/core/tally.vala @@ -12,7 +12,7 @@ namespace Midori { [GtkTemplate (ui = "/ui/tally.ui")] public class Tally : Gtk.EventBox { - public Tab tab { get; protected set; } + internal Tab tab { get; protected set; } public string? uri { get; set; } public string? title { get; set; } bool _show_close; @@ -46,7 +46,9 @@ namespace Midori { [GtkChild] Gtk.Button close; - public Tally (Tab tab) { + public Tally (Viewable viewable) { + var tab = viewable as Tab; + return_if_fail (tab != null); Object (tab: tab, uri: tab.display_uri, title: tab.display_title, diff --git a/core/urlbar.vala b/core/urlbar.vala index 4b4ed5a51..a06e15ade 100644 --- a/core/urlbar.vala +++ b/core/urlbar.vala @@ -267,7 +267,7 @@ namespace Midori { if (!suggestions.visible) { suggestions.set_default_widget (this); suggestions.relative_to = this; - var completion = new Completion (((Browser)get_toplevel ()).tab.web_context.is_ephemeral ()); + var completion = new Completion (((Browser)get_toplevel ()).is_incognito); bind_property ("key", completion, "key"); listbox.bind_model (completion, create_row); } diff --git a/extensions/bookmarks.vala b/extensions/bookmarks.vala index 080776949..ec36cfef2 100644 --- a/extensions/bookmarks.vala +++ b/extensions/bookmarks.vala @@ -144,7 +144,7 @@ namespace Bookmarks { }); } - async Midori.DatabaseItem item_for_tab (Midori.Tab tab) { + async Midori.DatabaseItem item_for_tab (Midori.Viewable tab) { var item = tab.get_data ("bookmarks-item"); if (item == null) { try { diff --git a/extensions/colorful-tabs.vala b/extensions/colorful-tabs.vala index 0635e37a2..bd75637a1 100644 --- a/extensions/colorful-tabs.vala +++ b/extensions/colorful-tabs.vala @@ -12,7 +12,7 @@ namespace ColorfulTabs { public class Tint : Peas.ExtensionBase, Midori.TabActivatable { - public Midori.Tab tab { owned get; set; } + public Midori.Viewable tab { owned get; set; } public void activate () { tab.notify["display-uri"].connect (apply_tint); diff --git a/extensions/session.vala b/extensions/session.vala index 8307d5cce..c2777e0f4 100644 --- a/extensions/session.vala +++ b/extensions/session.vala @@ -207,16 +207,13 @@ namespace Tabby { restored = true; connect_browser (browser, id); foreach (var widget in browser.tabs.get_children ()) { - yield tab_added (widget as Midori.Tab, id); + yield tab_added (widget as Midori.Viewable, id); } } else { var app = (Midori.App)default_browser.get_application (); browser = browser_for_session (app, id); } - var tab = new Midori.Tab (null, browser.web_context, - item.uri, item.title); - connect_tab (tab, item); - browser.add (tab); + connect_tab (browser.add_tab (null, browser, item.uri, item.title), item); } return restored; } @@ -242,9 +239,9 @@ namespace Tabby { browsers.insert (id.to_string (), browser); browser.set_data ("tabby_connected", true); foreach (var widget in browser.tabs.get_children ()) { - tab_added.begin (widget as Midori.Tab, id); + tab_added.begin (widget as Midori.Viewable, id); } - browser.tabs.add.connect ((widget) => { tab_added.begin (widget as Midori.Tab, id); }); + browser.tabs.add.connect ((widget) => { tab_added.begin (widget as Midori.Viewable, id); }); browser.delete_event.connect ((event) => { debug ("Closing session %s", id.to_string ()); update_session (id, true); @@ -252,7 +249,7 @@ namespace Tabby { }); } - void connect_tab (Midori.Tab tab, Midori.DatabaseItem item) { + void connect_tab (Midori.Viewable tab, Midori.DatabaseItem item) { debug ("Connecting %s to session %s", item.uri, item.get_data ("session_id").to_string ()); tab.set_data ("tabby-item", item); tab.notify["uri"].connect ((pspec) => { item.uri = tab.uri; update.begin (item); }); @@ -260,11 +257,11 @@ namespace Tabby { tab.close.connect (() => { tab_removed (tab); }); } - bool tab_is_connected (Midori.Tab tab) { + bool tab_is_connected (Midori.Viewable tab) { return tab.get_data ("tabby-item") != null; } - async void tab_added (Midori.Tab tab, int64 id) { + async void tab_added (Midori.Viewable tab, int64 id) { if (tab_is_connected (tab)) { return; } @@ -279,7 +276,7 @@ namespace Tabby { } } - void tab_removed (Midori.Tab tab) { + void tab_removed (Midori.Viewable tab) { var item = tab.get_data ("tabby-item"); debug ("Trashing tab %s:%s", item.get_data ("session_id").to_string (), tab.display_uri); item.delete.begin (); @@ -293,7 +290,7 @@ namespace Tabby { public void activate () { // Don't track locked (app) or private windows - if (browser.is_locked || browser.web_context.is_ephemeral ()) { + if (browser.is_locked || browser.is_incognito) { return; } // Skip windows already in the session @@ -339,7 +336,7 @@ namespace Tabby { try { bool restored = yield session.restore_windows (browser); if (!restored) { - browser.add (new Midori.Tab (null, browser.web_context)); + browser.add_tab (null, browser); session.connect_browser (browser); } } catch (Midori.DatabaseError error) { diff --git a/extensions/web-extensions.vala b/extensions/web-extensions.vala index 3fc06b495..360bb3fe5 100644 --- a/extensions/web-extensions.vala +++ b/extensions/web-extensions.vala @@ -264,8 +264,7 @@ namespace WebExtension { if (fn != null && fn.has_prefix ("tabs.create")) { var args = object.get_property (context, new JS.String.create_with_utf8_cstring ("args")).to_object (context); string? url = js_to_string (context, args.get_property (context, new JS.String.create_with_utf8_cstring ("url"))); - var tab = new Midori.Tab (null, browser.tab.web_context, url); - browser.add (tab); + var tab = browser.add_tab (null, browser, url); var promise = object.get_property (context, new JS.String.create_with_utf8_cstring ("promise")).to_number (context); debug ("Calling back to promise #%.f".printf (promise)); web_view.run_javascript.begin ("promises[%.f].resolve({id:%s});".printf (promise, tab.id)); @@ -494,9 +493,9 @@ namespace WebExtension { browser.tabs.add.disconnect (tab_added); var manager = ExtensionManager.get_default (); - var tab = widget as Midori.Tab; + var tab = widget as Midori.Viewable; - var content = tab.get_user_content_manager (); + var content = ((WebKit.WebView)tab).get_user_content_manager (); // Try and load plugins from build folder var builtin_path = ((Midori.App)Application.get_default ()).exec_path.get_parent ().get_child ("extensions"); manager.load_from_folder.begin (content, builtin_path);