summaryrefslogtreecommitdiff
path: root/desktop/browser_window.c
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/browser_window.c')
-rw-r--r--desktop/browser_window.c683
1 files changed, 386 insertions, 297 deletions
diff --git a/desktop/browser_window.c b/desktop/browser_window.c
index dea507fef..c70db7cf1 100644
--- a/desktop/browser_window.c
+++ b/desktop/browser_window.c
@@ -1,7 +1,7 @@
/*
* Copyright 2008 Michael Drake <tlsa@netsurf-browser.org>
* Copyright 2010 Daniel Silverstone <dsilvers@digital-scurf.org>
- * Copyright 2010 Vincent Sanders <vince@netsurf-browser.org>
+ * Copyright 2010-2020 Vincent Sanders <vince@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -26,49 +26,47 @@
#include "utils/config.h"
-#include <assert.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
#include <math.h>
#include <nsutils/time.h>
-#include "utils/corestrings.h"
+#include "utils/errors.h"
#include "utils/log.h"
+#include "utils/corestrings.h"
#include "utils/messages.h"
-#include "utils/nsurl.h"
-#include "utils/utils.h"
-#include "utils/utf8.h"
#include "utils/nsoption.h"
-#include "netsurf/misc.h"
+#include "netsurf/types.h"
+#include "netsurf/browser_window.h"
#include "netsurf/window.h"
+#include "netsurf/misc.h"
#include "netsurf/content.h"
+#include "netsurf/search.h"
#include "netsurf/plotters.h"
-#include "content/content_debug.h"
-#include "content/fetch.h"
+#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
-#include "css/utils.h"
-#include "html/form_internal.h"
+#include "content/content_debug.h"
+
#include "html/html.h"
-#include "html/box.h"
+#include "html/form_internal.h"
#include "javascript/js.h"
-#include "desktop/browser_history.h"
#include "desktop/browser_private.h"
+#include "desktop/scrollbar.h"
+#include "desktop/gui_internal.h"
#include "desktop/download.h"
#include "desktop/frames.h"
#include "desktop/global_history.h"
+#include "desktop/textinput.h"
#include "desktop/hotlist.h"
#include "desktop/knockout.h"
-#include "desktop/scrollbar.h"
-#include "desktop/selection.h"
+#include "desktop/browser_history.h"
#include "desktop/theme.h"
-#include "desktop/gui_internal.h"
-#include "desktop/textinput.h"
+
+#ifdef WITH_THEME_INSTALL
+#include "desktop/theme.h"
+#endif
/**
* smallest scale that can be applied to a browser window
@@ -85,9 +83,6 @@
*/
#define FRAME_DEPTH 8
-/* Have to forward declare browser_window_destroy_internal */
-static void browser_window_destroy_internal(struct browser_window *bw);
-
/* Forward declare internal navigation function */
static nserror browser_window__navigate_internal(
struct browser_window *bw, struct browser_fetch_parameters *params);
@@ -111,14 +106,6 @@ static void browser_window_destroy_children(struct browser_window *bw)
bw->rows = 0;
bw->cols = 0;
}
- if (bw->iframes) {
- for (i = 0; i < bw->iframe_count; i++) {
- browser_window_destroy_internal(&bw->iframes[i]);
- }
- free(bw->iframes);
- bw->iframes = NULL;
- bw->iframe_count = 0;
- }
}
@@ -328,22 +315,6 @@ browser_window__get_contextual_content(struct browser_window *bw,
/**
- * slow script handler
- */
-static bool slow_script(void *ctx)
-{
- static int count = 0;
- NSLOG(netsurf, INFO, "Continuing execution %d", count);
- count++;
- if (count > 1) {
- count = 0;
- return false;
- }
- return true;
-}
-
-
-/**
* implements the download operation of a window navigate
*/
static nserror
@@ -722,6 +693,130 @@ browser_window_convert_to_download(struct browser_window *bw,
/**
+ * scroll to a fragment if present
+ *
+ * \param bw browser window
+ * \return true if the scroll was sucessful
+ */
+static bool frag_scroll(struct browser_window *bw)
+{
+ struct rect rect;
+
+ if (bw->frag_id == NULL) {
+ return false;
+ }
+
+ if (!html_get_id_offset(bw->current_content,
+ bw->frag_id,
+ &rect.x0,
+ &rect.y0)) {
+ return false;
+ }
+
+ rect.x1 = rect.x0;
+ rect.y1 = rect.y0;
+ if (browser_window_set_scroll(bw, &rect) == NSERROR_OK) {
+ if (bw->current_content != NULL &&
+ bw->history != NULL &&
+ bw->history->current != NULL) {
+ browser_window_history_update(bw, bw->current_content);
+ }
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Redraw browser window, set extent to content, and update title.
+ *
+ * \param bw browser_window
+ * \param scroll_to_top move view to top of page
+ */
+static void browser_window_update(struct browser_window *bw, bool scroll_to_top)
+{
+ static const struct rect zrect = {
+ .x0 = 0,
+ .y0 = 0,
+ .x1 = 0,
+ .y1 = 0
+ };
+
+ if (bw->current_content == NULL) {
+ return;
+ }
+
+ switch (bw->browser_window_type) {
+
+ case BROWSER_WINDOW_NORMAL:
+ /* Root browser window, constituting a front end window/tab */
+ guit->window->set_title(bw->window,
+ content_get_title(bw->current_content));
+
+ browser_window_update_extent(bw);
+
+ /* if frag_id exists, then try to scroll to it */
+ /** @todo don't do this if the user has scrolled */
+ if (!frag_scroll(bw)) {
+ if (scroll_to_top) {
+ browser_window_set_scroll(bw, &zrect);
+ }
+ }
+
+ guit->window->invalidate(bw->window, NULL);
+
+ break;
+
+ case BROWSER_WINDOW_IFRAME:
+ /* Internal iframe browser window */
+ assert(bw->parent != NULL);
+ assert(bw->parent->current_content != NULL);
+
+ browser_window_update_extent(bw);
+
+ if (scroll_to_top) {
+ browser_window_set_scroll(bw, &zrect);
+ }
+
+ /* if frag_id exists, then try to scroll to it */
+ /** @todo don't do this if the user has scrolled */
+ frag_scroll(bw);
+
+ browser_window_invalidate_iframe(bw);
+
+ break;
+
+ case BROWSER_WINDOW_FRAME:
+ {
+ struct rect rect;
+ browser_window_update_extent(bw);
+
+ if (scroll_to_top) {
+ browser_window_set_scroll(bw, &zrect);
+ }
+
+ /* if frag_id exists, then try to scroll to it */
+ /** @todo don't do this if the user has scrolled */
+ frag_scroll(bw);
+
+ rect.x0 = scrollbar_get_offset(bw->scroll_x);
+ rect.y0 = scrollbar_get_offset(bw->scroll_y);
+ rect.x1 = rect.x0 + bw->width;
+ rect.y1 = rect.y0 + bw->height;
+
+ browser_window_invalidate_rect(bw, &rect);
+ }
+ break;
+
+ default:
+ case BROWSER_WINDOW_FRAMESET:
+ /* Nothing to do */
+ break;
+ }
+}
+
+
+/**
* handle message for content ready on browser window
*/
static nserror browser_window_content_ready(struct browser_window *bw)
@@ -743,9 +838,10 @@ static nserror browser_window_content_ready(struct browser_window *bw)
browser_window__free_fetch_parameters(&bw->current_parameters);
bw->current_parameters = bw->loading_parameters;
memset(&bw->loading_parameters, 0, sizeof(bw->loading_parameters));
- /* Transfer the SSL info */
- bw->current_ssl_info = bw->loading_ssl_info;
- bw->loading_ssl_info.num = 0;
+ /* Transfer the certificate chain */
+ cert_chain_free(bw->current_cert_chain);
+ bw->current_cert_chain = bw->loading_cert_chain;
+ bw->loading_cert_chain = NULL;
}
/* Format the new content to the correct dimensions */
@@ -808,15 +904,10 @@ static nserror browser_window_content_ready(struct browser_window *bw)
browser_window_set_status(bw, content_get_status_message(bw->current_content));
/* frames */
- if ((content_get_type(bw->current_content) == CONTENT_HTML) &&
- (html_get_frameset(bw->current_content) != NULL)) {
- res = browser_window_create_frameset(bw, html_get_frameset(bw->current_content));
- }
+ res = browser_window_create_frameset(bw);
- if (content_get_type(bw->current_content) == CONTENT_HTML &&
- html_get_iframe(bw->current_content) != NULL) {
- browser_window_create_iframes(bw, html_get_iframe(bw->current_content));
- }
+ /* iframes */
+ res = browser_window_create_iframes(bw);
/* Indicate page status may have changed */
if (res == NSERROR_OK) {
@@ -893,6 +984,7 @@ browser_window__handle_ssl_query_response(bool proceed, void *pw)
browser_window_stop(bw);
browser_window_remove_caret(bw, false);
browser_window_destroy_children(bw);
+ browser_window_destroy_iframes(bw);
}
if (!proceed) {
@@ -1038,6 +1130,7 @@ browser_window__handle_userpass_response(nsurl *url,
browser_window_stop(bw);
browser_window_remove_caret(bw, false);
browser_window_destroy_children(bw);
+ browser_window_destroy_iframes(bw);
}
bw->internal_nav = false;
return browser_window__navigate_internal(bw, &bw->loading_parameters);
@@ -1136,7 +1229,8 @@ browser_window__handle_bad_certs(struct browser_window *bw,
nserror err;
/* Initially we don't know WHY the SSL cert was bad */
const char *reason = messages_get_sslcode(SSL_CERT_ERR_UNKNOWN);
- size_t n;
+ size_t depth;
+ nsurl *chainurl = NULL;
memset(&params, 0, sizeof(params));
@@ -1151,12 +1245,26 @@ browser_window__handle_bad_certs(struct browser_window *bw,
goto out;
}
- for (n = 0; n < bw->loading_ssl_info.num; ++n) {
- size_t idx = bw->loading_ssl_info.num - (n + 1);
- ssl_cert_err err = bw->loading_ssl_info.certs[idx].err;
- if (err != SSL_CERT_ERR_OK) {
- reason = messages_get_sslcode(err);
- break;
+ if (bw->loading_cert_chain != NULL) {
+ for (depth = 0; depth < bw->loading_cert_chain->depth; ++depth) {
+ size_t idx = bw->loading_cert_chain->depth - (depth + 1);
+ ssl_cert_err err = bw->loading_cert_chain->certs[idx].err;
+ if (err != SSL_CERT_ERR_OK) {
+ reason = messages_get_sslcode(err);
+ break;
+ }
+ }
+
+ err = cert_chain_to_query(bw->loading_cert_chain, &chainurl);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ err = fetch_multipart_data_new_kv(&params.post_multipart,
+ "chainurl",
+ nsurl_access(chainurl));
+ if (err != NSERROR_OK) {
+ goto out;
}
}
@@ -1174,17 +1282,10 @@ browser_window__handle_bad_certs(struct browser_window *bw,
goto out;
}
- err = guit->misc->cert_verify(url,
- bw->loading_ssl_info.certs,
- bw->loading_ssl_info.num,
- browser_window__handle_ssl_query_response,
- bw);
-
- if (err == NSERROR_NOT_IMPLEMENTED) {
- err = NSERROR_OK;
- }
out:
browser_window__free_fetch_parameters(&params);
+ if (chainurl != NULL)
+ nsurl_unref(chainurl);
return err;
}
@@ -1286,6 +1387,8 @@ browser_window__handle_error(struct browser_window *bw,
if (message == NULL) {
message = messages_get_errorcode(code);
+ } else {
+ message = messages_get(message);
}
if (c == bw->loading_content) {
@@ -1315,7 +1418,28 @@ browser_window__handle_error(struct browser_window *bw,
break;
}
- return NSERROR_OK;
+ return res;
+}
+
+
+/**
+ * Update URL bar for a given browser window to given URL
+ *
+ * \param bw Browser window to update URL bar for.
+ * \param url URL for content displayed by bw including any fragment.
+ */
+static inline nserror
+browser_window_refresh_url_bar_internal(struct browser_window *bw, nsurl *url)
+{
+ assert(bw);
+ assert(url);
+
+ if ((bw->parent != NULL) || (bw->window == NULL)) {
+ /* Not root window or no gui window so do not set a URL */
+ return NSERROR_OK;
+ }
+
+ return guit->window->set_url(bw->window, url);
}
@@ -1331,11 +1455,8 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
switch (event->type) {
case CONTENT_MSG_SSL_CERTS:
/* SSL certificate information has arrived, store it */
- assert(event->data.certs.num < MAX_SSL_CERTS);
- memcpy(&bw->loading_ssl_info.certs[0],
- event->data.certs.certs,
- sizeof(struct ssl_cert_info) * event->data.certs.num);
- bw->loading_ssl_info.num = event->data.certs.num;
+ cert_chain_free(bw->loading_cert_chain);
+ cert_chain_dup(event->data.chain, &bw->loading_cert_chain);
break;
case CONTENT_MSG_LOG:
@@ -1393,6 +1514,7 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
if (urldb_add_url(event->data.redirect.from)) {
urldb_update_url_visit_data(event->data.redirect.from);
}
+ browser_window_refresh_url_bar_internal(bw, event->data.redirect.to);
break;
case CONTENT_MSG_STATUS:
@@ -1420,14 +1542,12 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
break;
case CONTENT_MSG_REFORMAT:
- if (c == bw->current_content &&
- content_get_type(c) == CONTENT_HTML) {
- /* reposition frames */
- if (html_get_frameset(c) != NULL)
- browser_window_recalculate_frameset(bw);
- /* reflow iframe positions */
- if (html_get_iframe(c) != NULL)
- browser_window_recalculate_iframes(bw);
+ if (c == bw->current_content) {
+ /* recompute frameset */
+ browser_window_recalculate_frameset(bw);
+
+ /* recompute iframe positions, sizes and scrollbars */
+ browser_window_recalculate_iframes(bw);
}
/* Hide any caret, but don't remove it */
@@ -1448,7 +1568,7 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
.y1 = event->data.redraw.y + event->data.redraw.height
};
- browser_window_update_box(bw, &rect);
+ browser_window_invalidate_rect(bw, &rect);
}
break;
@@ -1476,15 +1596,24 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
}
break;
- case CONTENT_MSG_GETCTX:
- /* only the content object created by the browser
- * window requires a new global compartment object
- */
- assert(bw->loading_content == c);
- if (js_newcompartment(bw->jsctx,
- bw,
- hlcache_handle_get_content(c)) != NULL) {
- *(event->data.jscontext) = bw->jsctx;
+ case CONTENT_MSG_GETTHREAD:
+ {
+ /* only the content object created by the browser
+ * window requires a new javascript thread object
+ */
+ jsthread *thread;
+ assert(bw->loading_content == c);
+
+ if (js_newthread(bw->jsheap,
+ bw,
+ hlcache_handle_get_content(c),
+ &thread) == NSERROR_OK) {
+ /* The content which is requesting the thread
+ * is required to keep hold of it and
+ * to destroy it when it is finished with it.
+ */
+ *(event->data.jsthread) = thread;
+ }
}
break;
@@ -1640,6 +1769,37 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
break;
+
+ case CONTENT_MSG_TEXTSEARCH:
+ switch (event->data.textsearch.type) {
+ case CONTENT_TEXTSEARCH_FIND:
+ guit->search->hourglass(event->data.textsearch.state,
+ event->data.textsearch.ctx);
+ break;
+
+ case CONTENT_TEXTSEARCH_MATCH:
+ guit->search->status(event->data.textsearch.state,
+ event->data.textsearch.ctx);
+ break;
+
+ case CONTENT_TEXTSEARCH_BACK:
+ guit->search->back_state(event->data.textsearch.state,
+ event->data.textsearch.ctx);
+ break;
+
+ case CONTENT_TEXTSEARCH_FORWARD:
+ guit->search->forward_state(event->data.textsearch.state,
+ event->data.textsearch.ctx);
+ break;
+
+ case CONTENT_TEXTSEARCH_RECENT:
+ guit->search->add_recent(event->data.textsearch.string,
+ event->data.textsearch.ctx);
+
+ break;
+ }
+ break;
+
default:
break;
}
@@ -1668,21 +1828,13 @@ static void scheduled_reformat(void *vbw)
}
}
-
-/**
- * Release all memory associated with a browser window.
- *
- * \param bw browser window
- */
-static void browser_window_destroy_internal(struct browser_window *bw)
+/* exported interface documented in desktop/browser_private.h */
+nserror browser_window_destroy_internal(struct browser_window *bw)
{
assert(bw);
- NSLOG(netsurf, INFO, "Destroying window");
-
- if (bw->children != NULL || bw->iframes != NULL) {
- browser_window_destroy_children(bw);
- }
+ browser_window_destroy_children(bw);
+ browser_window_destroy_iframes(bw);
/* Destroy scrollbars */
if (bw->scroll_x != NULL) {
@@ -1746,13 +1898,9 @@ static void browser_window_destroy_internal(struct browser_window *bw)
bw->favicon.current = NULL;
}
- if (bw->box != NULL) {
- bw->box->iframe = NULL;
- bw->box = NULL;
- }
-
- if (bw->jsctx != NULL) {
- js_destroycontext(bw->jsctx);
+ if (bw->jsheap != NULL) {
+ js_destroyheap(bw->jsheap);
+ bw->jsheap = NULL;
}
/* These simply free memory, so are safe here */
@@ -1763,6 +1911,11 @@ static void browser_window_destroy_internal(struct browser_window *bw)
browser_window_history_destroy(bw);
+ cert_chain_free(bw->current_cert_chain);
+ cert_chain_free(bw->loading_cert_chain);
+ bw->current_cert_chain = NULL;
+ bw->loading_cert_chain = NULL;
+
free(bw->name);
free(bw->status.text);
bw->status.text = NULL;
@@ -1770,62 +1923,8 @@ static void browser_window_destroy_internal(struct browser_window *bw)
browser_window__free_fetch_parameters(&bw->loading_parameters);
NSLOG(netsurf, INFO, "Status text cache match:miss %d:%d",
bw->status.match, bw->status.miss);
-}
-
-
-/**
- * Update URL bar for a given browser window to given URL
- *
- * \param bw Browser window to update URL bar for.
- * \param url URL for content displayed by bw including any fragment.
- */
-static inline nserror
-browser_window_refresh_url_bar_internal(struct browser_window *bw, nsurl *url)
-{
- assert(bw);
- assert(url);
-
- if ((bw->parent != NULL) || (bw->window == NULL)) {
- /* Not root window or no gui window so do not set a URL */
- return NSERROR_OK;
- }
-
- return guit->window->set_url(bw->window, url);
-}
-
-/**
- * scroll to a fragment if present
- *
- * \param bw browser window
- * \return true if the scroll was sucessful
- */
-static bool frag_scroll(struct browser_window *bw)
-{
- struct rect rect;
-
- if (bw->frag_id == NULL) {
- return false;
- }
-
- if (!html_get_id_offset(bw->current_content,
- bw->frag_id,
- &rect.x0,
- &rect.y0)) {
- return false;
- }
-
- rect.x1 = rect.x0;
- rect.y1 = rect.y0;
- if (browser_window_set_scroll(bw, &rect) == NSERROR_OK) {
- if (bw->current_content != NULL &&
- bw->history != NULL &&
- bw->history->current != NULL) {
- browser_window_history_update(bw, bw->current_content);
- }
- return true;
- }
- return false;
+ return NSERROR_OK;
}
@@ -1861,7 +1960,7 @@ browser_window_set_scale_internal(struct browser_window *bw, float scale)
res = browser_window_set_scale_internal(&bw->children[i], scale);
}
- /* sale iframes */
+ /* scale iframes */
for (i = 0; i < bw->iframe_count; i++) {
res = browser_window_set_scale_internal(&bw->iframes[i], scale);
}
@@ -2505,14 +2604,14 @@ browser_window_redraw(struct browser_window *bw,
struct rect content_clip;
nserror res;
- x /= bw->scale;
- y /= bw->scale;
-
if (bw == NULL) {
NSLOG(netsurf, INFO, "NULL browser window");
return false;
}
+ x /= bw->scale;
+ y /= bw->scale;
+
if ((bw->current_content == NULL) &&
(bw->children == NULL)) {
/* Browser window has no content, render blank fill */
@@ -2547,7 +2646,7 @@ browser_window_redraw(struct browser_window *bw,
/* Set current child */
child = &bw->children[cur_child];
- /* Get frame edge box in global coordinates */
+ /* Get frame edge area in global coordinates */
content_clip.x0 = (x + child->x) * child->scale;
content_clip.y0 = (y + child->y) * child->scale;
content_clip.x1 = content_clip.x0 +
@@ -3042,6 +3141,10 @@ browser_window_create(enum browser_window_create_flags flags,
gw_flags |= GW_CREATE_TAB;
if (flags & BW_CREATE_CLONE)
gw_flags |= GW_CREATE_CLONE;
+ if (flags & BW_CREATE_FOREGROUND)
+ gw_flags |= GW_CREATE_FOREGROUND;
+ if (flags & BW_CREATE_FOCUS_LOCATION)
+ gw_flags |= GW_CREATE_FOCUS_LOCATION;
ret->window = guit->window->create(ret,
(existing != NULL) ? existing->window : NULL,
@@ -3082,14 +3185,13 @@ browser_window_create(enum browser_window_create_flags flags,
nserror
browser_window_initialise_common(enum browser_window_create_flags flags,
struct browser_window *bw,
- struct browser_window *existing)
+ const struct browser_window *existing)
{
nserror err;
assert(bw);
/* new javascript context for each window/(i)frame */
- err = js_newcontext(nsoption_int(script_timeout),
- slow_script, NULL, &bw->jsctx);
+ err = js_newheap(nsoption_int(script_timeout), &bw->jsheap);
if (err != NSERROR_OK)
return err;
@@ -3161,15 +3263,9 @@ nserror browser_window_refresh_url_bar(struct browser_window *bw)
/* no content so return about:blank */
ret = browser_window_refresh_url_bar_internal(bw,
corestring_nsurl_about_blank);
- } else if (bw->throbbing) {
- /* We're throbbing, so show the loading parameters url,
- * or if there isn't one, the current parameters url
- */
- if (bw->loading_parameters.url != NULL) {
- url = bw->loading_parameters.url;
- } else {
- url = bw->current_parameters.url;
- }
+ } else if (bw->throbbing && bw->loading_parameters.url != NULL) {
+ /* Throbbing and we have loading parameters, use those */
+ url = bw->loading_parameters.url;
ret = browser_window_refresh_url_bar_internal(bw, url);
} else if (bw->frag_id == NULL) {
if (bw->internal_nav) {
@@ -3360,6 +3456,7 @@ browser_window_navigate(struct browser_window *bw,
browser_window_stop(bw);
browser_window_remove_caret(bw, false);
browser_window_destroy_children(bw);
+ browser_window_destroy_iframes(bw);
/* Set up the fetch parameters */
memset(&params, 0, sizeof(params));
@@ -3432,7 +3529,8 @@ navigate_internal_real(struct browser_window *bw,
fetch_is_post = (params->post_urlenc != NULL || params->post_multipart != NULL);
/* Clear SSL info for load */
- bw->loading_ssl_info.num = 0;
+ cert_chain_free(bw->loading_cert_chain);
+ bw->loading_cert_chain = NULL;
/* Set up retrieval parameters */
if (!(params->flags & BW_NAVIGATE_UNVERIFIABLE)) {
@@ -3591,17 +3689,28 @@ navigate_internal_query_ssl(struct browser_window *bw,
struct browser_fetch_parameters *params)
{
bool is_proceed = false, is_back = false;
+ const char *siteurl = NULL;
+ nsurl *siteurl_ns;
assert(params->post_multipart != NULL);
is_proceed = fetch_multipart_data_find(params->post_multipart, "proceed") != NULL;
is_back = fetch_multipart_data_find(params->post_multipart, "back") != NULL;
+ siteurl = fetch_multipart_data_find(params->post_multipart, "siteurl");
- if (!(is_proceed || is_back)) {
+ if (!(is_proceed || is_back) || siteurl == NULL) {
/* This is a request, so pass it on */
return navigate_internal_real(bw, params);
}
+ if (nsurl_create(siteurl, &siteurl_ns) != NSERROR_OK) {
+ NSLOG(netsurf, ERROR, "Unable to reset ssl loading parameters");
+ } else {
+ /* In order that we may proceed, replace the loading parameters */
+ nsurl_unref(bw->loading_parameters.url);
+ bw->loading_parameters.url = siteurl_ns;
+ }
+
return browser_window__handle_ssl_query_response(is_proceed, bw);
}
@@ -3720,7 +3829,9 @@ browser_window__navigate_internal(struct browser_window *bw,
lwc_string_unref(path);
return navigate_internal_query_fetcherror(bw, params);
}
- lwc_string_unref(path);
+ if (path != NULL) {
+ lwc_string_unref(path);
+ }
/* Fall through to a normal about: fetch */
@@ -3789,7 +3900,7 @@ nserror browser_window_navigate_up(struct browser_window *bw, bool new_window)
/* Exported interface, documented in include/netsurf/browser_window.h */
-nsurl* browser_window_access_url(struct browser_window *bw)
+nsurl* browser_window_access_url(const struct browser_window *bw)
{
assert(bw != NULL);
@@ -3941,91 +4052,9 @@ browser_window_set_dimensions(struct browser_window *bw, int width, int height)
}
-/* Exported interface, documented in netsurf/browser_window.h */
-void browser_window_update(struct browser_window *bw, bool scroll_to_top)
-{
- static const struct rect zrect = {
- .x0 = 0,
- .y0 = 0,
- .x1 = 0,
- .y1 = 0
- };
-
- if (bw->current_content == NULL) {
- return;
- }
-
- switch (bw->browser_window_type) {
-
- case BROWSER_WINDOW_NORMAL:
- /* Root browser window, constituting a front end window/tab */
- guit->window->set_title(bw->window,
- content_get_title(bw->current_content));
-
- browser_window_update_extent(bw);
-
- /* if frag_id exists, then try to scroll to it */
- /** @todo don't do this if the user has scrolled */
- if (!frag_scroll(bw)) {
- if (scroll_to_top) {
- browser_window_set_scroll(bw, &zrect);
- }
- }
-
- guit->window->invalidate(bw->window, NULL);
-
- break;
-
- case BROWSER_WINDOW_IFRAME:
- /* Internal iframe browser window */
- assert(bw->parent != NULL);
- assert(bw->parent->current_content != NULL);
-
- browser_window_update_extent(bw);
-
- if (scroll_to_top) {
- browser_window_set_scroll(bw, &zrect);
- }
-
- /* if frag_id exists, then try to scroll to it */
- /** @todo don't do this if the user has scrolled */
- frag_scroll(bw);
-
- html_redraw_a_box(bw->parent->current_content, bw->box);
- break;
-
- case BROWSER_WINDOW_FRAME:
- {
- struct rect rect;
- browser_window_update_extent(bw);
-
- if (scroll_to_top) {
- browser_window_set_scroll(bw, &zrect);
- }
-
- /* if frag_id exists, then try to scroll to it */
- /** @todo don't do this if the user has scrolled */
- frag_scroll(bw);
-
- rect.x0 = scrollbar_get_offset(bw->scroll_x);
- rect.y0 = scrollbar_get_offset(bw->scroll_y);
- rect.x1 = rect.x0 + bw->width;
- rect.y1 = rect.y0 + bw->height;
-
- browser_window_update_box(bw, &rect);
- }
- break;
-
- default:
- case BROWSER_WINDOW_FRAMESET:
- /* Nothing to do */
- break;
- }
-}
-
-
-/* Exported interface, documented in netsurf/browser_window.h */
-void browser_window_update_box(struct browser_window *bw, struct rect *rect)
+/* Exported interface, documented in browser/browser_private.h */
+nserror
+browser_window_invalidate_rect(struct browser_window *bw, struct rect *rect)
{
int pos_x;
int pos_y;
@@ -4050,7 +4079,7 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect)
rect->x1 *= top->scale;
rect->y1 *= top->scale;
- guit->window->invalidate(top->window, rect);
+ return guit->window->invalidate(top->window, rect);
}
@@ -4330,7 +4359,7 @@ browser_window_find_target(struct browser_window *bw,
target = html_get_base_target(c);
}
if (target == NULL) {
- target = TARGET_SELF;
+ target = "_self";
}
/* allow the simple case of target="_blank" to be ignored if requested
@@ -4342,7 +4371,7 @@ browser_window_find_target(struct browser_window *bw,
/* not a mouse button 2 click
* not a mouse button 1 click with ctrl pressed
* configured to ignore target="_blank" */
- if ((target == TARGET_BLANK) || (!strcasecmp(target, "_blank")))
+ if (!strcasecmp(target, "_blank"))
return bw;
}
@@ -4353,8 +4382,7 @@ browser_window_find_target(struct browser_window *bw,
((mouse & BROWSER_MOUSE_CLICK_1) &&
(mouse & BROWSER_MOUSE_MOD_2))) ||
((nsoption_bool(button_2_tab)) &&
- ((target == TARGET_BLANK) ||
- (!strcasecmp(target, "_blank"))))) {
+ (!strcasecmp(target, "_blank")))) {
/* open in new tab if:
* - button_2 opens in new tab and button_2 was pressed
* OR
@@ -4380,8 +4408,7 @@ browser_window_find_target(struct browser_window *bw,
((mouse & BROWSER_MOUSE_CLICK_1) &&
(mouse & BROWSER_MOUSE_MOD_2))) ||
((!nsoption_bool(button_2_tab)) &&
- ((target == TARGET_BLANK) ||
- (!strcasecmp(target, "_blank"))))) {
+ (!strcasecmp(target, "_blank")))) {
/* open in new window if:
* - button_2 doesn't open in new tabs and button_2 was pressed
* OR
@@ -4401,14 +4428,13 @@ browser_window_find_target(struct browser_window *bw,
return bw;
}
return bw_target;
- } else if ((target == TARGET_SELF) || (!strcasecmp(target, "_self"))) {
+ } else if (!strcasecmp(target, "_self")) {
return bw;
- } else if ((target == TARGET_PARENT) ||
- (!strcasecmp(target, "_parent"))) {
+ } else if (!strcasecmp(target, "_parent")) {
if (bw->parent)
return bw->parent;
return bw;
- } else if ((target == TARGET_TOP) || (!strcasecmp(target, "_top"))) {
+ } else if (!strcasecmp(target, "_top")) {
while (bw->parent)
bw = bw->parent;
return bw;
@@ -4645,7 +4671,7 @@ browser_window__reload_current_parameters(struct browser_window *bw)
/* Exported interface, documented in browser_window.h */
browser_window_page_info_state browser_window_get_page_info_state(
- struct browser_window *bw)
+ const struct browser_window *bw)
{
lwc_string *scheme;
bool match;
@@ -4694,7 +4720,7 @@ browser_window_page_info_state browser_window_get_page_info_state(
lwc_string_unref(scheme);
/* Did we have to override this SSL setting? */
- if (urldb_get_cert_permissions(bw->current_parameters.url)) {
+ if (urldb_get_cert_permissions(hlcache_handle_get_url(bw->current_content))) {
return PAGE_STATE_SECURE_OVERRIDE;
}
@@ -4708,17 +4734,80 @@ browser_window_page_info_state browser_window_get_page_info_state(
}
/* Exported interface, documented in browser_window.h */
-nserror browser_window_get_ssl_chain(struct browser_window *bw, size_t *num,
- struct ssl_cert_info **chain)
+nserror
+browser_window_get_ssl_chain(struct browser_window *bw,
+ struct cert_chain **chain)
{
assert(bw != NULL);
- if (bw->current_ssl_info.num == 0) {
+ if (bw->current_cert_chain == NULL) {
return NSERROR_NOT_FOUND;
}
- *num = bw->current_ssl_info.num;
- *chain = &(bw->current_ssl_info.certs[0]);
+ *chain = bw->current_cert_chain;
return NSERROR_OK;
}
+
+/* Exported interface, documented in browser_window.h */
+int browser_window_get_cookie_count(
+ const struct browser_window *bw)
+{
+ int count = 0;
+ char *cookies = urldb_get_cookie(browser_window_access_url(bw), true);
+ if (cookies == NULL) {
+ return 0;
+ }
+
+ for (char *c = cookies; *c != '\0'; c++) {
+ if (*c == ';')
+ count++;
+ }
+
+ free(cookies);
+
+ return count;
+}
+
+/* Exported interface, documented in browser_window.h */
+nserror browser_window_show_cookies(
+ const struct browser_window *bw)
+{
+ nserror err;
+ nsurl *url = browser_window_access_url(bw);
+ lwc_string *host = nsurl_get_component(url, NSURL_HOST);
+ const char *string = (host != NULL) ? lwc_string_data(host) : NULL;
+
+ err = guit->misc->present_cookies(string);
+
+ if (host != NULL) {
+ lwc_string_unref(host);
+ }
+ return err;
+}
+
+/* Exported interface, documented in browser_window.h */
+nserror browser_window_show_certificates(struct browser_window *bw)
+{
+ nserror res;
+ nsurl *url;
+
+ if (bw->current_cert_chain == NULL) {
+ return NSERROR_NOT_FOUND;
+ }
+
+ res = cert_chain_to_query(bw->current_cert_chain, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY |
+ BW_CREATE_FOREGROUND |
+ BW_CREATE_TAB,
+ url,
+ NULL,
+ bw,
+ NULL);
+
+ nsurl_unref(url);
+ }
+
+ return res;
+}