/*
* 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 .
*/
#include "view-source.h"
#include
#include
#include
#include "application.h"
#include "string-utils.h"
typedef struct {
WebKitURISchemeRequest *request;
gchar *uri;
gulong handler_id;
} DataSignalData;
static const gchar *document =
"\n"
"\n"
"\n"
"\n"
"Source of %s\n"
"\n"
"\n"
"\n"
"%s
\n"
"
\n"
"\n"
"\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)
{
gchar *path;
GHashTable *query;
gint64 origin_tab_id;
gchar *uri;
MqTabPage *origin_tab;
MqWebView *origin_web_view;
guchar *data;
gsize length;
DataSignalData *data_signal_data;
path = g_strdup(webkit_uri_scheme_request_get_path(request));
query = mq_parse_query_string(path);
/* 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(path);
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);
}
}