summaryrefslogtreecommitdiffstats
path: root/src/schemes/view-source.c
diff options
context:
space:
mode:
authorPatrick McDermott <pj@pehjota.net>2017-11-01 12:36:03 (EDT)
committer Patrick McDermott <pj@pehjota.net>2017-11-01 12:36:03 (EDT)
commit70fa295f32b86a6f575320665fd4541b5d969098 (patch)
tree0a7d091362c3e3028cbd4961da73df8208467d70 /src/schemes/view-source.c
parentf735fa8b547993130d7b5bad10e8e7e0efe61e70 (diff)
downloadmarquee-70fa295f32b86a6f575320665fd4541b5d969098.zip
marquee-70fa295f32b86a6f575320665fd4541b5d969098.tar.gz
marquee-70fa295f32b86a6f575320665fd4541b5d969098.tar.bz2
src/about*, src/view-source.*: Move under src/schemes/
Diffstat (limited to 'src/schemes/view-source.c')
-rw-r--r--src/schemes/view-source.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/schemes/view-source.c b/src/schemes/view-source.c
new file mode 100644
index 0000000..b6cce86
--- /dev/null
+++ b/src/schemes/view-source.c
@@ -0,0 +1,150 @@
+/*
+ * view-source: URI scheme
+ *
+ * Copyright (C) 2017 Patrick McDermott
+ *
+ * This file is part of Marquee.
+ *
+ * Marquee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Marquee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Marquee. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "view-source.h"
+
+#include <string.h>
+
+#include <glib.h>
+#include <webkit2/webkit2.h>
+
+#include "../application.h"
+#include "../utils/resources.h"
+#include "../utils/string.h"
+
+typedef struct {
+ WebKitURISchemeRequest *request;
+ gchar *uri;
+ gulong handler_id;
+} DataSignalData;
+
+static const gchar *document =
+ "<!doctype html>\n"
+ "<html dir=\"%s\">\n"
+ "<head>\n"
+ "<meta charset=\"utf-8\">\n"
+ "<title>Source of %s</title>\n"
+ "<link rel=\"stylesheet\" type=\"text/css\" "
+ "media=\"all\" "
+ "href=\"view-source:resources/prism/"
+ "prism.css\">\n"
+ "<script src=\"view-source:resources/prism/"
+ "prism.js\"></script>\n"
+ "</head>\n"
+ "<body style=\"margin: 0;\">\n"
+ "<pre style=\"overflow: visible; width: 100%; "
+ "margin: 0;\">\n"
+ "<code class=\"language-markup line-numbers\" "
+ "style=\"overflow: visible;\">"
+ "%s</code>\n"
+ "</pre>\n"
+ "</body>\n"
+ "</html>\n";
+
+static void
+respond(WebKitURISchemeRequest *request, const gchar *uri, guchar *data,
+ gsize length)
+{
+ gchar *escaped_data;
+ GInputStream *stream;
+
+ escaped_data = g_markup_escape_text((gchar *) data, length);
+
+ stream = g_memory_input_stream_new_from_data(
+ g_strdup_printf(document,
+ gtk_widget_get_default_direction() ==
+ GTK_TEXT_DIR_RTL ? "rtl" : "ltr",
+ uri, escaped_data), -1, g_free);
+
+ webkit_uri_scheme_request_finish(request, stream, -1, "text/html");
+ g_object_unref(stream);
+}
+
+static void
+data_cb(MqWebView *web_view, GParamSpec G_GNUC_UNUSED *param_spec,
+ DataSignalData *data_signal_data)
+{
+ guchar *data;
+ gsize length;
+
+ data = mq_web_view_get_data(web_view, &length);
+ respond(data_signal_data->request, data_signal_data->uri, data, length);
+ g_signal_handler_disconnect(web_view, data_signal_data->handler_id);
+ g_free(data_signal_data->uri);
+ g_free(data_signal_data);
+}
+
+void
+mq_view_source_request(WebKitURISchemeRequest *request,
+ MqApplication *application)
+{
+ const gchar *path;
+ gchar *query_str;
+ GHashTable *query;
+ gint64 origin_tab_id;
+ gchar *uri;
+ MqTabPage *origin_tab;
+ MqWebView *origin_web_view;
+ guchar *data;
+ gsize length;
+ DataSignalData *data_signal_data;
+
+ path = webkit_uri_scheme_request_get_path(request);
+
+ if (g_str_has_prefix(path, "resources/")) {
+ mq_resource_response(application, path + sizeof("resources"),
+ request);
+ return;
+ }
+
+ query_str = g_strdup(path);
+ query = mq_parse_query_string(query_str);
+
+ /* TODO: Handle missing tab ID ("origin-tab=0"). */
+ origin_tab_id = mq_atoi64(g_hash_table_lookup(query, "origin-tab"));
+ uri = g_strdup(g_hash_table_lookup(query, "uri"));
+
+ g_hash_table_unref(query);
+ g_free(query_str);
+
+ origin_tab = mq_application_get_tab(application, origin_tab_id);
+
+ if (origin_tab) {
+ origin_web_view = mq_tab_page_get_web_view(origin_tab);
+
+ data = mq_web_view_get_data(origin_web_view, &length);
+ if (data) {
+ respond(request, uri, data, length);
+ } else {
+ data_signal_data = g_new(DataSignalData, 1);
+ data_signal_data->request = request;
+ data_signal_data->uri = uri;
+ data_signal_data->handler_id = g_signal_connect(
+ origin_web_view, "notify::data",
+ G_CALLBACK(data_cb), data_signal_data);
+ }
+ } else {
+ /* TODO: Handling reloads by newly requesting the resource
+ * should obviate this. */
+ respond(request, uri,
+ (guchar *) g_strdup("Viewed tab no longer open"), -1);
+ }
+}