[epiphany] Add pdf handler



commit d04e9bba344662303cc20e88852d12aee2bb6709
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Sat Jun 20 18:19:39 2020 +0200

    Add pdf handler
    
    This implicitly enables controlling the load state through the combined
    stop load button.
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/-/issues/1189

 embed/ephy-embed-shell.c |  31 ++++-
 embed/ephy-embed-shell.h |   2 +
 embed/ephy-embed-utils.c |   1 +
 embed/ephy-embed.c       | 134 ---------------------
 embed/ephy-pdf-handler.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++
 embed/ephy-pdf-handler.h |  41 +++++++
 embed/ephy-web-view.c    |  16 ++-
 embed/meson.build        |   1 +
 src/ephy-session.c       |   3 +-
 9 files changed, 387 insertions(+), 141 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 482fe7c83..293a7f2f1 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -35,6 +35,7 @@
 #include "ephy-flatpak-utils.h"
 #include "ephy-history-service.h"
 #include "ephy-password-manager.h"
+#include "ephy-pdf-handler.h"
 #include "ephy-profile-utils.h"
 #include "ephy-reader-handler.h"
 #include "ephy-settings.h"
@@ -65,6 +66,7 @@ typedef struct {
   EphyAboutHandler *about_handler;
   EphyViewSourceHandler *source_handler;
   EphyReaderHandler *reader_handler;
+  EphyPDFHandler *pdf_handler;
   char *guid;
   EphyFiltersManager *filters_manager;
   EphySearchEngineManager *search_engine_manager;
@@ -192,6 +194,7 @@ ephy_embed_shell_dispose (GObject *object)
   g_clear_object (&priv->about_handler);
   g_clear_object (&priv->reader_handler);
   g_clear_object (&priv->source_handler);
+  g_clear_object (&priv->pdf_handler);
   g_clear_object (&priv->downloads_manager);
   g_clear_object (&priv->password_manager);
   g_clear_object (&priv->permissions_manager);
@@ -698,6 +701,15 @@ reader_request_cb (WebKitURISchemeRequest *request,
   ephy_reader_handler_handle_request (priv->reader_handler, request);
 }
 
+static void
+pdf_request_cb (WebKitURISchemeRequest *request,
+                EphyEmbedShell         *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  ephy_pdf_handler_handle_request (priv->pdf_handler, request);
+}
+
 static void
 ephy_resource_request_cb (WebKitURISchemeRequest *request)
 {
@@ -810,11 +822,6 @@ download_started_cb (WebKitWebContext *web_context,
 
   web_view = webkit_download_get_web_view (download);
   if (EPHY_IS_WEB_VIEW (web_view)) {
-    EphyEmbed *embed;
-
-    embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view);
-    ephy_embed_download_started (embed, ephy_download);
-
     if (ephy_web_view_get_document_type (EPHY_WEB_VIEW (web_view)) != EPHY_WEB_VIEW_DOCUMENT_PDF)
       ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
   } else {
@@ -898,6 +905,11 @@ ephy_embed_shell_startup (GApplication *application)
   webkit_web_context_register_uri_scheme (priv->web_context, EPHY_VIEW_SOURCE_SCHEME,
                                           (WebKitURISchemeRequestCallback)source_request_cb,
                                           shell, NULL);
+  /* pdf handler */
+  priv->pdf_handler = ephy_pdf_handler_new ();
+  webkit_web_context_register_uri_scheme (priv->web_context, EPHY_PDF_SCHEME,
+                                          (WebKitURISchemeRequestCallback)pdf_request_cb,
+                                          shell, NULL);
 
   /* reader mode handler */
   priv->reader_handler = ephy_reader_handler_new ();
@@ -1418,3 +1430,12 @@ ephy_embed_shell_unregister_ucm_handler (EphyEmbedShell           *shell,
                                                                           "passwordManagerSave",
                                                                           priv->guid);
 }
+
+void
+ephy_embed_shell_pdf_handler_stop (EphyEmbedShell *shell,
+                                   WebKitWebView  *web_view)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  ephy_pdf_handler_stop (priv->pdf_handler, web_view);
+}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index d4ec41f26..9464d42d4 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -91,5 +91,7 @@ void                     ephy_embed_shell_register_ucm_handler (EphyEmbedShell
 void                     ephy_embed_shell_unregister_ucm_handler (EphyEmbedShell           *shell,
                                                                   WebKitUserContentManager *ucm);
 
+void                     ephy_embed_shell_pdf_handler_stop (EphyEmbedShell *shell,
+                                                            WebKitWebView  *web_view);
 
 G_END_DECLS
diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c
index edbe3d614..1dc44ebe2 100644
--- a/embed/ephy-embed-utils.c
+++ b/embed/ephy-embed-utils.c
@@ -134,6 +134,7 @@ ephy_embed_utils_address_has_web_scheme (const char *address)
                      g_ascii_strncasecmp (address, "ephy-resource", colonpos) &&
                      g_ascii_strncasecmp (address, "ephy-source", colonpos) &&
                      g_ascii_strncasecmp (address, "ephy-reader", colonpos) &&
+                     g_ascii_strncasecmp (address, "ephy-pdf", colonpos) &&
                      g_ascii_strncasecmp (address, "gopher", colonpos) &&
                      g_ascii_strncasecmp (address, "inspector", colonpos) &&
                      g_ascii_strncasecmp (address, "webkit", colonpos));
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index b0de87d89..aaaa5e159 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -996,137 +996,3 @@ ephy_embed_detach_notification_container (EphyEmbed *embed)
     gtk_container_remove (GTK_CONTAINER (embed->overlay), g_object_ref (GTK_WIDGET (container)));
   }
 }
