[epiphany] implement search engine manager



commit 1d7ba9ca27853f8d13072da5814d15334a13a694
Author: cedlemo <cedlemo gmx com>
Date:   Fri Feb 24 12:21:00 2017 -0600

    implement search engine manager
    
    https://bugzilla.gnome.org/show_bug.cgi?id=776738

 data/org.gnome.epiphany.gschema.xml        |   27 ++-
 embed/ephy-embed-shell.c                   |   12 +
 embed/ephy-embed-shell.h                   |    2 +
 embed/ephy-embed-utils.c                   |   64 +++++-
 lib/Makefile.am                            |    2 +
 lib/ephy-prefs.h                           |    2 +
 lib/ephy-search-engine-manager.c           |  337 ++++++++++++++++++++++++++++
 lib/ephy-search-engine-manager.h           |   67 ++++++
 src/search-provider/ephy-search-provider.c |   29 ++-
 tests/ephy-embed-utils-test.c              |    7 +
 tests/ephy-web-view-test.c                 |   34 ++--
 11 files changed, 535 insertions(+), 48 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index 32ea34d..6540572 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -16,16 +16,25 @@
                        <description>Address of the user’s home page.</description>
                </key>
                <key type="s" name="keyword-search-url">
-                       <!-- DuckDuckGo is the default search engine. Must exactly match the URL used
-                            in the preferences dialog, except this string is surrounded by single quotes
-                            and uses &amp; instead of simply &. If the match is not otherwise exact,
-                            there will be a spurious, ugly entry in the preferences combo, so please
-                            test this. Should ideally also match the default smart bookmark link in
-                            default-bookmarks.rdf. See the comment there for region parameters to
-                            the URL. -->
-                       <default l10n="messages">'https://duckduckgo.com/?q=%s&amp;t=epiphany'</default>
+                       <default>'https://duckduckgo.com/?q=%s&amp;t=epiphany'</default>
                        <summary>URL Search</summary>
-                       <description>Search string for keywords entered in the URL bar.</description>
+                       <description>DEPRECATED: This key is deprecated and ignored. Use 
/org/gnome/epiphany/search-engines instead.</description>
+               </key>
+               <key type="s" name="default-search-engine">
+                       <default>'DuckDuckGo'</default>
+                       <summary>Default search engine.</summary>
+                       <description>Name of the search engine selected by default.</description>
+               </key>
+               <key type="a(sss)" name="search-engines">
+                       <default l10n="messages">
+                                 <!-- TRANSLATORS: These are the prepopulated search engines. You should
+                                      add country-specific URL query parameters if appropriate. -->
+                                 [('DuckDuckGo', 'https://duckduckgo.com/?q=%s&amp;t=epiphany', '!ddg'),
+                                 ('Google', 'https://www.google.com/search?q=%s', '!g'),
+                                 ('Bing', 'https://www.bing.com/search?q=%s', '!b')]
+                       </default>
+                       <summary>Default search engines.</summary>
+                       <description>List of the default search engines. It is an array in which each search 
engine is described by a name, an address, and a bang (shortcut).</description>
                </key>
                <key type="s" name="user-agent">
                        <default>''</default>
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 5779c38..eb5f0a9 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -67,6 +67,7 @@ typedef struct {
   GDBusServer *dbus_server;
   GList *web_extensions;
   EphyFiltersManager *filters_manager;
+  EphySearchEngineManager *search_engine_manager;
   GCancellable *cancellable;
 } EphyEmbedShellPrivate;
 
@@ -121,6 +122,7 @@ ephy_embed_shell_dispose (GObject *object)
   g_clear_object (&priv->web_context);
   g_clear_object (&priv->dbus_server);
   g_clear_object (&priv->filters_manager);
+  g_clear_object (&priv->search_engine_manager);
 
   G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object);
 }
@@ -1451,3 +1453,13 @@ ephy_embed_shell_get_permissions_manager (EphyEmbedShell *shell)
 
   return priv->permissions_manager;
 }
+
+EphySearchEngineManager *
+ephy_embed_shell_get_search_engine_manager (EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  if (!priv->search_engine_manager)
+    priv->search_engine_manager = ephy_search_engine_manager_new ();
+  return priv->search_engine_manager;
+}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index 8004002..43f40b2 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -27,6 +27,7 @@
 #include "ephy-encodings.h"
 #include "ephy-history-service.h"
 #include "ephy-permissions-manager.h"
