liferea icon indicating copy to clipboard operation
liferea copied to clipboard

Add support for Webkit swiping gestures

Open lwindolf opened this issue 2 years ago • 5 comments
trafficstars

Enabling like in devhelp

  #if WEBKIT_CHECK_VERSION(2, 23, 4)
          /* Enable navigation gesture */
          webkit_settings_set_enable_back_forward_navigation_gestures (webkit_settings, TRUE);
  #endif

challenge is to get it working with Reader mode and non-Webkit history.

lwindolf avatar Feb 19 '23 23:02 lwindolf

To add an url into webkit history, the url need to be loaded by liferea_webkit_launch_url(wkview, url).

Reader mode xml render and page load can be postponed to liferea_browser_load_finished() completely if the url was somehow preserved in the liferea:// scheme. Like liferea://readermode/https%3A%2F%2Fgithub.com%2F

I have the following code to pass item_id into liferea://item/id such that item pages are added to the webkit history. It broke reader mode somehow, I suspect that it set the wrong baseurl under reader mode.

diff --git a/js/htmlview.js b/js/htmlview.js
index c6a1e367..09ee2962 100644
--- a/js/htmlview.js
+++ b/js/htmlview.js
@@ -21,7 +21,7 @@
 function setBase(uri) {
 	var base = document.createElement ("base");
 	base.setAttribute ("href", uri);
-	document.head.appendChild (base);
+	document.head.insertBefore (base, document.head.firstElementChild.nextElementSibling);
 }
 
 /**
@@ -40,7 +40,7 @@ function loadContent(readerEnabled, content) {
 	var internalBrowsing = false;
 
 	if (false == readerEnabled) {
-		if (document.location.href === 'liferea://') {
+		if (document.location.href.startsWith('liferea://')) {
 			console.log('[liferea] reader mode is off');
 			document.body.innerHTML = decodeURIComponent(content);
 		} else {
@@ -61,7 +61,7 @@ function loadContent(readerEnabled, content) {
 			}
 
 			// Decide where we get the content from
-			if(document.location.href === 'liferea://') {
+			if(document.location.href.startsWith('liferea://')) {
 				// Add all content in shadow DOM and split decoration from content
 				// only pass the content to Readability.js
 				console.log('[liferea] load content passed by variable');
@@ -77,7 +77,7 @@ function loadContent(readerEnabled, content) {
 			// When we run with internal URI schema we get layout AND content
 			// from variable and split it, apply layout to document
 			// and copy content to documentClone
-			if(document.location.href === 'liferea://' && documentClone.getElementById('content') != null) {
+			if(document.location.href.startsWith('liferea://') && documentClone.getElementById('content') != null) {
 				documentClone.getElementById('content').innerHTML = '';
 				document.body.innerHTML = documentClone.body.innerHTML;
 				documentClone.body.innerHTML = content;
diff --git a/src/ui/liferea_browser.c b/src/ui/liferea_browser.c
index 51d2bc74..c0bdc295 100644
--- a/src/ui/liferea_browser.c
+++ b/src/ui/liferea_browser.c
@@ -448,6 +448,8 @@ liferea_browser_load_finished (LifereaBrowser *browser, const gchar *location)
 	    - for internal content: always (Readability is enable on demand here)
 	 */
 	if (browser->readerMode || (location == strstr (location, "liferea://"))) {
+		gchar         *baseURL = NULL;
+		itemPtr       item = NULL;
 		g_autoptr(GBytes) b1 = NULL, b2 = NULL, b3 = NULL;
 
 		// Return Readability.js and Liferea specific loader code
@@ -460,16 +462,43 @@ liferea_browser_load_finished (LifereaBrowser *browser, const gchar *location)
 		g_assert(b3 != NULL);
 
 		debug1 (DEBUG_GUI, "Enabling reader mode for '%s'", location);
+
+		if (location == strstr(location, "liferea:///item/")) {
+			const gchar *item_id_str = location + strlen("liferea:///item/");
+			gulong item_id = g_ascii_strtoull(item_id_str, NULL, 10);
+			item = item_load(item_id);
+		}
+		if (item) {
+			gchar *content;
+
+			baseURL = (gchar *)node_get_base_url (node_from_id (item->nodeId));
+			if (baseURL)
+				baseURL = g_markup_escape_text (baseURL, -1);
+
+			content = item_render (item, browser->viewMode);
+			if (content) {
+				if (browser->content) {
+					g_free(browser->content);
+					browser->content = NULL;
+				}
+				browser->content = g_uri_escape_string (content, NULL, TRUE);
+				g_free(content);
+			}
+			item_unload (item);
+		}
+
 		liferea_webkit_run_js (
 			browser->renderWidget,
-			g_strdup_printf ("%s\n%s\n%s\nloadContent(%s, '%s');\n",
-		        (gchar *)g_bytes_get_data (b1, NULL),
+			g_strdup_printf ("%s\n%s\n%s\nsetBase('%s');\nloadContent(%s, '%s');\n",
+			(gchar *)g_bytes_get_data (b1, NULL),
 			(gchar *)g_bytes_get_data (b2, NULL),
 			(gchar *)g_bytes_get_data (b3, NULL),
+			baseURL != NULL ? baseURL : "",
 			(browser->readerMode?"true":"false"),
 			browser->content != NULL ? browser->content : ""),
 			liferea_browser_load_finished_cb
 		);
+		g_free(baseURL);
 	}
 }
 