-
-typedef struct {
-  char *document_uri;
-  char *remote_uri;
-  WebKitDownload *download;
-  EphyWebView *web_view;
-} PdfAsyncData;
-
-static PdfAsyncData *
-pdf_async_data_new (const char  *document_uri,
-                    const char  *remote_uri,
-                    EphyWebView *web_view)
-{
-  PdfAsyncData *data;
-
-  data = g_new0 (PdfAsyncData, 1);
-  data->document_uri = g_strdup (document_uri);
-  data->remote_uri = g_strdup (remote_uri);
-  data->web_view = web_view;
-
-  if (web_view)
-    g_object_add_weak_pointer (G_OBJECT (web_view), (gpointer *)&data->web_view);
-
-  return data;
-}
-
-static void
-pdf_async_data_free (PdfAsyncData *data)
-{
-  if (data->web_view)
-    g_object_remove_weak_pointer (G_OBJECT (data->web_view), (gpointer *)&data->web_view);
-
-  g_free (data->document_uri);
-  g_free (data->remote_uri);
-  g_free (data);
-}
-
-static void
-pdf_file_deleted (GObject      *source,
-                  GAsyncResult *res,
-                  gpointer      user_data)
-{
-  g_autoptr (GError) error = NULL;
-  if (!g_file_delete_finish (G_FILE (source), res, &error))
-    g_warning ("Could not delete temporary PDF file: %s", error->message);
-}
-
-static void
-pdf_file_loaded (GObject      *source,
-                 GAsyncResult *res,
-                 gpointer      user_data)
-{
-  PdfAsyncData *data = user_data;
-  WebKitWebView *web_view = WEBKIT_WEB_VIEW (data->web_view);
-  GBytes *html_file;
-  g_autoptr (GError) error = NULL;
-  g_autoptr (GString) html = NULL;
-  g_autofree gchar *b64 = NULL;
-  g_autofree gchar *requested_uri = NULL;
-  g_autofree char *file_data = NULL;
-  gsize len = 0;
-
-  if (!g_file_load_contents_finish (G_FILE (source), res, &file_data, &len, NULL, &error)) {
-    g_warning ("Could not read PDF file content: %s", error->message);
-    pdf_async_data_free (data);
-    return;
-  }
-
-  html_file = g_resources_lookup_data ("/org/gnome/epiphany/pdfjs/web/viewer.html", 0, NULL);
-
-  b64 = g_base64_encode ((const guchar *)file_data, len);
-  g_file_delete_async (G_FILE (source), G_PRIORITY_DEFAULT, NULL, pdf_file_deleted, NULL);
-
-  html = g_string_new ("");
-  g_string_printf (html, g_bytes_get_data (html_file, NULL), b64, g_path_get_basename (data->remote_uri));
-
-  webkit_web_view_load_alternate_html (web_view, html->str, data->remote_uri, 
"ephy-resource:///org/gnome/epiphany/pdfjs/web/");
-
-  /* FIXME: Necessary WebKit API to access security level (TLS certificate) of a download is not
-   * available. Please fix this line once available.
-   */
-  ephy_web_view_set_security_level (data->web_view, EPHY_SECURITY_LEVEL_LOCAL_PAGE);
-
-  pdf_async_data_free (data);
-}
-
-static void
-pdf_download_finished_cb (WebKitDownload *download,
-                          EphyEmbed      *embed)
-{
-  EphyWebView *view = ephy_embed_get_web_view (embed);
-  WebKitURIRequest *request = webkit_download_get_request (download);
-  g_autoptr (GFile) file = NULL;
-  PdfAsyncData *pdf_data;
-  const char *document_uri = webkit_download_get_destination (download);
-  const char *remote_uri = webkit_uri_request_get_uri (request);
-
-  file = g_file_new_for_uri (document_uri);
-
-  pdf_data = pdf_async_data_new (document_uri, remote_uri, view);
-  g_file_load_contents_async (file, NULL, pdf_file_loaded, pdf_data);
-}
-
-static gboolean
-pdf_download_decide_destination_cb (WebKitDownload *wk_download,
-                                    gchar          *suggested_filename,
-                                    gpointer        user_data)
-{
-  EphyWebView *web_view = ephy_embed_get_web_view (EPHY_EMBED (user_data));
-
-  if (ephy_web_view_get_document_type (web_view) == EPHY_WEB_VIEW_DOCUMENT_PDF) {
-    g_autofree gchar *tmp_file = g_strdup_printf ("%s/%s", g_get_tmp_dir (), suggested_filename);
-    g_autofree gchar *file_uri = g_filename_to_uri (tmp_file, NULL, NULL);
-
-    webkit_download_set_allow_overwrite (wk_download, TRUE);
-    webkit_download_set_destination (wk_download, file_uri);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-void
-ephy_embed_download_started (EphyEmbed    *embed,
-                             EphyDownload *ephy_download)
-{
-  EphyWebView *web_view = ephy_embed_get_web_view (embed);
-  WebKitDownload *download = ephy_download_get_webkit_download (ephy_download);
-
-  if (ephy_web_view_get_document_type (web_view) == EPHY_WEB_VIEW_DOCUMENT_PDF) {
-    g_signal_connect_object (download, "finished", G_CALLBACK (pdf_download_finished_cb), embed, 0);
-    g_signal_connect_object (download, "decide-destination", G_CALLBACK 
(pdf_download_decide_destination_cb), embed, 0);
-  }
-}
diff --git a/embed/ephy-pdf-handler.c b/embed/ephy-pdf-handler.c
new file mode 100644
index 000000000..238842b1d
--- /dev/null
+++ b/embed/ephy-pdf-handler.c
@@ -0,0 +1,299 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2020 Jan-Michael Brummer <jan brummer tabos org>
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany 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.
+ *
+ *  Epiphany 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 Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "ephy-pdf-handler.h"
+
+#include "ephy-embed-container.h"
+#include "ephy-embed-shell.h"
+#include "ephy-web-view.h"
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+struct _EphyPDFHandler {
+  GObject parent_instance;
+
+  GList *outstanding_requests;
+};
+
+G_DEFINE_TYPE (EphyPDFHandler, ephy_pdf_handler, G_TYPE_OBJECT)
+
+typedef struct {
+  EphyPDFHandler *source_handler;
+  WebKitURISchemeRequest *scheme_request;
+  GCancellable *cancellable;
+  EphyDownload *download;
+} EphyPdfRequest;
+
+static EphyPdfRequest *
+ephy_pdf_request_new (EphyPDFHandler         *handler,
+                      WebKitURISchemeRequest *request)
+{
+  EphyPdfRequest *pdf_request;
+
+  pdf_request = g_new (EphyPdfRequest, 1);
+  pdf_request->source_handler = g_object_ref (handler);
+  pdf_request->scheme_request = g_object_ref (request);
+  pdf_request->cancellable = g_cancellable_new ();
+
+  return pdf_request;
+}
+
+static void
+ephy_pdf_request_free (EphyPdfRequest *request)
+{
+  if (request->download) {
+    g_signal_handlers_disconnect_by_data (request->download, request);
+
+    if (ephy_download_is_active (request->download))
+      ephy_download_cancel (request->download);
+  }
+
+  g_object_unref (request->source_handler);
+  g_object_unref (request->scheme_request);
+
+  g_cancellable_cancel (request->cancellable);
+  g_object_unref (request->cancellable);
+
+  g_free (request);
+}
+
+static void
+finish_uri_scheme_request (EphyPdfRequest *request,
+                           gchar          *data,
+                           GError         *error)
+{
+  GInputStream *stream;
+  gssize data_length;
+
+  g_assert ((data && !error) || (!data && error));
+
+  if (error) {
+    webkit_uri_scheme_request_finish_error (request->scheme_request, error);
+  } else {
+    data_length = MIN (strlen (data), G_MAXSSIZE);
+    stream = g_memory_input_stream_new_from_data (data, data_length, g_free);
+    webkit_uri_scheme_request_finish (request->scheme_request, stream, data_length, "text/html");
+    g_object_unref (stream);
+  }
+
+  request->source_handler->outstanding_requests =
+    g_list_remove (request->source_handler->outstanding_requests,
+                   request);
+
+  ephy_pdf_request_free (request);
+}
+
+static void
+pdf_file_deleted (GObject      *source,
+                  GAsyncResult *res,
+                  gpointer      user_data)
+{
+  g_autoptr (GError) error = NULL;
+  if (!g_file_delete_finish (G_FILE (source), res, &error))
+    g_warning ("Could not delete temporary PDF file: %s", error->message);
+}
+
+static void
+pdf_file_loaded (GObject      *source,
+                 GAsyncResult *res,
+                 gpointer      user_data)
+{
+  EphyPdfRequest *self = user_data;
+  GBytes *html_file;
+  g_autoptr (GError) error = NULL;
+  g_autoptr (GString) html = NULL;
+  g_autofree gchar *b64 = NULL;
+  g_autofree gchar *requested_uri = NULL;
+  g_autofree char *file_data = NULL;
+  gsize len = 0;
+
+  if (!g_file_load_contents_finish (G_FILE (source), res, &file_data, &len, NULL, &error)) {
+    if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+      g_warning ("Could not read PDF file content: %s", error->message);
+    return;
+  }
+
+  html_file = g_resources_lookup_data ("/org/gnome/epiphany/pdfjs/web/viewer.html", 0, NULL);
+
+  b64 = g_base64_encode ((const guchar *)file_data, len);
+  g_file_delete_async (G_FILE (source), G_PRIORITY_DEFAULT, NULL, pdf_file_deleted, NULL);
+
+  html = g_string_new ("");
+  g_string_printf (html, g_bytes_get_data (html_file, NULL), b64, g_file_get_basename (G_FILE (source)));
+
+  finish_uri_scheme_request (self, g_strdup (html->str), NULL);
+}
+
+static void
+download_completed_cb (EphyDownload   *download,
+                       EphyPdfRequest *self)
+{
+  g_assert (download);
+  g_assert (self);
+
+  g_signal_handlers_disconnect_by_data (download, self);
+
+  if (g_strcmp0 ("application/pdf", ephy_download_get_content_type (download)) == 0) {
+    g_autoptr (GFile) file = NULL;
+    const char *document_uri = webkit_download_get_destination (ephy_download_get_webkit_download 
(download));
+
+    file = g_file_new_for_uri (document_uri);
+
+    g_file_load_contents_async (file, self->cancellable, pdf_file_loaded, self);
+  } else {
+    g_warning ("PDF %s has invalid MIME type: %s",
+               ephy_download_get_destination_uri (download),
+               ephy_download_get_content_type (download));
+  }
+
+  g_clear_object (&self->download);
+}
+
+static void
+download_errored_cb (EphyDownload   *download,
+                     GError         *error,
+                     EphyPdfRequest *self)
+{
+  g_assert (download);
+  g_assert (error);
+  g_assert (self);
+
+  g_signal_handlers_disconnect_by_data (download, self);
+
+  if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+    WebKitURIRequest *request = webkit_download_get_request (ephy_download_get_webkit_download (download));
+
+    g_warning ("Cannot fetch pdf from <%s>: %s",
+               webkit_uri_request_get_uri (request),
+               error ? error->message : "Unknown error");
+  }
+
+  g_clear_object (&self->download);
+}
+
+static void
+ephy_pdf_request_start (EphyPdfRequest *request)
+{
+  g_autoptr (SoupURI) soup_uri = NULL;
+  g_autofree gchar *tmp_file = NULL;
+  g_autofree gchar *file_uri = NULL;
+  const char *modified_uri;
+  const char *original_uri;
+
+  request->source_handler->outstanding_requests =
+    g_list_prepend (request->source_handler->outstanding_requests, request);
+
+  original_uri = webkit_uri_scheme_request_get_uri (request->scheme_request);
+  soup_uri = soup_uri_new (original_uri);
+
+  if (!soup_uri) {
+    /* Can't assert because user could theoretically input something weird */
+    GError *error = g_error_new (WEBKIT_NETWORK_ERROR,
+                                 WEBKIT_NETWORK_ERROR_FAILED,
+                                 _("%s is not a valid URI"),
+                                 original_uri);
+    finish_uri_scheme_request (request, NULL, error);
+    g_error_free (error);
+    return;
+  }
+
+  modified_uri = soup_uri_get_path (soup_uri);
+  g_assert (modified_uri);
+
+  tmp_file = g_strdup_printf ("%s/%s", g_get_tmp_dir (), g_path_get_basename (modified_uri));
+  file_uri = g_filename_to_uri (tmp_file, NULL, NULL);
+
+  request->download = ephy_download_new_for_uri_internal (modified_uri);
+  ephy_download_set_destination_uri (request->download, file_uri);
+  ephy_download_disable_desktop_notification (request->download);
+  webkit_download_set_allow_overwrite (ephy_download_get_webkit_download (request->download), TRUE);
+
+  g_signal_connect (request->download, "completed", G_CALLBACK (download_completed_cb), request);
+  g_signal_connect (request->download, "error", G_CALLBACK (download_errored_cb), request);
+}
+
+static void
+cancel_outstanding_request (EphyPdfRequest *request)
+{
+  g_cancellable_cancel (request->cancellable);
+}
+
+static void
+ephy_pdf_handler_dispose (GObject *object)
+{
+  EphyPDFHandler *handler = EPHY_PDF_HANDLER (object);
+
+  if (handler->outstanding_requests) {
+    g_list_foreach (handler->outstanding_requests, (GFunc)cancel_outstanding_request, NULL);
+    g_list_free (handler->outstanding_requests);
+    handler->outstanding_requests = NULL;
+  }
+
+  G_OBJECT_CLASS (ephy_pdf_handler_parent_class)->dispose (object);
+}
+
+static void
+ephy_pdf_handler_init (EphyPDFHandler *handler)
+{
+}
+
+static void
+ephy_pdf_handler_class_init (EphyPDFHandlerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = ephy_pdf_handler_dispose;
+}
+
+EphyPDFHandler *
+ephy_pdf_handler_new (void)
+{
+  return EPHY_PDF_HANDLER (g_object_new (EPHY_TYPE_PDF_HANDLER, NULL));
+}
+
+void
+ephy_pdf_handler_handle_request (EphyPDFHandler         *handler,
+                                 WebKitURISchemeRequest *scheme_request)
+{
+  EphyPdfRequest *pdf_request;
+
+  pdf_request = ephy_pdf_request_new (handler, scheme_request);
+  ephy_pdf_request_start (pdf_request);
+}
+
+void
+ephy_pdf_handler_stop (EphyPDFHandler *handler,
+                       WebKitWebView  *web_view)
+{
+  GList *list;
+
+  for (list = handler->outstanding_requests; list; list = list->next) {
+    EphyPdfRequest *request = list->data;
+    WebKitWebView *request_web_view = webkit_uri_scheme_request_get_web_view (request->scheme_request);
+
+    if (request_web_view == web_view) {
+      ephy_pdf_request_free (request);
+      return;
+    }
+  }
+}
diff --git a/embed/ephy-pdf-handler.h b/embed/ephy-pdf-handler.h
new file mode 100644
index 000000000..637826d07
--- /dev/null
+++ b/embed/ephy-pdf-handler.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2020 Jan-Michael Brummer <jan brummer tabos org>
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany 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.
+ *
+ *  Epiphany 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 Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <webkit2/webkit2.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_PDF_HANDLER (ephy_pdf_handler_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyPDFHandler, ephy_pdf_handler, EPHY, PDF_HANDLER, GObject)
+
+#define EPHY_PDF_SCHEME "ephy-pdf"
+
+EphyPDFHandler *ephy_pdf_handler_new            (void);
+
+void            ephy_pdf_handler_handle_request (EphyPDFHandler  *handler,
+                                                 WebKitURISchemeRequest *request);
+
+void            ephy_pdf_handler_stop (EphyPDFHandler *handler,
+                                       WebKitWebView  *webv_view);
+
+G_END_DECLS
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 7e9094cdb..ea87460bf 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -46,6 +46,7 @@
 #include "ephy-snapshot-service.h"
 #include "ephy-string.h"
 #include "ephy-uri-helpers.h"
+#include "ephy-pdf-handler.h"
 #include "ephy-view-source-handler.h"
 #include "ephy-web-app-utils.h"
 #include "ephy-zoom.h"
@@ -854,8 +855,17 @@ decide_policy_cb (WebKitWebView            *web_view,
     } else if (strncmp (mime_type, "image/", 6) == 0) {
       type = EPHY_WEB_VIEW_DOCUMENT_IMAGE;
     } else if (strcmp (mime_type, "application/pdf") == 0) {
+      g_autofree char *pdf_uri = NULL;
+
       /* FIXME: figure out how to make PDFs work in iframes. */
       type = EPHY_WEB_VIEW_DOCUMENT_PDF;
+      EPHY_WEB_VIEW (web_view)->document_type = type;
+
+      pdf_uri = g_strconcat (EPHY_PDF_SCHEME, ":", request_uri, NULL);
+
+      webkit_web_view_load_uri (web_view, pdf_uri);
+
+      return FALSE;
     }
 
     /* FIXME: maybe it makes more sense to have an API to query the mime
@@ -1266,7 +1276,7 @@ update_security_status_for_committed_load (EphyWebView *view,
   SoupURI *soup_uri;
   g_autofree char *tld = NULL;
 
-  if (view->loading_error_page || (view->document_type == EPHY_WEB_VIEW_DOCUMENT_PDF))
+  if (view->loading_error_page)
     return;
 
   toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
@@ -1285,6 +1295,7 @@ update_security_status_for_committed_load (EphyWebView *view,
   if (!soup_uri ||
       strcmp (soup_uri->scheme, EPHY_VIEW_SOURCE_SCHEME) == 0 ||
       strcmp (soup_uri->scheme, EPHY_READER_SCHEME) == 0 ||
+      strcmp (soup_uri->scheme, EPHY_PDF_SCHEME) == 0 ||
       g_strcmp0 (tld, "127.0.0.1") == 0 ||
       g_strcmp0 (tld, "::1") == 0 ||
       g_strcmp0 (tld, "localhost") == 0 || /* We trust localhost to be local since glib!616. */
@@ -1427,6 +1438,9 @@ load_changed_cb (WebKitWebView   *web_view,
       /* Ensure we load the icon for this web view, if available. */
       _ephy_web_view_update_icon (view);
 
+      if (g_str_has_prefix (webkit_web_view_get_uri (web_view), "ephy-pdf"))
+        ephy_embed_shell_pdf_handler_stop (ephy_embed_shell_get_default (), web_view);
+
       /* Reset visit type. */
       view->visit_type = EPHY_PAGE_VISIT_NONE;
 
diff --git a/embed/meson.build b/embed/meson.build
index 72188aae5..ab55cbe14 100644
--- a/embed/meson.build
+++ b/embed/meson.build
@@ -27,6 +27,7 @@ libephyembed_sources = [
   'ephy-file-monitor.c',
   'ephy-filters-manager.c',
   'ephy-find-toolbar.c',
+  'ephy-pdf-handler.c',
   'ephy-reader-handler.c',
   'ephy-view-source-handler.c',
   'ephy-web-view.c',
diff --git a/src/ephy-session.c b/src/ephy-session.c
index 337d0740e..cd7f71c8f 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -876,7 +876,8 @@ session_seems_sane (GList *windows)
         if (uri->host != NULL ||
             uri->scheme == SOUP_URI_SCHEME_DATA ||
             uri->scheme == SOUP_URI_SCHEME_FILE ||
-            strcmp (uri->scheme, "ephy-reader") == 0)
+            strcmp (uri->scheme, "ephy-reader") == 0 ||
+            strcmp (uri->scheme, "ephy-pdf") == 0)
           sane = TRUE;
         soup_uri_free (uri);
       }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]