+#include "ephy-search-engine-manager.h"
 
 G_BEGIN_DECLS
 
@@ -79,5 +80,6 @@ void               ephy_embed_shell_schedule_thumbnail_update  (EphyEmbedShell
 WebKitUserContentManager *ephy_embed_shell_get_user_content_manager (EphyEmbedShell *shell);
 EphyDownloadsManager     *ephy_embed_shell_get_downloads_manager    (EphyEmbedShell *shell);
 EphyPermissionsManager   *ephy_embed_shell_get_permissions_manager  (EphyEmbedShell *shell);
+EphySearchEngineManager  *ephy_embed_shell_get_search_engine_manager (EphyEmbedShell *shell);
 
 G_END_DECLS
diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c
index 9157583..9fa7c52 100644
--- a/embed/ephy-embed-utils.c
+++ b/embed/ephy-embed-utils.c
@@ -28,10 +28,10 @@
 #include "ephy-settings.h"
 #include "ephy-string.h"
 
-#include <string.h>
+#include <JavaScriptCore/JavaScript.h>
 #include <glib/gi18n.h>
 #include <libsoup/soup.h>
-#include <JavaScriptCore/JavaScript.h>
+#include <string.h>
 
 static GRegex *non_search_regex;
 static GRegex *domain_regex;
@@ -167,6 +167,33 @@ is_public_domain (const char *address)
   return retval;
 }
 
