[gnome-builder/wip/gtk4-port] libide/webkit: add IdeHtmlGenerator abstract class
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port] libide/webkit: add IdeHtmlGenerator abstract class
- Date: Tue, 7 Jun 2022 04:05:21 +0000 (UTC)
commit 456f53118e61063e00f1026a3ca4c6c69d34fc52
Author: Christian Hergert <chergert redhat com>
Date: Mon Jun 6 20:42:44 2022 -0700
libide/webkit: add IdeHtmlGenerator abstract class
This can simplify how we generate HTML and be more extensible in allowing
async operations to occur. The other plugins will be ported shortly.
src/libide/webkit/ide-html-generator.c | 289 +++++++++++++++++++++
src/libide/webkit/ide-html-generator.h | 67 +++++
src/libide/webkit/ide-text-buffer-html-generator.c | 205 +++++++++++++++
src/libide/webkit/ide-text-buffer-html-generator.h | 31 +++
src/libide/webkit/ide-webkit-page.c | 118 ++++-----
src/libide/webkit/ide-webkit-page.h | 10 +-
src/libide/webkit/meson.build | 3 +
7 files changed, 658 insertions(+), 65 deletions(-)
---
diff --git a/src/libide/webkit/ide-html-generator.c b/src/libide/webkit/ide-html-generator.c
new file mode 100644
index 000000000..2fbca2620
--- /dev/null
+++ b/src/libide/webkit/ide-html-generator.c
@@ -0,0 +1,289 @@
+/* ide-html-generator.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-html-generator"
+
+#include "config.h"
+
+#include <libide-threading.h>
+
+#include "ide-html-generator.h"
+#include "ide-text-buffer-html-generator.h"
+
+typedef struct
+{
+ char *base_uri;
+} IdeHtmlGeneratorPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (IdeHtmlGenerator, ide_html_generator, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_BASE_URI,
+ N_PROPS
+};
+
+enum {
+ INVALIDATE,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS];
+static GParamSpec *properties[N_PROPS];
+
+static void
+ide_html_generator_real_generate_async (IdeHtmlGenerator *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(IdeTask) task = NULL;
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, ide_html_generator_real_generate_async);
+ ide_task_return_unsupported_error (task);
+}
+
+static GBytes *
+ide_html_generator_real_generate_finish (IdeHtmlGenerator *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ return ide_task_propagate_pointer (IDE_TASK (result), error);
+}
+
+static void
+ide_html_generator_dispose (GObject *object)
+{
+ IdeHtmlGenerator *self = (IdeHtmlGenerator *)object;
+ IdeHtmlGeneratorPrivate *priv = ide_html_generator_get_instance_private (self);
+
+ g_clear_pointer (&priv->base_uri, g_free);
+
+ G_OBJECT_CLASS (ide_html_generator_parent_class)->dispose (object);
+}
+
+static void
+ide_html_generator_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeHtmlGenerator *self = IDE_HTML_GENERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BASE_URI:
+ g_value_set_string (value, ide_html_generator_get_base_uri (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_html_generator_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeHtmlGenerator *self = IDE_HTML_GENERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BASE_URI:
+ ide_html_generator_set_base_uri (self, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_html_generator_class_init (IdeHtmlGeneratorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_html_generator_dispose;
+ object_class->get_property = ide_html_generator_get_property;
+ object_class->set_property = ide_html_generator_set_property;
+
+ klass->generate_async = ide_html_generator_real_generate_async;
+ klass->generate_finish = ide_html_generator_real_generate_finish;
+
+ /**
+ * IdeHtmlGenerator::invalidate:
+ *
+ * The "invalidate" signal is emitted when contents have changed.
+ *
+ * This signal is emmitted by subclasses when the contents have changed
+ * and HTML will need to be regenerated.
+ */
+ signals [INVALIDATE] =
+ g_signal_new ("invalidate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdeHtmlGeneratorClass, invalidate),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+}
+
+static void
+ide_html_generator_init (IdeHtmlGenerator *self)
+{
+}
+
+/**
+ * ide_html_generator_generate_async:
+ * @self: a #IdeHtmlGenerator
+ * @cancellable: a #GCancellable
+ * @callback: a function to call after completion
+ * @user_data: closure data for @callback
+ *
+ * Asynchronously generate HTML.
+ *
+ * This virtual function should be implemented by subclasses to generate
+ * HTML based on some form of input (which is left to the subclass).
+ *
+ * Upon completion, @callback is called and expected to call
+ * ide_html_generator_generate_finish() to retrieve the result.
+ */
+void
+ide_html_generator_generate_async (IdeHtmlGenerator *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (IDE_IS_HTML_GENERATOR (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ IDE_HTML_GENERATOR_GET_CLASS (self)->generate_async (self, cancellable, callback, user_data);
+}
+
+/**
+ * ide_html_generator_generate_finish:
+ * @self: a #IdeHtmlGenerator
+ * @result: a #GAsyncResult
+ * @error: a location for a #GError
+ *
+ * Completes a request to generate HTML.
+ *
+ * This function is used to complete a request to generate HTML from some
+ * form of input, asynchronously. The content of the HTML is dependent on
+ * the subclass implementation of #IdeHtmlGenerator.
+ *
+ * It is required that the resulting bytes have a NULL terminator at
+ * the end which is not part of the bytes length.
+ *
+ * Returns: (transfer full): a #GBytes if successful; otherwise %NULL
+ * and @error is set.
+ */
+GBytes *
+ide_html_generator_generate_finish (IdeHtmlGenerator *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GBytes *ret;
+
+ g_return_val_if_fail (IDE_IS_HTML_GENERATOR (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ ret = IDE_HTML_GENERATOR_GET_CLASS (self)->generate_finish (self, result, error);
+
+#ifdef G_ENABLE_DEBUG
+ if (ret != NULL)
+ {
+ const guint8 *data;
+ gsize len;
+
+ data = g_bytes_get_data (ret, &len);
+ g_assert (data[len] == 0);
+ }
+#endif
+
+ return ret;
+}
+
+/**
+ * ide_html_generator_invalidate:
+ * @self: a #IdeHtmlGenerator
+ *
+ * Notifies that the last generated HTML is now invalid.
+ *
+ * This is used by subclasses to denote that the HTML contents
+ * have changed and will need to be regenerated.
+ */
+void
+ide_html_generator_invalidate (IdeHtmlGenerator *self)
+{
+ g_return_if_fail (IDE_IS_HTML_GENERATOR (self));
+
+ g_signal_emit (self, signals [INVALIDATE], 0);
+}
+
+/**
+ * ide_html_generator_new_for_buffer:
+ * @buffer: a #GtkTextBuffer
+ *
+ * Create a 1:1 HTML generator for a buffer.
+ *
+ * Creates a #IdeHtmlGenerator that passes the content directly from
+ * what is found in a #GtkTextBuffer.
+ *
+ * Returns: (transfer full): an #IdeHtmlGenerator
+ */
+IdeHtmlGenerator *
+ide_html_generator_new_for_buffer (GtkTextBuffer *buffer)
+{
+ g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+
+ return g_object_new (IDE_TYPE_TEXT_BUFFER_HTML_GENERATOR,
+ "buffer", buffer,
+ NULL);
+}
+
+const char *
+ide_html_generator_get_base_uri (IdeHtmlGenerator *self)
+{
+ IdeHtmlGeneratorPrivate *priv = ide_html_generator_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_HTML_GENERATOR (self), NULL);
+
+ return priv->base_uri;
+}
+
+void
+ide_html_generator_set_base_uri (IdeHtmlGenerator *self,
+ const char *base_uri)
+{
+ IdeHtmlGeneratorPrivate *priv = ide_html_generator_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_HTML_GENERATOR (self));
+
+ if (g_strcmp0 (priv->base_uri, base_uri) != 0)
+ {
+ g_free (priv->base_uri);
+ priv->base_uri = g_strdup (base_uri);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BASE_URI]);
+ }
+}
diff --git a/src/libide/webkit/ide-html-generator.h b/src/libide/webkit/ide-html-generator.h
new file mode 100644
index 000000000..aef2ec92d
--- /dev/null
+++ b/src/libide/webkit/ide-html-generator.h
@@ -0,0 +1,67 @@
+/* ide-html-generator.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_HTML_GENERATOR (ide_html_generator_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE (IdeHtmlGenerator, ide_html_generator, IDE, HTML_GENERATOR, GObject)
+
+struct _IdeHtmlGeneratorClass
+{
+ GObjectClass parent_class;
+
+ void (*invalidate) (IdeHtmlGenerator *self);
+ void (*generate_async) (IdeHtmlGenerator *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ GBytes *(*generate_finish) (IdeHtmlGenerator *self,
+ GAsyncResult *result,
+ GError **error);
+};
+
+IDE_AVAILABLE_IN_ALL
+const char *ide_html_generator_get_base_uri (IdeHtmlGenerator *self);
+IDE_AVAILABLE_IN_ALL
+void ide_html_generator_set_base_uri (IdeHtmlGenerator *self,
+ const char *base_uri);
+IDE_AVAILABLE_IN_ALL
+void ide_html_generator_invalidate (IdeHtmlGenerator *self);
+IDE_AVAILABLE_IN_ALL
+void ide_html_generator_generate_async (IdeHtmlGenerator *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_ALL
+GBytes *ide_html_generator_generate_finish (IdeHtmlGenerator *self,
+ GAsyncResult *result,
+ GError **error);
+IDE_AVAILABLE_IN_ALL
+IdeHtmlGenerator *ide_html_generator_new_for_buffer (GtkTextBuffer *buffer);
+
+G_END_DECLS
diff --git a/src/libide/webkit/ide-text-buffer-html-generator.c
b/src/libide/webkit/ide-text-buffer-html-generator.c
new file mode 100644
index 000000000..5764c2148
--- /dev/null
+++ b/src/libide/webkit/ide-text-buffer-html-generator.c
@@ -0,0 +1,205 @@
+/* ide-text-buffer-html-generator.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-text-buffer-html-generator"
+
+#include "config.h"
+
+#include <libide-code.h>
+#include <libide-threading.h>
+
+#include "ide-text-buffer-html-generator.h"
+
+struct _IdeTextBufferHtmlGenerator
+{
+ IdeHtmlGenerator parent_instance;
+ GSignalGroup *buffer_signals;
+};
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (IdeTextBufferHtmlGenerator, ide_text_buffer_html_generator, IDE_TYPE_HTML_GENERATOR)
+
+static GParamSpec *properties [N_PROPS];
+
+static inline GBytes *
+get_buffer_bytes (GtkTextBuffer *buffer)
+{
+ GtkTextIter begin, end;
+ char *slice;
+
+ gtk_text_buffer_get_bounds (buffer, &begin, &end);
+ slice = gtk_text_iter_get_slice (&begin, &end);
+
+ return g_bytes_new_take (slice, strlen (slice));
+}
+
+static void
+ide_text_buffer_html_generator_generate_async (IdeHtmlGenerator *generator,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeTextBufferHtmlGenerator *self = (IdeTextBufferHtmlGenerator *)generator;
+ g_autoptr(GtkTextBuffer) buffer = NULL;
+ g_autoptr(IdeTask) task = NULL;
+
+ g_assert (IDE_IS_TEXT_BUFFER_HTML_GENERATOR (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, ide_text_buffer_html_generator_generate_async);
+
+ buffer = g_signal_group_dup_target (self->buffer_signals);
+
+ if (IDE_IS_BUFFER (buffer))
+ ide_task_return_pointer (task,
+ ide_buffer_dup_content (IDE_BUFFER (buffer)),
+ g_bytes_unref);
+ else if (GTK_IS_TEXT_BUFFER (buffer))
+ ide_task_return_pointer (task, get_buffer_bytes (buffer), g_bytes_unref);
+ else
+ ide_task_return_pointer (task,
+ g_bytes_new_take (g_strdup (""), 0),
+ g_bytes_unref);
+}
+
+static GBytes *
+ide_text_buffer_html_generator_generate_finish (IdeHtmlGenerator *generator,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (IDE_IS_TEXT_BUFFER_HTML_GENERATOR (generator));
+ g_assert (IDE_IS_TASK (result));
+
+ return ide_task_propagate_pointer (IDE_TASK (result), error);
+}
+
+static gboolean
+file_to_base_uri (GBinding *binding,
+ const GValue *from,
+ GValue *to,
+ gpointer user_data)
+{
+ g_value_set_string (to, g_file_get_uri (g_value_get_object (from)));
+ return TRUE;
+}
+
+static void
+ide_text_buffer_html_generator_set_buffer (IdeTextBufferHtmlGenerator *self,
+ GtkTextBuffer *buffer)
+{
+ g_assert (IDE_IS_TEXT_BUFFER_HTML_GENERATOR (self));
+ g_assert (!buffer || GTK_IS_TEXT_BUFFER (buffer));
+
+ g_signal_group_set_target (self->buffer_signals, buffer);
+
+ if (IDE_IS_BUFFER (buffer))
+ g_object_bind_property_full (buffer, "file",
+ self, "base-uri",
+ G_BINDING_SYNC_CREATE,
+ file_to_base_uri,
+ NULL, NULL, NULL);
+}
+
+static void
+ide_text_buffer_html_generator_dispose (GObject *object)
+{
+ IdeTextBufferHtmlGenerator *self = (IdeTextBufferHtmlGenerator *)object;
+
+ g_clear_object (&self->buffer_signals);
+
+ G_OBJECT_CLASS (ide_text_buffer_html_generator_parent_class)->dispose (object);
+}
+
+static void
+ide_text_buffer_html_generator_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeTextBufferHtmlGenerator *self = IDE_TEXT_BUFFER_HTML_GENERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ g_value_take_object (value, g_signal_group_dup_target (self->buffer_signals));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_text_buffer_html_generator_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeTextBufferHtmlGenerator *self = IDE_TEXT_BUFFER_HTML_GENERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ ide_text_buffer_html_generator_set_buffer (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_text_buffer_html_generator_class_init (IdeTextBufferHtmlGeneratorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeHtmlGeneratorClass *generator_class = IDE_HTML_GENERATOR_CLASS (klass);
+
+ object_class->dispose = ide_text_buffer_html_generator_dispose;
+ object_class->get_property = ide_text_buffer_html_generator_get_property;
+ object_class->set_property = ide_text_buffer_html_generator_set_property;
+
+ generator_class->generate_async = ide_text_buffer_html_generator_generate_async;
+ generator_class->generate_finish = ide_text_buffer_html_generator_generate_finish;
+
+ properties [PROP_BUFFER] =
+ g_param_spec_object ("buffer", NULL, NULL,
+ GTK_TYPE_TEXT_BUFFER,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_text_buffer_html_generator_init (IdeTextBufferHtmlGenerator *self)
+{
+ self->buffer_signals = g_signal_group_new (GTK_TYPE_TEXT_BUFFER);
+
+ g_signal_group_connect_object (self->buffer_signals,
+ "changed",
+ G_CALLBACK (ide_html_generator_invalidate),
+ self,
+ G_CONNECT_SWAPPED);
+}
diff --git a/src/libide/webkit/ide-text-buffer-html-generator.h
b/src/libide/webkit/ide-text-buffer-html-generator.h
new file mode 100644
index 000000000..843910b33
--- /dev/null
+++ b/src/libide/webkit/ide-text-buffer-html-generator.h
@@ -0,0 +1,31 @@
+/* ide-text-buffer-html-generator.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ide-html-generator.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_TEXT_BUFFER_HTML_GENERATOR (ide_text_buffer_html_generator_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeTextBufferHtmlGenerator, ide_text_buffer_html_generator, IDE,
TEXT_BUFFER_HTML_GENERATOR, IdeHtmlGenerator)
+
+G_END_DECLS
diff --git a/src/libide/webkit/ide-webkit-page.c b/src/libide/webkit/ide-webkit-page.c
index ab8cb5ae9..b5bc30680 100644
--- a/src/libide/webkit/ide-webkit-page.c
+++ b/src/libide/webkit/ide-webkit-page.c
@@ -27,8 +27,6 @@
#include "ide-webkit-page.h"
#include "ide-url-bar.h"
-#define UPDATE_DELAY_MSEC 250
-
typedef struct
{
GtkStack *reload_stack;
@@ -39,12 +37,11 @@ typedef struct
GSimpleActionGroup *actions;
- /* Used for pages linked to buffers */
- GtkTextBuffer *buffer;
- IdeHtmlTransformFunc transform_func;
- gpointer transform_data;
- GDestroyNotify transform_data_destroy;
- guint queued_update_source;
+ IdeHtmlGenerator *generator;
+
+ guint dirty : 1;
+ guint generating : 1;
+ guint disposed : 1;
} IdeWebkitPagePrivate;
enum {
@@ -343,17 +340,10 @@ ide_webkit_page_dispose (GObject *object)
IdeWebkitPage *self = (IdeWebkitPage *)object;
IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
- if (priv->transform_data_destroy)
- {
- GDestroyNotify notify = g_steal_pointer (&priv->transform_data_destroy);
- gpointer data = g_steal_pointer (&priv->transform_data);
- priv->transform_func = NULL;
- notify (data);
- }
+ priv->disposed = TRUE;
+ g_clear_object (&priv->generator);
g_clear_object (&priv->actions);
- g_clear_object (&priv->buffer);
- g_clear_handle_id (&priv->queued_update_source, g_source_remove);
G_OBJECT_CLASS (ide_webkit_page_parent_class)->dispose (object);
}
@@ -593,79 +583,91 @@ ide_webkit_page_reload_ignoring_cache (IdeWebkitPage *self)
webkit_web_view_reload_bypass_cache (priv->web_view);
}
-static gboolean
-ide_webkit_page_do_update_cb (gpointer user_data)
+static void
+ide_webkit_page_generate_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- IdeWebkitPage *self = user_data;
+ IdeHtmlGenerator *generator = (IdeHtmlGenerator *)object;
+ g_autoptr(IdeWebkitPage) self = user_data;
IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
- g_autofree char *base_uri = NULL;
- g_autofree char *text = NULL;
- GtkTextIter begin, end;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GBytes) bytes = NULL;
- g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_HTML_GENERATOR (generator));
+ g_assert (G_IS_ASYNC_RESULT (result));
g_assert (IDE_IS_WEBKIT_PAGE (self));
- g_assert (GTK_IS_TEXT_BUFFER (priv->buffer));
-
- priv->queued_update_source = 0;
-
- gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
- text = gtk_text_iter_get_slice (&begin, &end);
- if (IDE_IS_BUFFER (priv->buffer))
- base_uri = g_file_get_uri (ide_buffer_get_file (IDE_BUFFER (priv->buffer)));
+ priv->generating = FALSE;
- if (priv->transform_func != NULL)
+ if (!(bytes = ide_html_generator_generate_finish (generator, result, &error)))
{
- g_autofree char *input = g_steal_pointer (&text);
- text = priv->transform_func (input, priv->transform_data);
+ /* Don't try to spin again in this case by checking dirty */
+ g_warning ("Failed to generate HTML: %s", error->message);
+ return;
}
- webkit_web_view_load_html (priv->web_view, text, base_uri);
+ if (priv->disposed)
+ return;
+
+ webkit_web_view_load_html (priv->web_view,
+ (const char *)g_bytes_get_data (bytes, NULL),
+ ide_html_generator_get_base_uri (generator));
- return G_SOURCE_REMOVE;
+ /* See if we need to run again, and check for re-entrantcy */
+ if (priv->dirty && !priv->generating)
+ {
+ priv->dirty = FALSE;
+ priv->generating = TRUE;
+ ide_html_generator_generate_async (generator,
+ NULL,
+ ide_webkit_page_generate_cb,
+ g_steal_pointer (&self));
+ }
}
static void
-ide_webkit_page_buffer_changed_cb (IdeWebkitPage *self,
- GtkTextBuffer *buffer)
+ide_webkit_page_generator_invalidate_cb (IdeWebkitPage *self,
+ IdeHtmlGenerator *generator)
{
IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_WEBKIT_PAGE (self));
- g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (IDE_IS_HTML_GENERATOR (generator));
+
+ priv->dirty = TRUE;
- if (priv->queued_update_source == 0)
- priv->queued_update_source = g_timeout_add (UPDATE_DELAY_MSEC,
- ide_webkit_page_do_update_cb,
- self);
+ if (priv->generating)
+ return;
+
+ priv->generating = TRUE;
+ priv->dirty = FALSE;
+
+ ide_html_generator_generate_async (generator,
+ NULL,
+ ide_webkit_page_generate_cb,
+ g_object_ref (self));
}
IdeWebkitPage *
-ide_webkit_page_new_for_buffer (GtkTextBuffer *buffer,
- IdeHtmlTransformFunc transform_func,
- gpointer transform_data,
- GDestroyNotify transform_data_destroy)
+ide_webkit_page_new_for_generator (IdeHtmlGenerator *generator)
{
IdeWebkitPage *self;
IdeWebkitPagePrivate *priv;
- g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+ g_return_val_if_fail (IDE_IS_HTML_GENERATOR (generator), NULL);
self = ide_webkit_page_new ();
priv = ide_webkit_page_get_instance_private (self);
- priv->transform_func = transform_func;
- priv->transform_data = transform_data;
- priv->transform_data_destroy = transform_data_destroy;
-
- priv->buffer = g_object_ref (buffer);
- g_signal_connect_object (buffer,
- "changed",
- G_CALLBACK (ide_webkit_page_buffer_changed_cb),
+ priv->generator = g_object_ref (generator);
+ g_signal_connect_object (priv->generator,
+ "invalidate",
+ G_CALLBACK (ide_webkit_page_generator_invalidate_cb),
self,
G_CONNECT_SWAPPED);
- ide_webkit_page_buffer_changed_cb (self, buffer);
+ ide_webkit_page_generator_invalidate_cb (self, generator);
return self;
}
diff --git a/src/libide/webkit/ide-webkit-page.h b/src/libide/webkit/ide-webkit-page.h
index 26e47335c..091511fbe 100644
--- a/src/libide/webkit/ide-webkit-page.h
+++ b/src/libide/webkit/ide-webkit-page.h
@@ -22,13 +22,12 @@
#include <libide-gui.h>
+#include "ide-html-generator.h"
+
G_BEGIN_DECLS
#define IDE_TYPE_WEBKIT_PAGE (ide_webkit_page_get_type())
-typedef char *(*IdeHtmlTransformFunc) (const char *input,
- gpointer user_data);
-
IDE_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE (IdeWebkitPage, ide_webkit_page, IDE, WEBKIT_PAGE, IdePage)
@@ -40,10 +39,7 @@ struct _IdeWebkitPageClass
IDE_AVAILABLE_IN_ALL
IdeWebkitPage *ide_webkit_page_new (void);
IDE_AVAILABLE_IN_ALL
-IdeWebkitPage *ide_webkit_page_new_for_buffer (GtkTextBuffer *buffer,
- IdeHtmlTransformFunc transform_func,
- gpointer transform_data,
- GDestroyNotify transform_data_destroy);
+IdeWebkitPage *ide_webkit_page_new_for_generator (IdeHtmlGenerator *generator);
IDE_AVAILABLE_IN_ALL
void ide_webkit_page_load_uri (IdeWebkitPage *self,
const char *uri);
diff --git a/src/libide/webkit/meson.build b/src/libide/webkit/meson.build
index c06cc4246..43011c64a 100644
--- a/src/libide/webkit/meson.build
+++ b/src/libide/webkit/meson.build
@@ -13,6 +13,7 @@ libide_include_directories += include_directories('.')
libide_webkit_private_sources = [
'ide-webkit-plugin.c',
'ide-webkit-util.c',
+ 'ide-text-buffer-html-generator.c',
'ide-url-bar.c',
]
@@ -22,10 +23,12 @@ libide_webkit_private_sources = [
libide_webkit_public_headers = [
'libide-webkit.h',
+ 'ide-html-generator.h',
'ide-webkit-page.h',
]
libide_webkit_public_sources = [
+ 'ide-html-generator.c',
'ide-webkit-page.c',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]