From b5b4d3a8680ac4b7c7358af782cc823213b412bc Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Mon, 25 Feb 2013 14:17:11 +0100 Subject: Move code to get application icon from DOM to ephy-dom-utils https://bugzilla.gnome.org/show_bug.cgi?id=694091 --- lib/ephy-web-app-utils.c | 230 ----------------------------------------------- lib/ephy-web-app-utils.h | 4 - lib/ephy-web-dom-utils.c | 223 +++++++++++++++++++++++++++++++++++++++++++++ lib/ephy-web-dom-utils.h | 5 ++ src/window-commands.c | 33 ++++++- 5 files changed, 258 insertions(+), 237 deletions(-) diff --git a/lib/ephy-web-app-utils.c b/lib/ephy-web-app-utils.c index e12649aa8..9f23fb8ac 100644 --- a/lib/ephy-web-app-utils.c +++ b/lib/ephy-web-app-utils.c @@ -35,236 +35,6 @@ #define EPHY_WEB_APP_DESKTOP_FILE_PREFIX "epiphany-" -static char * -resolve_uri (WebKitWebView *view, - const char *uri) -{ - SoupURI *base; - SoupURI *new; - const char *base_uri; - char *ret; - - if (uri == NULL) - return NULL; - - base_uri = webkit_web_view_get_uri (view); - if (base_uri == NULL) - return NULL; - - base = soup_uri_new (base_uri); - new = soup_uri_new_with_base (base, uri); - soup_uri_free (base); - ret = soup_uri_to_string (new, FALSE); - soup_uri_free (new); - - return ret; -} - -#ifdef HAVE_WEBKIT2 -/* TODO: DOM Bindindgs */ -#else -static gboolean -get_icon_from_mstile (WebKitWebView *view, - char **uri_out, - char **color_out) -{ - gboolean ret; - WebKitDOMDocument *document; - WebKitDOMNodeList *metas; - gulong length, i; - char *image = NULL; - char *color = NULL; - - document = webkit_web_view_get_dom_document (view); - metas = webkit_dom_document_get_elements_by_tag_name (document, "meta"); - length = webkit_dom_node_list_get_length (metas); - - for (i = 0; i < length; i++) { - WebKitDOMNode *node = webkit_dom_node_list_item (metas, i); - char *name; - - name = webkit_dom_html_meta_element_get_name (WEBKIT_DOM_HTML_META_ELEMENT (node)); - if (g_strcmp0 (name, "msapplication-TileImage") == 0) { - if (image == NULL) - image = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); - } else if (g_strcmp0 (name, "msapplication-TileColor") == 0) { - if (color == NULL) - color = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); - } - } - - ret = (image != NULL && *image != '\0'); - - if (uri_out != NULL) - *uri_out = g_strdup (image); - if (color_out != NULL) - *color_out = g_strdup (color); - - g_free (image); - g_free (color); - - return ret; -} - -static gboolean -get_icon_from_ogp (WebKitWebView *view, - char **uri_out, - char **color_out) -{ - gboolean ret; - WebKitDOMDocument *document; - WebKitDOMNodeList *metas; - gulong length, i; - char *image = NULL; - char *color = NULL; - - document = webkit_web_view_get_dom_document (view); - metas = webkit_dom_document_get_elements_by_tag_name (document, "meta"); - length = webkit_dom_node_list_get_length (metas); - - for (i = 0; i < length && image == NULL; i++) { - WebKitDOMNode *node = webkit_dom_node_list_item (metas, i); - char *property; - char *itemprop; - - property = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "property"); - itemprop = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "itemprop"); - if (g_strcmp0 (property, "og:image") == 0 || - g_strcmp0 (itemprop, "image") == 0) { - image = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); - } - g_free (property); - g_free (itemprop); - } - - ret = (image != NULL && *image != '\0'); - - if (uri_out != NULL) - *uri_out = g_strdup (image); - if (color_out != NULL) - *color_out = g_strdup (color); - - return ret; -} - -static gboolean -get_icon_from_touch_icon (WebKitWebView *view, - char **uri_out, - char **color_out) -{ - gboolean ret; - WebKitDOMDocument *document; - WebKitDOMNodeList *links; - gulong length, i; - char *image = NULL; - char *color = NULL; - - document = webkit_web_view_get_dom_document (view); - links = webkit_dom_document_get_elements_by_tag_name (document, "link"); - length = webkit_dom_node_list_get_length (links); - - for (i = 0; i < length && image == NULL; i++) { - char *rel; - WebKitDOMNode *node = webkit_dom_node_list_item (links, i); - - rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); - /* TODO: support more than one possible icon. */ - if (g_strcmp0 (rel, "apple-touch-icon") == 0 || - g_strcmp0 (rel, "apple-touch-icon-precomposed") == 0) { - image = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); - } - g_free (rel); - } - - ret = (image != NULL && *image != '\0'); - - if (uri_out != NULL) - *uri_out = g_strdup (image); - if (color_out != NULL) - *color_out = g_strdup (color); - - return ret; -} - -static gboolean -get_icon_from_favicon (WebKitWebView *view, - char **uri_out, - char **color_out) -{ - gboolean ret; - WebKitDOMDocument *document; - WebKitDOMNodeList *links; - gulong length, i; - char *image = NULL; - char *color = NULL; - - document = webkit_web_view_get_dom_document (view); - links = webkit_dom_document_get_elements_by_tag_name (document, "link"); - length = webkit_dom_node_list_get_length (links); - - for (i = 0; i < length; i++) { - char *rel; - WebKitDOMNode *node = webkit_dom_node_list_item (links, i); - - rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); - if (g_strcmp0 (rel, "shortcut-icon") == 0 || - g_strcmp0 (rel, "shortcut icon") == 0 || - g_strcmp0 (rel, "SHORTCUT ICON") == 0 || - g_strcmp0 (rel, "Shortcut Icon") == 0 || - g_strcmp0 (rel, "icon shortcut") == 0 || - g_strcmp0 (rel, "icon") == 0) { - image = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); - } - g_free (rel); - } - - ret = (image != NULL && *image != '\0'); - - if (uri_out != NULL) - *uri_out = g_strdup (image); - if (color_out != NULL) - *color_out = g_strdup (color); - - return ret; -} -#endif /* HAVE_WEBKIT2 */ - -gboolean -ephy_web_view_get_best_icon (WebKitWebView *view, - char **uri, - GdkRGBA *rgba) -{ - gboolean ret = FALSE; - char *image = NULL; - char *color = NULL; - -#ifdef HAVE_WEBKIT2 - /* TODO: DOM Bindindgs */ -#else - - /* First try to get a mstile, then try OGP, then favicon */ - - ret = get_icon_from_mstile (view, &image, &color); - if (! ret) - ret = get_icon_from_ogp (view, &image, &color); - if (! ret) - ret = get_icon_from_touch_icon (view, &image, &color); - if (! ret) - ret = get_icon_from_favicon (view, &image, &color); - -#endif - - if (uri != NULL) - *uri = resolve_uri (view, image); - if (rgba != NULL && color != NULL) - gdk_rgba_parse (rgba, color); - - g_free (image); - g_free (color); - - return ret; -} - /* This is necessary because of gnome-shell's guessing of a .desktop filename from WM_CLASS property. */ static char * diff --git a/lib/ephy-web-app-utils.h b/lib/ephy-web-app-utils.h index adb254e5f..adc2acd7e 100644 --- a/lib/ephy-web-app-utils.h +++ b/lib/ephy-web-app-utils.h @@ -58,10 +58,6 @@ void ephy_web_application_free_application_list (GList *list); gboolean ephy_web_application_exists (const char *name); -gboolean ephy_web_view_get_best_icon (WebKitWebView *view, - char **uri, - GdkRGBA *rgba); - G_END_DECLS #endif diff --git a/lib/ephy-web-dom-utils.c b/lib/ephy-web-dom-utils.c index 184cf6769..375a7be60 100644 --- a/lib/ephy-web-dom-utils.c +++ b/lib/ephy-web-dom-utils.c @@ -22,6 +22,7 @@ #include "config.h" #include "ephy-web-dom-utils.h" +#include #ifdef HAVE_WEBKIT2 #include #include @@ -131,3 +132,225 @@ ephy_web_dom_utils_get_application_title (WebKitDOMDocument *document) return title; } + +static char * +resolve_uri (const char *base_uri, + const char *uri) +{ + SoupURI *base; + SoupURI *new; + char *ret; + + if (uri == NULL) + return NULL; + + if (base_uri == NULL) + return NULL; + + base = soup_uri_new (base_uri); + new = soup_uri_new_with_base (base, uri); + soup_uri_free (base); + ret = soup_uri_to_string (new, FALSE); + soup_uri_free (new); + + return ret; +} + +static gboolean +get_icon_from_mstile (WebKitDOMDocument *document, + char **uri_out, + char **color_out) +{ + gboolean ret; + WebKitDOMNodeList *metas; + gulong length, i; + char *image = NULL; + char *color = NULL; + + metas = webkit_dom_document_get_elements_by_tag_name (document, "meta"); + length = webkit_dom_node_list_get_length (metas); + + for (i = 0; i < length; i++) { + WebKitDOMNode *node = webkit_dom_node_list_item (metas, i); + char *name; + + name = webkit_dom_html_meta_element_get_name (WEBKIT_DOM_HTML_META_ELEMENT (node)); + if (g_strcmp0 (name, "msapplication-TileImage") == 0) { + if (image == NULL) + image = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); + } else if (g_strcmp0 (name, "msapplication-TileColor") == 0) { + if (color == NULL) + color = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); + } + } + + ret = (image != NULL && *image != '\0'); + + if (uri_out != NULL) + *uri_out = g_strdup (image); + if (color_out != NULL) + *color_out = g_strdup (color); + + g_free (image); + g_free (color); + + return ret; +} + +static gboolean +get_icon_from_ogp (WebKitDOMDocument *document, + char **uri_out, + char **color_out) +{ + gboolean ret; + WebKitDOMNodeList *metas; + gulong length, i; + char *image = NULL; + char *color = NULL; + + metas = webkit_dom_document_get_elements_by_tag_name (document, "meta"); + length = webkit_dom_node_list_get_length (metas); + + for (i = 0; i < length && image == NULL; i++) { + WebKitDOMNode *node = webkit_dom_node_list_item (metas, i); + char *property; + char *itemprop; + + property = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "property"); + itemprop = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "itemprop"); + if (g_strcmp0 (property, "og:image") == 0 || + g_strcmp0 (itemprop, "image") == 0) { + image = webkit_dom_html_meta_element_get_content (WEBKIT_DOM_HTML_META_ELEMENT (node)); + } + g_free (property); + g_free (itemprop); + } + + ret = (image != NULL && *image != '\0'); + + if (uri_out != NULL) + *uri_out = g_strdup (image); + if (color_out != NULL) + *color_out = g_strdup (color); + + return ret; +} + +static gboolean +get_icon_from_touch_icon (WebKitDOMDocument *document, + char **uri_out, + char **color_out) +{ + gboolean ret; + WebKitDOMNodeList *links; + gulong length, i; + char *image = NULL; + char *color = NULL; + + links = webkit_dom_document_get_elements_by_tag_name (document, "link"); + length = webkit_dom_node_list_get_length (links); + + for (i = 0; i < length && image == NULL; i++) { + char *rel; + WebKitDOMNode *node = webkit_dom_node_list_item (links, i); + + rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); + /* TODO: support more than one possible icon. */ + if (g_strcmp0 (rel, "apple-touch-icon") == 0 || + g_strcmp0 (rel, "apple-touch-icon-precomposed") == 0) { + image = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); + } + g_free (rel); + } + + ret = (image != NULL && *image != '\0'); + + if (uri_out != NULL) + *uri_out = g_strdup (image); + if (color_out != NULL) + *color_out = g_strdup (color); + + return ret; +} + +static gboolean +get_icon_from_favicon (WebKitDOMDocument *document, + char **uri_out, + char **color_out) +{ + gboolean ret; + WebKitDOMNodeList *links; + gulong length, i; + char *image = NULL; + char *color = NULL; + + links = webkit_dom_document_get_elements_by_tag_name (document, "link"); + length = webkit_dom_node_list_get_length (links); + + for (i = 0; i < length; i++) { + char *rel; + WebKitDOMNode *node = webkit_dom_node_list_item (links, i); + + rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); + if (g_strcmp0 (rel, "shortcut-icon") == 0 || + g_strcmp0 (rel, "shortcut icon") == 0 || + g_strcmp0 (rel, "SHORTCUT ICON") == 0 || + g_strcmp0 (rel, "Shortcut Icon") == 0 || + g_strcmp0 (rel, "icon shortcut") == 0 || + g_strcmp0 (rel, "icon") == 0) { + image = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node)); + } + g_free (rel); + } + + ret = (image != NULL && *image != '\0'); + + if (uri_out != NULL) + *uri_out = g_strdup (image); + if (color_out != NULL) + *color_out = g_strdup (color); + + return ret; +} + +/** + * ephy_web_dom_utils_get_best_icon: + * @document: the DOM document. + * @base_uri: base URI of the #WebKitWebView. + * @uri_out: Icon URI. + * @color_out: Icon background color. + * + * Tries to get the icon (and its background color if any) for a web application + * from the @document meta data. First try to get a mstile, then OGP, then touch + * icon and finally favicon. + * + * Returns %TRUE if it finds an icon in the @document. + **/ +gboolean +ephy_web_dom_utils_get_best_icon (WebKitDOMDocument *document, + const char *base_uri, + char **uri_out, + char **color_out) +{ + gboolean ret = FALSE; + char *image = NULL; + char *color = NULL; + + ret = get_icon_from_mstile (document, &image, &color); + if (! ret) + ret = get_icon_from_ogp (document, &image, &color); + if (! ret) + ret = get_icon_from_touch_icon (document, &image, &color); + if (! ret) + ret = get_icon_from_favicon (document, &image, &color); + + if (uri_out != NULL) + *uri_out = resolve_uri (base_uri, image); + if (color_out != NULL) + *color_out = g_strdup (color); + + g_free (image); + g_free (color); + + return ret; +} diff --git a/lib/ephy-web-dom-utils.h b/lib/ephy-web-dom-utils.h index d98344c70..a998d4a17 100644 --- a/lib/ephy-web-dom-utils.h +++ b/lib/ephy-web-dom-utils.h @@ -37,6 +37,11 @@ gboolean ephy_web_dom_utils_has_modified_forms (WebKitDOMDocument *document); char * ephy_web_dom_utils_get_application_title (WebKitDOMDocument *document); +gboolean ephy_web_dom_utils_get_best_icon (WebKitDOMDocument *document, + const char *base_uri, + char **uri_out, + char **color_out); + G_END_DECLS #endif diff --git a/src/window-commands.c b/src/window-commands.c index c60f4df52..d86ff06a1 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -658,6 +658,10 @@ download_icon_and_set_image (EphyApplicationDialogData *data) static void fill_default_application_image (EphyApplicationDialogData *data) { + WebKitDOMDocument *document; + const char *base_uri; + char *image = NULL; + char *color = NULL; gboolean res; data->icon_rgba.red = 0.5; @@ -665,9 +669,32 @@ fill_default_application_image (EphyApplicationDialogData *data) data->icon_rgba.blue = 0.5; data->icon_rgba.alpha = 0.3; - res = ephy_web_view_get_best_icon (WEBKIT_WEB_VIEW (data->view), - &data->icon_href, - &data->icon_rgba); + base_uri = webkit_web_view_get_uri (WEBKIT_WEB_VIEW (data->view)); + +#ifdef HAVE_WEBKIT2 + /* TODO use web extension to get image and color */ + res = FALSE; +#else + document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (data->view)); + res = ephy_web_dom_utils_get_best_icon (document, + base_uri, + &image, + &color); +#endif + + if (image != NULL) + { + data->icon_href = g_strdup (image); + } + + if (color != NULL) + { + gdk_rgba_parse (&data->icon_rgba, color); + } + + g_free (image); + g_free (color); + if (res) { download_icon_and_set_image (data); -- cgit v1.2.3