summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--amiga/gui.c22
-rw-r--r--desktop/options.h3
-rw-r--r--gtk/scaffolding.c13
-rw-r--r--render/html_interaction.c24
-rw-r--r--riscos/window.c14
-rw-r--r--utils/nsurl.c51
-rw-r--r--utils/nsurl.h18
7 files changed, 136 insertions, 9 deletions
diff --git a/amiga/gui.c b/amiga/gui.c
index b4f3b136d..cfd6b44b2 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -4892,12 +4892,28 @@ static void gui_window_set_status(struct gui_window *g, const char *text)
static nserror gui_window_set_url(struct gui_window *g, nsurl *url)
{
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
+ char *url_lc = NULL;
+
if(!g) return NSERROR_OK;
- if (g == g->shared->gw) {
+ if(g == g->shared->gw) {
+ if(nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_access_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) {
+ url_lc = ami_utf8_easy(idn_url_s);
+ }
+ }
+
RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL],
- g->shared->win, NULL, STRINGA_TextVal,
- nsurl_access(url), TAG_DONE);
+ g->shared->win, NULL,
+ STRINGA_TextVal, url_lc ? url_lc : nsurl_access(url),
+ TAG_DONE);
+
+ if(url_lc) {
+ ami_utf8_free(url_lc);
+ if(idn_url_s) free(idn_url_s);
+ }
}
ami_update_buttons(g->shared);
diff --git a/desktop/options.h b/desktop/options.h
index 33ecb7554..f01261ee1 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -185,6 +185,9 @@ NSOPTION_UINT(min_reflow_period, DEFAULT_REFLOW_PERIOD)
/* use core selection menu */
NSOPTION_BOOL(core_select_menu, false)
+/* display decoded international domain names */
+NSOPTION_BOOL(display_decoded_idn, false)
+
/******** Fetcher options ********/
/** Maximum simultaneous active fetchers */
diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c
index 4506ac27f..a9904debf 100644
--- a/gtk/scaffolding.c
+++ b/gtk/scaffolding.c
@@ -2343,10 +2343,21 @@ void nsgtk_window_set_title(struct gui_window *gw, const char *title)
nserror gui_window_set_url(struct gui_window *gw, nsurl *url)
{
struct nsgtk_scaffolding *g;
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
g = nsgtk_get_scaffold(gw);
if (g->top_level == gw) {
- gtk_entry_set_text(GTK_ENTRY(g->url_bar), nsurl_access(url));
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_access_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
+ idn_url_s = NULL;
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(g->url_bar), idn_url_s ? idn_url_s : nsurl_access(url));
+
+ if(idn_url_s)
+ free(idn_url_s);
+
gtk_editable_set_position(GTK_EDITABLE(g->url_bar), -1);
}
return NSERROR_OK;
diff --git a/render/html_interaction.c b/render/html_interaction.c
index 6e2a2df4c..1b2e5b9c9 100644
--- a/render/html_interaction.c
+++ b/render/html_interaction.c
@@ -300,6 +300,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE;
const char *title = 0;
nsurl *url = 0;
+ char *url_s = NULL;
+ size_t url_l = 0;
const char *target = 0;
char status_buffer[200];
const char *status = 0;
@@ -814,12 +816,26 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
y - html_object_pos_y);
}
} else if (url) {
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_access_utf8(url, &url_s, &url_l) != NSERROR_OK) {
+ /* Unable to obtain a decoded IDN. This is not a fatal error.
+ * Ensure the string pointer is NULL so we use the encoded version. */
+ url_s = NULL;
+ }
+ }
+
if (title) {
snprintf(status_buffer, sizeof status_buffer, "%s: %s",
- nsurl_access(url), title);
- status = status_buffer;
- } else
- status = nsurl_access(url);
+ url_s ? url_s : nsurl_access(url), title);
+ } else {
+ snprintf(status_buffer, sizeof status_buffer, "%s",
+ url_s ? url_s : nsurl_access(url));
+ }
+
+ status = status_buffer;
+
+ if (url_s != NULL)
+ free(url_s);
pointer = get_pointer_shape(url_box, imagemap);
diff --git a/riscos/window.c b/riscos/window.c
index 097ab9ee6..59c24ac8a 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -1038,8 +1038,20 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
/* exported function documented in riscos/window.h */
nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url)
{
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
+
if (g->toolbar) {
- ro_toolbar_set_url(g->toolbar, nsurl_access(url), true, false);
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_access_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
+ idn_url_s = NULL;
+ }
+
+ ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false);
+
+ if (idn_url_s)
+ free(idn_url_s);
+
ro_gui_url_complete_start(g->toolbar);
}
diff --git a/utils/nsurl.c b/utils/nsurl.c
index 8d53be84f..ed6d896b6 100644
--- a/utils/nsurl.c
+++ b/utils/nsurl.c
@@ -1700,6 +1700,57 @@ const char *nsurl_access(const nsurl *url)
/* exported interface, documented in nsurl.h */
+nserror nsurl_access_utf8(const nsurl *url, char **url_s, size_t *url_l)
+{
+ nserror err;
+ lwc_string *host;
+ char *idna_host;
+ size_t idna_host_len;
+ char *scheme;
+ size_t scheme_len;
+ char *path;
+ size_t path_len;
+
+ assert(url != NULL);
+
+ host = nsurl_get_component(url, NSURL_HOST);
+
+ if(host == NULL)
+ return NSERROR_BAD_URL;
+
+ err = idna_decode(lwc_string_data(host), lwc_string_length(host),
+ &idna_host, &idna_host_len);
+
+ lwc_string_unref(host);
+
+ if (err != NSERROR_OK)
+ return err;
+
+ err = nsurl_get(url, NSURL_SCHEME | NSURL_CREDENTIALS,
+ &scheme, &scheme_len);
+
+ if (err != NSERROR_OK)
+ return err;
+
+ err = nsurl_get(url, NSURL_PORT | NSURL_PATH | NSURL_QUERY | NSURL_FRAGMENT,
+ &path, &path_len);
+
+ if (err != NSERROR_OK)
+ return err;
+
+ *url_l = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */
+ *url_s = malloc(*url_l);
+
+ if (*url_s == NULL)
+ return NSERROR_NOMEM;
+
+ snprintf(*url_s, *url_l, "%s%s%s", scheme, idna_host, path);
+
+ return NSERROR_OK;
+}
+
+
+/* exported interface, documented in nsurl.h */
const char *nsurl_access_leaf(const nsurl *url)
{
size_t path_len;
diff --git a/utils/nsurl.h b/utils/nsurl.h
index b84f55eed..85e46dfd6 100644
--- a/utils/nsurl.h
+++ b/utils/nsurl.h
@@ -181,6 +181,24 @@ const char *nsurl_access(const nsurl *url);
/**
+ * Access a NetSurf URL object as a UTF-8 string (for human readable IDNs)
+ *
+ * \param url NetSurf URL object
+ * \param url_s Returns a url string
+ * \param url_l Returns length of url_s
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * If return value != NSERROR_OK, nothing will be returned in url_s or url_l.
+ *
+ * The string returned in url_s is owned by the client and it is up to them
+ * to free it. It includes a trailing '\0'.
+ *
+ * The length returned in url_l excludes the trailing '\0'.
+ */
+nserror nsurl_access_utf8(const nsurl *url, char **url_s, size_t *url_l);
+
+
+/**
* Access a URL's path leaf as a string
*
* \param url NetSurf URL to retrieve a string pointer for.