@@ -658,8 +687,13 @@ liferea_browser_refresh (LifereaBrowser *browser, guint mode)
 		case ITEMVIEW_SINGLE_ITEM:
 			item = itemlist_get_selected ();
 			if(item) {
-				baseURL = (gchar *)node_get_base_url (node_from_id (item->nodeId));
+				baseURL = g_strdup_printf("liferea:///item/%ld", item->id);
+				browser->viewMode = mode;
+				liferea_browser_launch_URL_internal(browser, baseURL);
+
+				g_free(baseURL);
 				item_unload (item);
+				return;
 			}
 			break;
 		case ITEMVIEW_NODE_INFO:
diff --git a/src/webkit/webkit.c b/src/webkit/webkit.c
index a0f7d2ca..c0813ecf 100644
--- a/src/webkit/webkit.c
+++ b/src/webkit/webkit.c
@@ -376,10 +376,16 @@ liferea_webkit_handle_liferea_scheme (WebKitURISchemeRequest *request, gpointer
 	gssize length;
 	gchar *contents;
 
-	contents = g_strdup_printf ("Placeholder handler for liferea scheme. URI requested : %s", uri);
+	contents = g_strdup_printf(("<!DOCTYPE html>\n"
+			"<html>\n<head>\n"
+			"<title>HTML View</title>\n"
+			"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
+			"</head>\n<body>%s</body>\n</html>"), uri
+			);
+
 	length = (gssize) strlen (contents);
 	stream = g_memory_input_stream_new_from_data (contents, length, g_free);
-	webkit_uri_scheme_request_finish (request, stream, length, "text/plain");
+	webkit_uri_scheme_request_finish (request, stream, length, "text/html");
 	g_object_unref (stream);
 }
 

mozbugbox avatar Feb 26 '23 03:02 mozbugbox

Personally I would think this would only make sense after a port to GTK4 and the latest webkitgtk...

nekohayo avatar Aug 23 '23 13:08 nekohayo

@nekohayo Latest 1.15.1 is now in latest webkitgtk.

lwindolf avatar Aug 23 '23 23:08 lwindolf

Indeed, though that's webkit2gtk4.1 which means GTK3, rather than webkitgtk-6.0 which would be GTK4; I'm under the impression that attempting this would only make sense after your GTK4 migration :)

nekohayo avatar Sep 11 '23 13:09 nekohayo

@nekohayo True.

lwindolf avatar Sep 13 '23 17:09 lwindolf