+static gboolean
+is_bang_search (const char *address)
+{
+  EphyEmbedShell *shell;
+  EphySearchEngineManager *search_engine_manager;
+  char **bangs;
+  GString *buffer;
+
+  shell = ephy_embed_shell_get_default ();
+  search_engine_manager = ephy_embed_shell_get_search_engine_manager (shell);
+  bangs = ephy_search_engine_manager_get_bangs (search_engine_manager);
+
+  for (uint i = 0; bangs[i] != NULL; i++) {
+    buffer = g_string_new (bangs[i]);
+    g_string_append (buffer, " ");
+
+    if (strstr (address, buffer->str) == address) {
+      g_string_free (buffer, TRUE);
+      return TRUE;
+    }
+    g_string_free (buffer, TRUE);
+  }
+  g_free (bangs);
+
+  return FALSE;
+}
+
 gboolean
 ephy_embed_utils_address_is_valid (const char *address)
 {
@@ -181,7 +208,8 @@ ephy_embed_utils_address_is_valid (const char *address)
   retval = scheme ||
            ephy_embed_utils_address_is_existing_absolute_filename (address) ||
            g_regex_match (get_non_search_regex (), address, 0, NULL) ||
-           is_public_domain (address);
+           is_public_domain (address) ||
+           is_bang_search (address);
 
   g_free (scheme);
 
@@ -195,6 +223,16 @@ ephy_embed_utils_normalize_address (const char *address)
 
   g_return_val_if_fail (address, NULL);
 
+  if (is_bang_search (address)) {
+    EphyEmbedShell *shell;
+    EphySearchEngineManager *search_engine_manager;
+
+    shell = ephy_embed_shell_get_default ();
+    search_engine_manager = ephy_embed_shell_get_search_engine_manager (shell);
+    return ephy_search_engine_manager_parse_bang_search (search_engine_manager,
+                                                         address);
+  }
+
   if (ephy_embed_utils_address_is_existing_absolute_filename (address))
     return g_strconcat ("file://", address, NULL);
 
@@ -229,25 +267,27 @@ ephy_embed_utils_normalize_address (const char *address)
 char *
 ephy_embed_utils_autosearch_address (const char *search_key)
 {
-  char *query_param, *url_search;
+  char *query_param;
+  const char *address_search;
+  char *default_name;
   char *effective_address;
+  EphyEmbedShell *shell;
+  EphySearchEngineManager *search_engine_manager;
 
-  url_search = g_settings_get_string (EPHY_SETTINGS_MAIN,
-                                      EPHY_PREFS_KEYWORD_SEARCH_URL);
-  if (url_search == NULL || url_search[0] == '\0') {
-    g_free (url_search);
-    url_search = g_strdup (_("https://duckduckgo.com/?q=%s&amp;t=epiphany";));
-  }
+  shell = ephy_embed_shell_get_default ();
+  search_engine_manager = ephy_embed_shell_get_search_engine_manager (shell);
+  default_name = ephy_search_engine_manager_get_default_engine (search_engine_manager);
+  address_search = ephy_search_engine_manager_get_address (search_engine_manager, default_name);
 
   query_param = soup_form_encode ("q", search_key, NULL);
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
   /* Format string under control of user input... but gsettings is trusted input. */
   /* + 2 here is getting rid of 'q=' */
-  effective_address = g_strdup_printf (url_search, query_param + 2);
+  effective_address = g_strdup_printf (address_search, query_param + 2);
 #pragma GCC diagnostic pop
   g_free (query_param);
-  g_free (url_search);
+  g_free (default_name);
 
   return effective_address;
 }
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c4b636a..bd2767f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -31,6 +31,8 @@ libephymisc_la_SOURCES = \
        ephy-prefs.h                            \
        ephy-profile-utils.c                    \
        ephy-profile-utils.h                    \
+       ephy-search-engine-manager.c            \
+       ephy-search-engine-manager.h            \
        ephy-security-levels.c                  \
        ephy-security-levels.h                  \
        ephy-settings.c                         \
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index f3eb4e2..919037e 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -139,6 +139,8 @@ static const char * const ephy_prefs_web_schema[] = {
 #define EPHY_PREFS_SYNC_USER                          "sync-user"
 #define EPHY_PREFS_SYNC_TIME                          "sync-time"
 #define EPHY_PREFS_ADBLOCK_FILTERS                    "adblock-filters"
+#define EPHY_PREFS_SEARCH_ENGINES                     "search-engines"
+#define EPHY_PREFS_DEFAULT_SEARCH_ENGINE              "default-search-engine"
 
 #define EPHY_PREFS_LOCKDOWN_SCHEMA            "org.gnome.Epiphany.lockdown"
 #define EPHY_PREFS_LOCKDOWN_FULLSCREEN        "disable-fullscreen"
diff --git a/lib/ephy-search-engine-manager.c b/lib/ephy-search-engine-manager.c
new file mode 100644
index 0000000..d8c6b74
--- /dev/null
+++ b/lib/ephy-search-engine-manager.c
@@ -0,0 +1,337 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2017 Cedric Le Moigne <cedlemo gmx com>
+ *
+ *  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-search-engine-manager.h"
+
+#include "ephy-file-helpers.h"
+#include "ephy-string.h"
+
+#include "ephy-settings.h"
+#include "ephy-prefs.h"
+
+struct _EphySearchEngineManager
+{
+  GObject parent_instance;
+  GHashTable *search_engines;
+};
+
+typedef struct
+{
+  char *address;
+  char *bang;
+} EphySearchEngineInfo;
+
+G_DEFINE_TYPE (EphySearchEngineManager, ephy_search_engine_manager, G_TYPE_OBJECT)
+
+static void
+ephy_search_engine_info_free (EphySearchEngineInfo *info)
+{
+  g_free (info->address);
+  g_free (info->bang);
+  g_free (info);
+}
+
+static EphySearchEngineInfo *
+ephy_search_engine_info_new (const char *address,
+                             const char *bang)
+{
+  EphySearchEngineInfo *info;
+  info = g_malloc (sizeof (EphySearchEngineInfo));
+  info->address = g_strdup (address);
+  info->bang = g_strdup (bang);
+  return info;
+}
+
+static void
+ephy_search_engine_manager_init (EphySearchEngineManager *manager)
+{
+  const char *address;
+  const char *bang;
+  char *name;
+  GVariantIter *iter = NULL;
+
+  manager->search_engines = g_hash_table_new_full (g_str_hash,
+                                                   g_str_equal,
+                                                   g_free,
+                                                   (GDestroyNotify)ephy_search_engine_info_free);
+
+  g_settings_get (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, "a(sss)", &iter);
+
+  while (g_variant_iter_next (iter, "(s&s&s)", &name, &address, &bang)) {
+    g_hash_table_insert (manager->search_engines,
+                         name,
+                         ephy_search_engine_info_new (address,
+                                                      bang));
+  }
+}
+
+static void
+ephy_search_engine_manager_dispose (GObject *object)
+{
+  EphySearchEngineManager *manager = EPHY_SEARCH_ENGINE_MANAGER (object);
+
+  g_clear_pointer (&manager->search_engines, g_hash_table_destroy);
+
+  G_OBJECT_CLASS (ephy_search_engine_manager_parent_class)->dispose (object);
+}
+
+static void
+ephy_search_engine_manager_class_init (EphySearchEngineManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = ephy_search_engine_manager_dispose;
+}
+
+EphySearchEngineManager *
+ephy_search_engine_manager_new (void)
+{
+  return EPHY_SEARCH_ENGINE_MANAGER (g_object_new (EPHY_TYPE_SEARCH_ENGINE_MANAGER, NULL));
+}
+
+const char *
+ephy_search_engine_manager_get_address (EphySearchEngineManager *manager,
+                                        const char              *name)
+{
+  EphySearchEngineInfo *info;
+
+  info = (EphySearchEngineInfo *) g_hash_table_lookup (manager->search_engines, name);
+
+  if (info)
+    return info->address;
+
+  return NULL;
+}
+
+const char *
+ephy_search_engine_manager_get_bang (EphySearchEngineManager *manager,
+                                     const char              *name)
+{
+  EphySearchEngineInfo *info;
+
+  info = (EphySearchEngineInfo *) g_hash_table_lookup (manager->search_engines, name);
+
+  if (info)
+    return info->bang;
+
+  return NULL;
+}
+
+char *
+ephy_search_engine_manager_get_default_engine (EphySearchEngineManager *manager)
+{
+  return g_settings_get_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_DEFAULT_SEARCH_ENGINE);
+}
+
+gboolean
+ephy_search_engine_manager_set_default_engine (EphySearchEngineManager *manager,
+                                               const char              *name)
+{
+  if (!g_hash_table_contains (manager->search_engines, name))
+    return FALSE;
+
+  return g_settings_set_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_DEFAULT_SEARCH_ENGINE, name);
+}
+
+char **
+ephy_search_engine_manager_get_names (EphySearchEngineManager *manager)
+{
+  GHashTableIter iter;
+  gpointer key;
+  char **search_engine_names;
+  guint size;
+  guint i = 0;
+
+  size = g_hash_table_size (manager->search_engines);
+  search_engine_names = g_new0 (char *, size + 1);
+
+  g_hash_table_iter_init (&iter, manager->search_engines);
+
+  while (g_hash_table_iter_next (&iter, &key, NULL))
+    search_engine_names[i++] = g_strdup((char *) key);
+
+  return search_engine_names;
+}
+
+char **
+ephy_search_engine_manager_get_bangs (EphySearchEngineManager *manager)
+{
+  GHashTableIter iter;
+  gpointer value;
+  char **search_engine_bangs;
+  guint size;
+  guint i = 0;
+
+  size = g_hash_table_size (manager->search_engines);
+  search_engine_bangs = g_new0 (char *, size + 1);
+
+  g_hash_table_iter_init (&iter, manager->search_engines);
+
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    search_engine_bangs[i++] = ((EphySearchEngineInfo *)value)->bang;
+
+  return search_engine_bangs;
+}
+
+static void
+ephy_search_engine_manager_apply_settings (EphySearchEngineManager *manager)
+{
+  GHashTableIter iter;
+  EphySearchEngineInfo *info;
+  gpointer key;
+  gpointer value;
+  GVariantBuilder builder;
+  GVariant *variant;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sss)"));
+  g_hash_table_iter_init (&iter, manager->search_engines);
+
+  while (g_hash_table_iter_next (&iter, &key, &value)) {
+    info = (EphySearchEngineInfo *) value;
+    g_variant_builder_add (&builder, "(sss)", key, info->address, info->bang);
+  }
+  variant = g_variant_builder_end (&builder);
+  g_settings_set_value (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, variant);
+}
+
+void
+ephy_search_engine_manager_add_engine (EphySearchEngineManager *manager,
+                                       const char              *name,
+                                       const char              *address,
+                                       const char              *bang)
+{
+  EphySearchEngineInfo *info;
+
+  info = ephy_search_engine_info_new (address, bang);
+  g_hash_table_insert (manager->search_engines, g_strdup (name), info);
+  ephy_search_engine_manager_apply_settings (manager);
+}
+
+void
+ephy_search_engine_manager_delete_engine (EphySearchEngineManager *manager,
+                                          const char              *name)
+{
+  g_hash_table_remove (manager->search_engines, name);
+  ephy_search_engine_manager_apply_settings (manager);
+}
+
+void
+ephy_search_engine_manager_modify_engine (EphySearchEngineManager *manager,
+                                          const char              *name,
+                                          const char              *address,
+                                          const char              *bang)
+{
+  EphySearchEngineInfo *info;
+
+  info = ephy_search_engine_info_new (address, bang);
+  g_hash_table_replace (manager->search_engines,
+                        g_strdup (name),
+                        info);
+  ephy_search_engine_manager_apply_settings (manager);
+}
+
+const char *
+ephy_search_engine_manager_engine_from_bang (EphySearchEngineManager *manager,
+                                             const char              *bang)
+{
+  GHashTableIter iter;
+  EphySearchEngineInfo *info;
+  gpointer key;
+  gpointer value;
+
+  g_hash_table_iter_init (&iter, manager->search_engines);
+
+  while (g_hash_table_iter_next (&iter, &key, &value)) {
+    info = (EphySearchEngineInfo *) value;
+    if (g_strcmp0(bang, info->bang) == 0)
+      return (const char *)key;
+  }
+
+  return NULL;
+}
+
+static char *
+ephy_search_engine_manager_replace_pattern (const char *string,
+                                            const char *pattern,
+                                            const char *replace)
+{
+  gchar **strings;
+  GString *buffer;
+
+  strings = g_strsplit (string, pattern, -1);
+
+  buffer = g_string_new (NULL);
+
+  for (guint i = 0; strings[i] != NULL; i++) {
+    if (i > 0)
+      g_string_append (buffer, replace);
+
+    g_string_append (buffer, strings[i]);
+  }
+
+  g_strfreev (strings);
+
+  return g_string_free (buffer, FALSE);
+}
+
+char *
+ephy_search_engine_manager_build_search_address (EphySearchEngineManager *manager,
+                                                 const char              *name,
+                                                 const char              *search)
+{
+  EphySearchEngineInfo *info;
+
+  info = (EphySearchEngineInfo *) g_hash_table_lookup (manager->search_engines, name);
+
+  if (info == NULL)
+    return NULL;
+
+  return ephy_search_engine_manager_replace_pattern (info->address, "%s", search);
+}
+
+char *
+ephy_search_engine_manager_parse_bang_search (EphySearchEngineManager *manager,
+                                              const char              *search)
+{
+  GHashTableIter iter;
+  EphySearchEngineInfo *info;
+  gpointer value;
+  GString *buffer;
+  char *search_address = NULL;
+
+  g_hash_table_iter_init (&iter, manager->search_engines);
+
+  while (g_hash_table_iter_next (&iter, NULL, &value)) {
+    info = (EphySearchEngineInfo *) value;
+    buffer = g_string_new (info->bang);
+    g_string_append (buffer, " ");
+    if (strstr (search, buffer->str) == search) {
+      search_address = ephy_search_engine_manager_replace_pattern (info->address,
+                                                                   "%s",
+                                                                   (search + buffer->len));
+      g_string_free (buffer, TRUE);
+      return search_address;
+    }
+    g_string_free (buffer, TRUE);
+  }
+
+  return search_address;
+}
diff --git a/lib/ephy-search-engine-manager.h b/lib/ephy-search-engine-manager.h
new file mode 100644
index 0000000..2e92396
--- /dev/null
+++ b/lib/ephy-search-engine-manager.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2017 Cedric Le Moigne <cedlemo gmx com>
+ *
+ *  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 <gio/gio.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+G_BEGIN_DECLS
+
+/* TRANSLATORS: Please modify the main address of duckduckgo in order to match
+ * the version used in your country. For example for the french version :
+ * replace the ".com" with ".fr" :  "https://duckduckgo.fr/?q=%s&amp;t=epiphany";
+*/
+#define EPHY_SEARCH_ENGINE_DEFAULT_ADDRESS _("https://duckduckgo.com/?q=%s&amp;t=epiphany";)
+
+#define EPHY_TYPE_SEARCH_ENGINE_MANAGER (ephy_search_engine_manager_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphySearchEngineManager, ephy_search_engine_manager, EPHY, SEARCH_ENGINE_MANAGER, 
GObject)
+
+EphySearchEngineManager     *ephy_search_engine_manager_new                      (void);
+const char                  *ephy_search_engine_manager_get_address              (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name);
+const char                  *ephy_search_engine_manager_get_bang                 (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name);
+char                        *ephy_search_engine_manager_get_default_engine       (EphySearchEngineManager 
*manager);
+gboolean                     ephy_search_engine_manager_set_default_engine       (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name);
+char                       **ephy_search_engine_manager_get_names                (EphySearchEngineManager 
*manager);
+char                       **ephy_search_engine_manager_get_bangs                (EphySearchEngineManager 
*manager);
+void                         ephy_search_engine_manager_add_engine               (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name,
+                                                                                  const char              
*address,
+                                                                                  const char              
*bang);
+void                         ephy_search_engine_manager_delete_engine            (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name);
+void                         ephy_search_engine_manager_modify_engine            (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name,
+                                                                                  const char              
*address,
+                                                                                  const char              
*bang);
+const char                  *ephy_search_engine_manager_engine_from_bang         (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*bang);
+char                        *ephy_search_engine_manager_build_search_address     (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*name,
+                                                                                  const char              
*search);
+char                        *ephy_search_engine_manager_parse_bang_search        (EphySearchEngineManager 
*manager,
+                                                                                  const char              
*search);
+
+G_END_DECLS
diff --git a/src/search-provider/ephy-search-provider.c b/src/search-provider/ephy-search-provider.c
index 977fa7d..d8a8d4b 100644
--- a/src/search-provider/ephy-search-provider.c
+++ b/src/search-provider/ephy-search-provider.c
@@ -29,11 +29,11 @@
 #include "ephy-profile-utils.h"
 #include "ephy-shell.h"
 
-#include <string.h>
-#include <glib/gi18n.h>
 #include <gio/gio.h>
 #include <gio/gdesktopappinfo.h>
+#include <glib/gi18n.h>
 #include <libsoup/soup.h>
+#include <string.h>
 
 struct _EphySearchProvider {
   GApplication parent_instance;
@@ -277,15 +277,18 @@ launch_search (EphySearchProvider *self,
                char              **terms,
                guint               timestamp)
 {
-  char *search_string, *url_search, *query_param, *effective_url;
-
-  url_search = g_settings_get_string (self->settings, EPHY_PREFS_KEYWORD_SEARCH_URL);
-
-  if (url_search == NULL || url_search[0] == '\0') {
-    g_free (url_search);
-
-    url_search = g_strdup (_("https://duckduckgo.com/?q=%s&amp;t=epiphany";));
-  }
+  char *search_string;
+  const char *address_search;
+  char *query_param;
+  char *effective_url;
+  char *default_name;
+  EphyEmbedShell *shell;
+  EphySearchEngineManager *search_engine_manager;
+
+  shell = ephy_embed_shell_get_default ();
+  search_engine_manager = ephy_embed_shell_get_search_engine_manager (shell);
+  default_name = ephy_search_engine_manager_get_default_engine (search_engine_manager);
+  address_search = ephy_search_engine_manager_get_address (search_engine_manager, default_name);
 
   search_string = g_strjoinv (" ", terms);
   query_param = soup_form_encode ("q", search_string, NULL);
@@ -294,15 +297,15 @@ launch_search (EphySearchProvider *self,
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
   /* Format string under control of user input... but gsettings is trusted input. */
   /* + 2 here is getting rid of 'q=' */
-  effective_url = g_strdup_printf (url_search, query_param + 2);
+  effective_url = g_strdup_printf (address_search, query_param + 2);
 #pragma GCC diagnostic pop
 
   launch_uri (effective_url, timestamp);
 
   g_free (query_param);
-  g_free (url_search);
   g_free (effective_url);
   g_free (search_string);
+  g_free (default_name);
 }
 
 static gboolean
diff --git a/tests/ephy-embed-utils-test.c b/tests/ephy-embed-utils-test.c
index d52da80..7f184cf 100644
--- a/tests/ephy-embed-utils-test.c
+++ b/tests/ephy-embed-utils-test.c
@@ -19,7 +19,11 @@
  */
 
 #include "config.h"
+
 #include "ephy-embed-utils.h"
+#include "ephy-file-helpers.h"
+#include "ephy-shell.h"
+
 #include <glib.h>
 #include <gtk/gtk.h>
 
@@ -129,6 +133,9 @@ main (int argc, char *argv[])
   guint i;
   gtk_test_init (&argc, &argv);
 
+  ephy_file_helpers_init (NULL, EPHY_FILE_HELPERS_PRIVATE_PROFILE, NULL);
+  _ephy_shell_create_instance (EPHY_EMBED_SHELL_MODE_TEST);
+
   for (i = 0; i < G_N_ELEMENTS (tests_has_scheme); i++) {
     SchemeTest test;
     char *test_name;
diff --git a/tests/ephy-web-view-test.c b/tests/ephy-web-view-test.c
index eb3351f..6475bc0 100644
--- a/tests/ephy-web-view-test.c
+++ b/tests/ephy-web-view-test.c
@@ -24,6 +24,7 @@
 #include "ephy-embed-utils.h"
 #include "ephy-file-helpers.h"
 #include "ephy-history-service.h"
+#include "ephy-search-engine-manager.h"
 #include "ephy-settings.h"
 #include "ephy-shell.h"
 #include "ephy-web-view.h"
@@ -289,30 +290,35 @@ verify_normalize_or_autosearch_urls (EphyWebView               *view,
 static void
 test_ephy_web_view_normalize_or_autosearch (void)
 {
-  char *default_engine_url;
+  char *default_engine;
   EphyWebView *view;
+  EphySearchEngineManager *manager;
+  EphyEmbedShell *shell;
+
 
   view = EPHY_WEB_VIEW (ephy_web_view_new ());
-  default_engine_url = g_settings_get_string (EPHY_SETTINGS_MAIN,
-                                              EPHY_PREFS_KEYWORD_SEARCH_URL);
 
-  g_settings_set_string (EPHY_SETTINGS_MAIN,
-                         EPHY_PREFS_KEYWORD_SEARCH_URL,
-                         "http://duckduckgo.com/?q=%s&t=epiphany";);
+  shell = ephy_embed_shell_get_default ();
+  manager = ephy_embed_shell_get_search_engine_manager (shell);
+
 
+  default_engine = ephy_search_engine_manager_get_default_engine (manager);
+  ephy_search_engine_manager_add_engine (manager,
+                                         "org.gnome.Epiphany.EphyWebViewTest",
+                                         "http://duckduckgo.com/?q=%s&t=epiphany";,
+                                         "");
+  g_assert (ephy_search_engine_manager_set_default_engine (manager, "org.gnome.Epiphany.EphyWebViewTest"));
   verify_normalize_or_autosearch_urls (view, normalize_or_autosearch_test_ddg, G_N_ELEMENTS 
(normalize_or_autosearch_test_ddg));
 
-  g_settings_set_string (EPHY_SETTINGS_MAIN,
-                         EPHY_PREFS_KEYWORD_SEARCH_URL,
-                         "http://www.google.com/?q=%s";);
+  ephy_search_engine_manager_modify_engine (manager,
+                                            "org.gnome.Epiphany.EphyWebViewTest",
+                                            "http://www.google.com/?q=%s";,
+                                            "");
 
+  g_assert (ephy_search_engine_manager_set_default_engine (manager, default_engine));
   verify_normalize_or_autosearch_urls (view, normalize_or_autosearch_test_google, G_N_ELEMENTS 
(normalize_or_autosearch_test_google));
 
-  g_settings_set_string (EPHY_SETTINGS_MAIN,
-                         EPHY_PREFS_KEYWORD_SEARCH_URL,
-                         default_engine_url);
-
-  g_free (default_engine_url);
+  g_free (default_engine);
   g_object_unref (g_object_ref_sink (view));
 }
 


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