From 3bfb5b96a7c7cb2718a60987e69cd659ed49b9d8 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 14 Feb 2013 15:09:28 +0000 Subject: [PATCH] browser_window_navigate refactor --- amiga/arexx.c | 50 ++++- amiga/context_menu.c | 86 ++++++++- amiga/download.c | 18 +- amiga/file.c | 17 +- amiga/gui.c | 135 +++++++++++-- amiga/menu.c | 21 +- amiga/tree.c | 20 +- atari/ctxmenu.c | 34 +++- atari/toolbar.c | 45 ++++- beos/gui.cpp | 2 +- beos/scaffolding.cpp | 89 ++++++++- cocoa/BookmarksController.m | 33 +++- cocoa/BrowserView.m | 48 ++++- cocoa/BrowserViewController.m | 37 +++- desktop/browser.c | 353 +++++++++++++++------------------- desktop/browser.h | 71 +++++-- desktop/frames.c | 25 +-- desktop/history_core.c | 36 ++-- framebuffer/gui.c | 19 +- gtk/dialogs/about.c | 34 +++- gtk/scaffolding.c | 157 ++++++++++++--- javascript/jsapi/location.bnd | 26 ++- monkey/browser.c | 27 ++- render/form.c | 62 ++++-- render/html_interaction.c | 23 ++- riscos/gui.c | 48 +++-- riscos/gui/url_bar.c | 29 ++- riscos/url_complete.c | 15 +- riscos/window.c | 82 ++++++-- utils/errors.h | 4 +- windows/gui.c | 56 +++++- 31 files changed, 1283 insertions(+), 419 deletions(-) diff --git a/amiga/arexx.c b/amiga/arexx.c index 7048c0673..66b1ad88e 100755 --- a/amiga/arexx.c +++ b/amiga/arexx.c @@ -223,12 +223,18 @@ STATIC VOID rx_open(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((unu { struct dlnode *dln; struct browser_window *bw = curbw; + nsurl *url; cmd->ac_RC = 0; if((cmd->ac_ArgList[4]) && (cmd->ac_ArgList[5])) bw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[4], *(ULONG *)cmd->ac_ArgList[5]); + if (nsurl_create((char *)cmd->ac_ArgList[0], &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + return; + } + if(cmd->ac_ArgList[3]) { if(!bw) return; @@ -238,27 +244,44 @@ STATIC VOID rx_open(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((unu dln->node.ln_Name = strdup((char *)cmd->ac_ArgList[0]); dln->node.ln_Type = NT_USER; AddTail(&bw->window->dllist, (struct Node *)dln); - if(!bw->download) browser_window_download(curbw,(char *)cmd->ac_ArgList[0],NULL); + if(!bw->download) { + browser_window_navigate(curbw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + } } else if(cmd->ac_ArgList[2]) { - browser_window_create((char *)cmd->ac_ArgList[0],NULL,NULL,true,true); + browser_window_create(url, NULL, NULL, true, true); } else if(cmd->ac_ArgList[1]) { - browser_window_create((char *)cmd->ac_ArgList[0],NULL,NULL,true,false); + browser_window_create(url, NULL, NULL, true, false); } else { if(bw) { - browser_window_go(bw,(char *)cmd->ac_ArgList[0],NULL,true); + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); } else { - browser_window_create((char *)cmd->ac_ArgList[0],NULL,NULL,true,false); + browser_window_create(url, NULL, NULL, true, false); } } + nsurl_unref(url); } STATIC VOID rx_save(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((unused))) @@ -456,13 +479,28 @@ STATIC VOID rx_forward(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__(( STATIC VOID rx_home(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((unused))) { struct browser_window *bw = curbw; + nsurl *url; cmd->ac_RC = 0; if((cmd->ac_ArgList[0]) && (cmd->ac_ArgList[1])) bw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[0], *(ULONG *)cmd->ac_ArgList[1]); - if(bw) browser_window_go(bw, nsoption_charp(homepage_url), NULL, true); + if(bw == NULL) return; + + if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } STATIC VOID rx_reload(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((unused))) diff --git a/amiga/context_menu.c b/amiga/context_menu.c index 2e09c99b6..952d5c2c8 100755 --- a/amiga/context_menu.c +++ b/amiga/context_menu.c @@ -788,19 +788,54 @@ static uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved case CMID_FRAMESAVE: case CMID_SAVEURL: - browser_window_download(gwin->bw, userdata, - nsurl_access(hlcache_handle_get_url(gwin->bw->current_content))); + { + nsurl *url; + if (nsurl_create(userdata, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + hlcache_handle_get_url(gwin->bw->current_content), + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } break; case CMID_FRAMESHOW: case CMID_SHOWOBJ: - browser_window_go(gwin->bw, nsurl_access(hlcache_handle_get_url(userdata)), - nsurl_access(hlcache_handle_get_url(gwin->bw->current_content)), true); + browser_window_navigate(gwin->bw, + hlcache_handle_get_url(userdata), + hlcache_handle_get_url(gwin->bw->current_content), + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + break; case CMID_URLOPEN: - browser_window_go(gwin->bw, userdata, - nsurl_access(hlcache_handle_get_url(gwin->bw->current_content)), true); + { + nsurl *url; + if (nsurl_create(userdata, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + hlcache_handle_get_url(gwin->bw->current_content), + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } break; case CMID_FRAMERELOAD: @@ -860,7 +895,24 @@ static uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved break; case CMID_NAVHOME: - browser_window_go(gwin->bw, nsoption_charp(homepage_url), NULL, true); + { + nsurl *url; + + if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + + } break; case CMID_NAVBACK: @@ -911,12 +963,26 @@ static uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved case CMID_SELSEARCH: { struct ami_text_selection *sel; - char *url; + char *urltxt; + nsurl *url; if(sel = ami_selection_to_text(gwin)) { - url = search_web_from_term(sel->text); - browser_window_go(gwin->bw, url, NULL, true); + urltxt = search_web_from_term(sel->text); + + if (nsurl_create(urltxt, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } FreeVec(sel); } diff --git a/amiga/download.c b/amiga/download.c index c49bd8554..9db05ca49 100644 --- a/amiga/download.c +++ b/amiga/download.c @@ -291,7 +291,23 @@ void gui_download_window_done(struct gui_download_window *dw) DisposeObject(dw->objects[OID_MAIN]); DelObject(dw->node); - if(queuedl) browser_window_download(bw,dln2->node.ln_Name,NULL); + if(queuedl) { + nsurl *url; + if (nsurl_create(dln2->node.ln_Name, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } + } BOOL ami_download_window_event(struct gui_download_window *dw) diff --git a/amiga/file.c b/amiga/file.c index 30a63b615..419cc2a4d 100644 --- a/amiga/file.c +++ b/amiga/file.c @@ -80,6 +80,7 @@ static const ULONG ami_file_asl_mime_hook(struct Hook *mh, void ami_file_open(struct gui_window_2 *gwin) { char *temp, *temp2; + nsurl *url; if(AslRequestTags(filereq, ASLFR_TitleText, messages_get("NetSurf"), @@ -94,7 +95,21 @@ void ami_file_open(struct gui_window_2 *gwin) strlcpy(temp, filereq->fr_Drawer, 1024); AddPart(temp, filereq->fr_File, 1024); temp2 = path_to_url(temp); - browser_window_go(gwin->bw, temp2, NULL, true); + + if (nsurl_create(temp2, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + free(temp2); FreeVec(temp); } diff --git a/amiga/gui.c b/amiga/gui.c index 60950d244..62aa87713 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -1633,8 +1633,23 @@ void ami_handle_msg(void) { storage = (ULONG)search_web_from_term((char *)storage); } + { + nsurl *url; - browser_window_go(gwin->bw,(char *)storage, NULL, true); + if (nsurl_create((char *)storage, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } break; case GID_TOOLBARLAYOUT: @@ -1647,12 +1662,43 @@ void ami_handle_msg(void) (Object *)gwin->objects[GID_SEARCHSTRING], (ULONG *)&storage); storage = (ULONG)search_web_from_term((char *)storage); + { + nsurl *url; - browser_window_go(gwin->bw,(char *)storage, NULL, true); + if (nsurl_create((char *)storage, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } break; case GID_HOME: - browser_window_go(gwin->bw,nsoption_charp(homepage_url),NULL,true); + { + nsurl *url; + + if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } break; case GID_STOP: @@ -2070,16 +2116,32 @@ void ami_handle_appmsg(void) if(ami_mouse_to_ns_coords(gwin, &x, &y, appmsg->am_MouseX, appmsg->am_MouseY) == false) { + nsurl *url; urlfilename = path_to_url(filename); - if(i == 0) - { - browser_window_go(gwin->bw, urlfilename, NULL, true); - ActivateWindow(gwin->win); + if (nsurl_create(urlfilename, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); } else { - browser_window_create(urlfilename, gwin->bw, 0, true, true); + if(i == 0) + { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + + ActivateWindow(gwin->win); + } + else + { + browser_window_create(url, NULL, gwin->bw, true, true); + } + nsurl_unref(url); } free(urlfilename); @@ -2088,16 +2150,33 @@ void ami_handle_appmsg(void) { if(browser_window_drop_file_at_point(gwin->bw, x, y, filename) == false) { + nsurl *url; urlfilename = path_to_url(filename); - if(i == 0) - { - browser_window_go(gwin->bw, urlfilename, NULL, true); - ActivateWindow(gwin->win); + if (nsurl_create(urlfilename, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); } else { - browser_window_create(urlfilename, gwin->bw, 0, true, true); + + if(i == 0) + { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + + ActivateWindow(gwin->win); + } + else + { + browser_window_create(url, NULL, gwin->bw, true, true); + } + nsurl_unref(url); } free(urlfilename); } @@ -4519,7 +4598,8 @@ void ami_scroller_hook(struct Hook *hook,Object *object,struct IntuiMessage *msg struct IntuiWheelData *wheel; Object *reqrefresh = NULL; struct Node *node = NULL; - char *url; + char *urltxt; + nsurl *url; switch(msg->Class) { @@ -4539,12 +4619,29 @@ void ami_scroller_hook(struct Hook *hook,Object *object,struct IntuiMessage *msg case GID_HOTLIST: if(node = (struct Node *)GetTagData(SPEEDBAR_SelectedNode, 0, msg->IAddress)) { - GetSpeedButtonNodeAttrs(node, SBNA_UserData, (ULONG *)&url, TAG_DONE); - - if(gwin->key_state & BROWSER_MOUSE_MOD_2) { - browser_window_create(url, gwin->bw, NULL, false, true); + GetSpeedButtonNodeAttrs(node, SBNA_UserData, (ULONG *)&urltxt, TAG_DONE); + + if (nsurl_create(urltxt, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); } else { - browser_window_go(gwin->bw, url, NULL, true); + if(gwin->key_state & BROWSER_MOUSE_MOD_2) { + browser_window_create(url, + NULL, + gwin->bw, + false, + true); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + + } + nsurl_unref(url); } } break; diff --git a/amiga/menu.c b/amiga/menu.c index 496400dfb..f480b3f69 100755 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -985,11 +985,28 @@ static void ami_menu_item_hotlist_show(struct Hook *hook, APTR window, struct In static void ami_menu_item_hotlist_entries(struct Hook *hook, APTR window, struct IntuiMessage *msg) { - char *url = hook->h_Data; + nsurl *url; + nserror error; + char *urltxt = hook->h_Data; struct gui_window_2 *gwin; GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); - if(url) browser_window_go(gwin->bw, url, NULL, true); + if(urltxt == NULL) return; + + error = nsurl_create(addr, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } static void ami_menu_item_settings_edit(struct Hook *hook, APTR window, struct IntuiMessage *msg) diff --git a/amiga/tree.c b/amiga/tree.c index cbaef836e..32cd8a1fa 100755 --- a/amiga/tree.c +++ b/amiga/tree.c @@ -317,8 +317,24 @@ void ami_tree_drag_end(struct treeview_window *twin, int x, int y) { if(gwin = ami_window_at_pointer(AMINS_WINDOW)) { - browser_window_go(gwin->bw, tree_url_node_get_url(selected_node), - NULL, true); + nsurl *url; + nserror error; + + error = nsurl_create(tree_url_node_get_url(selected_node), &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(gwin->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } else if((tw = ami_window_at_pointer(AMINS_TVWINDOW)) && (tw != twin) && (tw->type == AMI_TREE_HOTLIST)) diff --git a/atari/ctxmenu.c b/atari/ctxmenu.c index d89060a65..859aeea5b 100644 --- a/atari/ctxmenu.c +++ b/atari/ctxmenu.c @@ -192,21 +192,37 @@ void context_popup(struct gui_window * gw, short x, short y) case POP_CTX_SAVE_AS: if (ctx->ccdata.object != NULL) { if( hlcache_handle_get_url(ctx->ccdata.object) != NULL ) { - browser_window_download( + browser_window_navigate( gw->browser->bw, - nsurl_access(hlcache_handle_get_url(ctx->ccdata.object)), - nsurl_access(hlcache_handle_get_url(gw->browser->bw->current_content)) - ); + hlcache_handle_get_url(ctx->ccdata.object), + hlcache_handle_get_url(gw->browser->bw->current_content), + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL + ); } } case POP_CTX_SAVE_LINK_AS: if (ctx->ccdata.link_url != NULL) { - browser_window_download( - gw->browser->bw, - ctx->ccdata.link_url, - nsurl_access(hlcache_handle_get_url(gw->browser->bw->current_content)) - ); + nsurl *url; + if (nsurl_create(ctx->ccdata.link_url, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate( + gw->browser->bw, + url, + hlcache_handle_get_url(gw->browser->bw->current_content), + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL + ); + nsurl_unref(url); + } } break; diff --git a/atari/toolbar.c b/atari/toolbar.c index d71f2eeb0..eca44fa88 100644 --- a/atari/toolbar.c +++ b/atari/toolbar.c @@ -705,10 +705,25 @@ bool toolbar_key_input(struct s_toolbar *tb, short nkc) } } else if (ik == KEY_CR || ik == KEY_NL) { + nsurl *url; char tmp_url[PATH_MAX]; if ( textarea_get_text( tb->url.textarea, tmp_url, PATH_MAX) > 0 ) { window_set_focus(tb->owner, BROWSER, gw->browser); - browser_window_go(gw->browser->bw, (const char*)&tmp_url, 0, true); + + if (nsurl_create((const char*)&tmp_url, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gw->browser->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + ret = true; } } @@ -939,14 +954,28 @@ void toolbar_forward_click(struct s_toolbar *tb) void toolbar_home_click(struct s_toolbar *tb) { - struct browser_window * bw; - struct gui_window * gw; + struct browser_window * bw; + struct gui_window * gw; + nsurl *url; - gw = window_get_active_gui_window(tb->owner); - assert(gw != NULL); - bw = gw->browser->bw; - assert(bw != NULL); - browser_window_go(bw, option_homepage_url, 0, true); + gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + bw = gw->browser->bw; + assert(bw != NULL); + + if (nsurl_create(nsoption_charp(option_homepage_url), &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } diff --git a/beos/gui.cpp b/beos/gui.cpp index 133ee8ca8..c556d45e5 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -1071,7 +1071,7 @@ static void nsbeos_ssl_accept(beosButton *w, gpointer data) beosWindow *wnd = session[3]; urldb_set_cert_permissions(url, true); - browser_window_go(bw, url, 0, true); + browser_window_navigate(bw, url, 0, true); beos_widget_destroy(beos_WIDGET(wnd)); g_object_unref(G_OBJECT(x)); diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index 709795b53..0a337685d 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -782,10 +782,29 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m } else url << path.Path(); - if (/*message->WasDropped() &&*/ i == 0) - browser_window_go(bw, url.String(), 0, true); - else - browser_window_create(url.String(), bw, NULL, false, false); + nsurl *nsurl; + nserror error; + + error = nsurl_create(url.String(), &nsurl); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + if (/*message->WasDropped() &&*/ i == 0) { + browser_window_navigate(bw, + nsurl, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + } else { + browser_window_create(nsurl, NULL, bw, false, false); + } + nsurl_unref(nsurl); + } + + } break; } @@ -808,7 +827,24 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m BString url; if (message->FindString("be:url", &url) < B_OK) break; - browser_window_go(bw, url.String(), 0, true); + + nsurl *nsurl; + nserror error; + + error = nsurl_create(url.String(), &nsurl); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + nsurl, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(nsurl); + } break; } case B_COPY: @@ -857,23 +893,58 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m case BROWSER_NAVIGATE_HOME: case 'home': { + nsurl *url; + nserror error; + static const char *addr = NETSURF_HOMEPAGE; - if (nsoption_charp(homepage_url) != NULL) + if (nsoption_charp(homepage_url) != NULL) { addr = nsoption_charp(homepage_url); + } - browser_window_go(bw, addr, 0, true); + error = nsurl_create(addr, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } break; } case 'urle': { + nsurl *url; + nserror error; BString text; + if (!scaffold->url_bar->LockLooper()) break; + text = scaffold->url_bar->Text(); scaffold->scroll_view->Target()->MakeFocus(); scaffold->url_bar->UnlockLooper(); - browser_window_go(bw, text.String(), 0, true); + + error = nsurl_create(text.String(), &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } break; } case 'urlc': @@ -1136,7 +1207,7 @@ gboolean nsbeos_openfile_open(beosWidget *widget, gpointer data) sprintf(url, "file://%s", filename); - browser_window_go(bw, url, 0, true); + browser_window_navigate(bw, url, 0, true); g_free(filename); free(url); diff --git a/cocoa/BookmarksController.m b/cocoa/BookmarksController.m index 78bbec004..bb43b2fde 100644 --- a/cocoa/BookmarksController.m +++ b/cocoa/BookmarksController.m @@ -128,15 +128,34 @@ static const char *cocoa_hotlist_path( void ) - (IBAction) openBookmarkURL: (id) sender; { - const char *url = [[sender representedObject] UTF8String]; - NSParameterAssert( url != NULL ); - - BrowserViewController *tab = [(NetSurfApp *)NSApp frontTab]; - if (tab != nil) { - browser_window_go( [tab browser], url, NULL, true ); + const char *urltxt = [[sender representedObject] UTF8String]; + NSParameterAssert( urltxt != NULL ); + + nsurl *url; + nserror error; + + error = nsurl_create(urltxt, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); } else { - browser_window_create( url, NULL, NULL, true, false ); + BrowserViewController *tab = [(NetSurfApp *)NSApp frontTab]; + if (tab != nil) { + browser_window_navigate([tab browser], + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + } else { + browser_window_create( url, NULL, NULL, true, false ); + } + + nsurl_unref(url); } + + } - (IBAction) addBookmark: (id) sender; diff --git a/cocoa/BrowserView.m b/cocoa/BrowserView.m index 72ba0ea00..63efac468 100644 --- a/cocoa/BrowserView.m +++ b/cocoa/BrowserView.m @@ -585,7 +585,19 @@ static browser_mouse_state cocoa_mouse_flags_for_event( NSEvent *evt ) - (IBAction) cmDownloadURL: (id) sender; { - browser_window_download( browser, [[sender representedObject] UTF8String], NULL ); + nsurl *url; + + if (nsurl_create([[sender representedObject] UTF8String], &url) == NSERROR_OK) { + browser_window_navigate(browser, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } - (IBAction) cmImageCopy: (id) sender; @@ -622,17 +634,37 @@ static browser_mouse_state cocoa_mouse_flags_for_event( NSEvent *evt ) - (BOOL)performDragOperation:(id )sender { - NSPasteboard *pb = [sender draggingPasteboard]; + nsurl *url; + nserror error; - NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObjects: @"public.url", NSURLPboardType, nil]]; + NSPasteboard *pb = [sender draggingPasteboard]; - NSString *url = nil; - if ([type isEqualToString: NSURLPboardType]) url = [[NSURL URLFromPasteboard: pb] absoluteString]; - else url = [pb stringForType: type]; + NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObjects: @"public.url", NSURLPboardType, nil]]; + + NSString *urlstr = nil; + + if ([type isEqualToString: NSURLPboardType]) { + urlstr = [[NSURL URLFromPasteboard: pb] absoluteString]; + } else { + urlstr = [pb stringForType: type]; + } - browser_window_go( browser, [url UTF8String], NULL, true ); + error = nsurl_create([urlstr UTF8String], &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(browser, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } - return YES; + return YES; } // MARK: - diff --git a/cocoa/BrowserViewController.m b/cocoa/BrowserViewController.m index f8b26e12f..7a134eedf 100644 --- a/cocoa/BrowserViewController.m +++ b/cocoa/BrowserViewController.m @@ -67,7 +67,23 @@ - (IBAction) navigate: (id) sender; { - browser_window_go( browser, [url UTF8String], NULL, true ); + nsurl *unsrl; + nserror error; + + error = nsurl_create([url UTF8String], &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(browser, + nsurl, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } - (void) awakeFromNib; @@ -115,7 +131,24 @@ - (IBAction) goHome: (id) sender; { - browser_window_go( browser, nsoption_charp(homepage_url), NULL, true ); + nsurl *url; + nserror error; + + error = nsurl_create(nsoption_charp(homepage_url), &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(browser, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } - (IBAction) reloadPage: (id) sender; diff --git a/desktop/browser.c b/desktop/browser.c index f9353afef..c373e84e3 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -662,17 +662,20 @@ void browser_window_debug_dump(struct browser_window *bw, FILE *f) /** * Create and open a new root browser window with the given page. * - * \param url URL to start fetching in the new window (copied) + * \param url URL to start fetching in the new window + * \param referer The referring uri or NULL if none * \param clone The browser window to clone - * \param referer The referring uri (copied), or 0 if none * \param history_add add to history * \param new_tab create a new tab * \return new browser window or NULL on error */ -struct browser_window *browser_window_create(const char *url, - struct browser_window *clone, - const char *referer, bool history_add, bool new_tab) +struct browser_window * +browser_window_create(nsurl *url, + nsurl *referer, + struct browser_window *clone, + bool history_add, + bool new_tab) { struct browser_window *bw; struct browser_window *top; @@ -709,11 +712,15 @@ struct browser_window *browser_window_create(const char *url, return NULL; } - if (url) { - browser_window_go(bw, url, referer, history_add); + if (url != NULL) { + enum browser_window_nav_flags flags; + flags = BROWSER_WINDOW_GO_FLAG_VERIFIABLE; + if (history_add) { + flags |= BROWSER_WINDOW_GO_FLAG_HISTORY; + } + browser_window_navigate(bw, url, referer, flags, NULL, NULL, NULL); } - return bw; } @@ -755,92 +762,55 @@ void browser_window_initialise_common(struct browser_window *bw, bw->status_miss = 0; } - /** - * Start fetching a page in a browser window. - * - * \param bw browser window - * \param url URL to start fetching (copied) - * \param referer the referring uri (copied), or 0 if none - * \param history_add Add to history - * - * Any existing fetches in the window are aborted. + * implements the download operation of a window navigate */ - -void browser_window_go(struct browser_window *bw, const char *url, - const char *referer, bool history_add) +static nserror +browser_window_download(struct browser_window *bw, + nsurl *url, + nsurl *nsref, + uint32_t fetch_flags, + bool fetch_is_post, + llcache_post_data *post) { - /* All fetches passing through here are verifiable - * (i.e are the result of user action) */ - browser_window_go_post(bw, url, 0, 0, history_add, referer, - false, true, NULL); + llcache_handle *l; + struct browser_window *root; + nserror error; + + root = browser_window_get_root(bw); + assert(root != NULL); + + fetch_flags |= LLCACHE_RETRIEVE_FORCE_FETCH; + fetch_flags |= LLCACHE_RETRIEVE_STREAM_DATA; + + error = llcache_handle_retrieve(url, fetch_flags, nsref, + fetch_is_post ? post : NULL, + NULL, NULL, &l); + if (error == NSERROR_NO_FETCH_HANDLER) { + /* no internal handler for this type, call out to frontend */ + gui_launch_url(nsurl_access(url)); + } else if (error != NSERROR_OK) { + LOG(("Failed to fetch download: %d", error)); + } else { + error = download_context_create(l, root->window); + if (error != NSERROR_OK) { + LOG(("Failed creating download context: %d", error)); + llcache_handle_abort(l); + llcache_handle_release(l); + } + } + + return error; } - -/** - * Start a download of the given URL from a browser window. - * - * \param bw browser window - * \param url URL to start downloading (copied) - * \param referer the referring uri (copied), or 0 if none - */ - -void browser_window_download(struct browser_window *bw, const char *url, - const char *referer) -{ - browser_window_go_post(bw, url, 0, 0, false, referer, - true, true, NULL); -} - - -/** - * Start fetching a page in a browser window. - * - * \param bw browser window - * \param url URL to start fetching (copied) - * \param referer the referring uri (copied), or 0 if none - * \param history_add add to history - * \param parent parent handle - * - * Any existing fetches in the window are aborted. - */ - -void browser_window_go_unverifiable(struct browser_window *bw, - const char *url, const char *referer, bool history_add, - hlcache_handle *parent) -{ - /* All fetches passing through here are unverifiable - * (i.e are not the result of user action) */ - browser_window_go_post(bw, url, 0, 0, history_add, referer, - false, false, parent); -} - -/** - * Start fetching a page in a browser window, POSTing form data. - * - * \param bw browser window - * \param url URL to start fetching (copied) - * \param post_urlenc url encoded post data, or 0 if none - * \param post_multipart multipart post data, or 0 if none - * \param add_to_history add to window history - * \param referer the referring uri (copied), or 0 if none - * \param download download, rather than render the uri - * \param verifiable this transaction is verifiable - * \param parent Parent content, or NULL - * - * Any existing fetches in the window are aborted. - * - * If post_urlenc and post_multipart are 0 the url is fetched using GET. - * - * The page is not added to the window history if add_to_history is false. - * This should be used when returning to a page in the window history. - */ - -void browser_window_go_post(struct browser_window *bw, const char *url, - char *post_urlenc, - struct fetch_multipart_data *post_multipart, - bool add_to_history, const char *referer, bool download, - bool verifiable, hlcache_handle *parent) +/* exported interface documented in desktop/browser.h */ +nserror browser_window_navigate(struct browser_window *bw, + nsurl *url, + nsurl *referrer, + enum browser_window_nav_flags flags, + char *post_urlenc, + struct fetch_multipart_data *post_multipart, + hlcache_handle *parent) { hlcache_handle *c; int depth = 0; @@ -851,24 +821,23 @@ void browser_window_go_post(struct browser_window *bw, const char *url, hlcache_child_context child; nserror error; - nsurl *nsref = NULL; - nsurl *nsurl; - LOG(("bw %p, url %s", bw, url)); assert(bw); assert(url); /* don't allow massively nested framesets */ - for (cur = bw; cur->parent; cur = cur->parent) + for (cur = bw; cur->parent; cur = cur->parent) { depth++; + } if (depth > FRAME_DEPTH) { LOG(("frame depth too high.")); - return; + return NSERROR_FRAME_DEPTH; } /* Set up retrieval parameters */ - if (verifiable) + if ((flags & BROWSER_WINDOW_GO_FLAG_VERIFIABLE) != 0) { fetch_flags |= LLCACHE_RETRIEVE_VERIFIABLE; + } if (post_multipart != NULL) { post.type = LLCACHE_POST_MULTIPART; @@ -878,72 +847,46 @@ void browser_window_go_post(struct browser_window *bw, const char *url, post.data.urlenc = post_urlenc; } - if (parent != NULL && content_get_type(parent) == CONTENT_HTML) { + if ((parent != NULL) && (content_get_type(parent) == CONTENT_HTML)) { child.charset = html_get_encoding(parent); child.quirks = content_get_quirks(parent); } - error = nsurl_create(url, &nsurl); - if (error != NSERROR_OK) { - return; - } + url = nsurl_ref(url); - if (referer != NULL) { - error = nsurl_create(referer, &nsref); - if (error != NSERROR_OK) { - nsurl_unref(nsurl); - return; - } + if (referrer != NULL) { + referrer = nsurl_ref(referrer); } /* Get download out of the way */ - if (download) { - llcache_handle *l; - struct browser_window *root; - - root = browser_window_get_root(bw); - assert(root != NULL); - - fetch_flags |= LLCACHE_RETRIEVE_FORCE_FETCH; - fetch_flags |= LLCACHE_RETRIEVE_STREAM_DATA; - - error = llcache_handle_retrieve(nsurl, fetch_flags, nsref, - fetch_is_post ? &post : NULL, - NULL, NULL, &l); - if (error == NSERROR_NO_FETCH_HANDLER) { - gui_launch_url(nsurl_access(nsurl)); - } else if (error != NSERROR_OK) { - LOG(("Failed to fetch download: %d", error)); - } else { - error = download_context_create(l, root->window); - if (error != NSERROR_OK) { - LOG(("Failed creating download context: %d", - error)); - llcache_handle_abort(l); - llcache_handle_release(l); - } + if ((flags & BROWSER_WINDOW_GO_FLAG_DOWNLOAD) != 0) { + error = browser_window_download(bw, + url, + referrer, + fetch_flags, + fetch_is_post, + &post); + nsurl_unref(url); + if (referrer != NULL) { + nsurl_unref(referrer); } - - nsurl_unref(nsurl); - if (nsref != NULL) - nsurl_unref(nsref); - - return; + return error; } - if (bw->frag_id != NULL) + if (bw->frag_id != NULL) { lwc_string_unref(bw->frag_id); + } bw->frag_id = NULL; - if (nsurl_has_component(nsurl, NSURL_FRAGMENT)) { + if (nsurl_has_component(url, NSURL_FRAGMENT)) { bool same_url = false; - bw->frag_id = nsurl_get_component(nsurl, NSURL_FRAGMENT); + bw->frag_id = nsurl_get_component(url, NSURL_FRAGMENT); /* Compare new URL with existing one (ignoring fragments) */ - if (bw->current_content != NULL && - hlcache_handle_get_url(bw->current_content) != NULL) { - same_url = nsurl_compare(nsurl, + if ((bw->current_content != NULL) && + (hlcache_handle_get_url(bw->current_content) != NULL)) { + same_url = nsurl_compare(url, hlcache_handle_get_url(bw->current_content), NSURL_COMPLETE); } @@ -951,23 +894,30 @@ void browser_window_go_post(struct browser_window *bw, const char *url, /* if we're simply moving to another ID on the same page, * don't bother to fetch, just update the window. */ - if (same_url && fetch_is_post == false && - nsurl_has_component(nsurl, NSURL_QUERY) == - false) { - nsurl_unref(nsurl); - if (nsref != NULL) - nsurl_unref(nsref); - if (add_to_history) - history_add(bw->history, bw->current_content, - bw->frag_id == NULL ? NULL : - lwc_string_data(bw->frag_id)); + if ((same_url) && + (fetch_is_post == false) && + (nsurl_has_component(url, NSURL_QUERY) == false)) { + nsurl_unref(url); + + if (referrer != NULL) { + nsurl_unref(referrer); + } + + if ((flags & BROWSER_WINDOW_GO_FLAG_HISTORY) != 0) { + history_add(bw->history, + bw->current_content, + bw->frag_id == NULL ? NULL : + lwc_string_data(bw->frag_id)); + } + browser_window_update(bw, false); + if (bw->current_content != NULL) { browser_window_refresh_url_bar(bw, hlcache_handle_get_url(bw->current_content), bw->frag_id); } - return; + return NSERROR_OK; } } @@ -975,53 +925,55 @@ void browser_window_go_post(struct browser_window *bw, const char *url, browser_window_remove_caret(bw); browser_window_destroy_children(bw); - LOG(("Loading '%s'", nsurl_access(nsurl))); + LOG(("Loading '%s'", nsurl_access(url))); browser_window_set_status(bw, messages_get("Loading")); - bw->history_add = add_to_history; + if ((flags & BROWSER_WINDOW_GO_FLAG_HISTORY) != 0) { + bw->history_add = true; + } /* Verifiable fetches may trigger a download */ - if (verifiable) + if ((flags & BROWSER_WINDOW_GO_FLAG_VERIFIABLE) != 0) { fetch_flags |= HLCACHE_RETRIEVE_MAY_DOWNLOAD; + } - error = hlcache_handle_retrieve(nsurl, + error = hlcache_handle_retrieve(url, fetch_flags | HLCACHE_RETRIEVE_SNIFF_TYPE, - nsref, + referrer, fetch_is_post ? &post : NULL, browser_window_callback, bw, parent != NULL ? &child : NULL, CONTENT_ANY, &c); switch (error) { - case NSERROR_NO_FETCH_HANDLER: /* no handler for this type */ - gui_launch_url(nsurl_access(nsurl)); - nsurl_unref(nsurl); - if (nsref != NULL) - nsurl_unref(nsref); - break; - case NSERROR_OK: bw->loading_content = c; browser_window_start_throbber(bw); - browser_window_refresh_url_bar(bw, nsurl, NULL); - - nsurl_unref(nsurl); - if (nsref != NULL) - nsurl_unref(nsref); + browser_window_refresh_url_bar(bw, url, NULL); break; - default: /* assume out of memory */ - /* TODO: fix all fetcher errors being reported as OOM? */ - nsurl_unref(nsurl); - if (nsref != NULL) - nsurl_unref(nsref); - browser_window_set_status(bw, messages_get("NoMemory")); - warn_user("NoMemory", 0); + case NSERROR_NO_FETCH_HANDLER: /* no handler for this type */ + /** @todo does this always try and download even unverifiable content? */ + gui_launch_url(nsurl_access(url)); + break; + default: /* report error to user */ + browser_window_set_status(bw, messages_get_errorcode(error)); + /** @todo should the caller report the error? */ + warn_user(messages_get_errorcode(error), 0); + break; + + } + + nsurl_unref(url); + if (referrer != NULL) { + nsurl_unref(referrer); } /* Record time */ bw->last_action = wallclock(); + + return error; } @@ -1658,9 +1610,10 @@ void browser_window_convert_to_download(struct browser_window *bw, void browser_window_refresh(void *p) { struct browser_window *bw = p; - bool history_add = true; - const char *url; - const char *refresh; + nsurl *url; + nsurl *refresh; + hlcache_handle *parent = NULL; + enum browser_window_nav_flags flags = BROWSER_WINDOW_GO_FLAG_NONE; assert(bw->current_content != NULL && (content_get_status(bw->current_content) == @@ -1670,16 +1623,17 @@ void browser_window_refresh(void *p) /* Ignore if the refresh URL has gone * (may happen if a fetch error occurred) */ - refresh = nsurl_access(content_get_refresh_url(bw->current_content)); + refresh = content_get_refresh_url(bw->current_content); if (refresh == NULL) return; /* mark this content as invalid so it gets flushed from the cache */ content_invalidate_reuse_data(bw->current_content); - url = nsurl_access(hlcache_handle_get_url(bw->current_content)); - if (url != NULL && strcmp(url, refresh) == 0) - history_add = false; + url = hlcache_handle_get_url(bw->current_content); + if ((url == NULL) || (nsurl_compare(url, refresh, NSURL_COMPLETE))) { + flags |= BROWSER_WINDOW_GO_FLAG_HISTORY; + } /* Treat an (almost) immediate refresh in a top-level browser window as * if it were an HTTP redirect, and thus make the resulting fetch @@ -1689,11 +1643,19 @@ void browser_window_refresh(void *p) * all. */ if (bw->refresh_interval <= 100 && bw->parent == NULL) { - browser_window_go(bw, refresh, url, history_add); + flags |= BROWSER_WINDOW_GO_FLAG_VERIFIABLE; } else { - browser_window_go_unverifiable(bw, refresh, url, history_add, - bw->current_content); + parent = bw->current_content; } + + browser_window_navigate(bw, + refresh, + url, + flags, + NULL, + NULL, + parent); + } @@ -1962,8 +1924,13 @@ void browser_window_reload(struct browser_window *bw, bool all) content_invalidate_reuse_data(bw->current_content); - browser_window_go(bw, nsurl_access( - hlcache_handle_get_url(bw->current_content)), 0, false); + browser_window_navigate(bw, + hlcache_handle_get_url(bw->current_content), + NULL, + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); } @@ -2386,7 +2353,7 @@ struct browser_window *browser_window_find_target(struct browser_window *bw, * OR * - button_2 opens in new tab and the link target is "_blank" */ - bw_target = browser_window_create(NULL, bw, NULL, false, true); + bw_target = browser_window_create(NULL, NULL, bw, false, true); if (!bw_target) return bw; return bw_target; @@ -2407,7 +2374,7 @@ struct browser_window *browser_window_find_target(struct browser_window *bw, * - button_2 doesn't open in new tabs and the link target is * "_blank" */ - bw_target = browser_window_create(NULL, bw, NULL, false, false); + bw_target = browser_window_create(NULL, NULL, bw, false, false); if (!bw_target) return bw; return bw_target; @@ -2441,7 +2408,7 @@ struct browser_window *browser_window_find_target(struct browser_window *bw, if (!nsoption_bool(target_blank)) return bw; - bw_target = browser_window_create(NULL, bw, NULL, false, false); + bw_target = browser_window_create(NULL, NULL, bw, false, false); if (!bw_target) return bw; diff --git a/desktop/browser.h b/desktop/browser.h index f3c68fa09..7e62eb613 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -60,30 +60,69 @@ typedef enum { DRAGGING_OTHER } browser_drag_type; - extern bool browser_reformat_pending; -struct browser_window * browser_window_create(const char *url, - struct browser_window *clone, const char *referrer, - bool history_add, bool new_tab); +/** flags to browser window go */ +enum browser_window_nav_flags { + BROWSER_WINDOW_GO_FLAG_NONE = 0, + /** The page is added to the window history, this should + * be used when returning to a page in the window history. + */ + BROWSER_WINDOW_GO_FLAG_HISTORY = 1, + /** download rather than render the uri */ + BROWSER_WINDOW_GO_FLAG_DOWNLOAD = 2, + /** this transaction is verifiable */ + BROWSER_WINDOW_GO_FLAG_VERIFIABLE = 4, +}; + void browser_window_initialise_common(struct browser_window *bw, struct browser_window *clone); -void browser_window_go(struct browser_window *bw, const char *url, - const char *referrer, bool history_add); -void browser_window_go_post(struct browser_window *bw, - const char *url, char *post_urlenc, - struct fetch_multipart_data *post_multipart, - bool add_to_history, const char *referer, bool download, - bool verifiable, struct hlcache_handle *parent); -void browser_window_go_unverifiable(struct browser_window *bw, - const char *url, const char *referrer, bool history_add, - struct hlcache_handle *parent); + +/** + * Create and open a new root browser window with the given page. + * + * \param url URL to start fetching in the new window + * \param referer The referring uri or NULL if none + * \param clone The browser window to clone + * \param history_add add to history + * \param new_tab create a new tab + * \return new browser window or NULL on error + */ +struct browser_window *browser_window_create(nsurl *url, + nsurl *referer, + struct browser_window *clone, + bool history_add, + bool new_tab); + +/** + * Start fetching a page in a browser window. + * + * \param bw browser window + * \param url URL to start fetching + * \param referrer The referring uri or NULL if none + * \param post_urlenc url encoded post data or NULL if none + * \param post_multipart multipart post data or NULL if none + * \param parent Parent content or NULL if none + * \param flags Flags to control operation + * + * Any existing fetches in the window are aborted. + * + * If post_urlenc and post_multipart are NULL the url is fetched using + * GET rather than POST. + * + */ +nserror browser_window_navigate(struct browser_window *bw, + nsurl *url, + nsurl *referrer, + enum browser_window_nav_flags flags, + char *post_urlenc, + struct fetch_multipart_data *post_multipart, + hlcache_handle *parent); + void browser_window_get_dimensions(struct browser_window *bw, int *width, int *height, bool scaled); void browser_window_set_dimensions(struct browser_window *bw, int width, int height); -void browser_window_download(struct browser_window *bw, - const char *url, const char *referrer); void browser_window_update(struct browser_window *bw, bool scroll_to_top); void browser_window_update_box(struct browser_window *bw, struct rect *rect); void browser_window_stop(struct browser_window *bw); diff --git a/desktop/frames.c b/desktop/frames.c index cc2cabfd2..235dc83ef 100644 --- a/desktop/frames.c +++ b/desktop/frames.c @@ -249,11 +249,13 @@ void browser_window_create_iframes(struct browser_window *bw, window = &(bw->iframes[index++]); if (cur->url) { /* fetch iframe's content */ - browser_window_go_unverifiable(window, - nsurl_access(cur->url), - nsurl_access(hlcache_handle_get_url( - bw->current_content)), - false, bw->current_content); + browser_window_navigate(window, + cur->url, + hlcache_handle_get_url(bw->current_content), + BROWSER_WINDOW_GO_FLAG_NONE, + NULL, + NULL, + bw->current_content); } } } @@ -384,12 +386,13 @@ void browser_window_create_frameset(struct browser_window *bw, window = &bw->children[index]; if (frame->url) { - browser_window_go_unverifiable(window, - nsurl_access(frame->url), - nsurl_access(hlcache_handle_get_url( - parent)), - true, - parent); + browser_window_navigate(window, + frame->url, + hlcache_handle_get_url(parent), + BROWSER_WINDOW_GO_FLAG_HISTORY, + NULL, + NULL, + parent); } } } diff --git a/desktop/history_core.c b/desktop/history_core.c index 2430e04e5..dda4bcaec 100644 --- a/desktop/history_core.c +++ b/desktop/history_core.c @@ -423,40 +423,52 @@ bool history_forward_available(struct history *history) /* Documented in history_core.h */ -void history_go(struct browser_window *bw, struct history *history, - struct history_entry *entry, bool new_window) +void history_go(struct browser_window *bw, + struct history *history, + struct history_entry *entry, + bool new_window) { - char *url; + char *full_url; + nsurl *url; struct history_entry *current; + nserror error; // LOG(("%p %p %p", bw, history, entry)); // LOG(("%s %s %s", // entry->page.url, entry->page.title, entry->page.frag_id)); if (entry->page.frag_id) { - url = malloc(strlen(entry->page.url) + + full_url = malloc(strlen(entry->page.url) + strlen(entry->page.frag_id) + 5); - if (!url) { + if (full_url == NULL) { warn_user("NoMemory", 0); return; } - sprintf(url, "%s#%s", entry->page.url, entry->page.frag_id); + sprintf(full_url, "%s#%s", entry->page.url, entry->page.frag_id); + + error = nsurl_create(full_url, &url); + free(full_url); + } else { + error = nsurl_create(entry->page.url, &url); + } + + + if (error != NSERROR_OK) { + warn_user("NoMemory", 0); + return; } - else - url = entry->page.url; if (new_window) { current = history->current; history->current = entry; - browser_window_create(url, bw, 0, false, false); + browser_window_create(url, NULL, bw, false, false); history->current = current; } else { history->current = entry; - browser_window_go(bw, url, 0, false); + browser_window_navigate(bw, url, NULL, BROWSER_WINDOW_GO_FLAG_VERIFIABLE, NULL, NULL, NULL); } - if (entry->page.frag_id) - free(url); + nsurl_unref(url); } diff --git a/framebuffer/gui.c b/framebuffer/gui.c index 8a84d4b7c..986eaaa22 100644 --- a/framebuffer/gui.c +++ b/framebuffer/gui.c @@ -1050,7 +1050,24 @@ static int fb_url_enter(void *pw, char *text) { struct browser_window *bw = pw; - browser_window_go(bw, text, 0, true); + nsurl *url; + nserror error; + + error = nsurl_create(text, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + return 0; } diff --git a/gtk/dialogs/about.c b/gtk/dialogs/about.c index 35150ff5d..7a8c10932 100644 --- a/gtk/dialogs/about.c +++ b/gtk/dialogs/about.c @@ -28,7 +28,22 @@ static void nsgtk_about_dialog_credits(GtkWidget *button, gpointer data) { struct browser_window *bw = data; - browser_window_go(bw, "about:credits", 0, true); + nsurl *url; + + if (nsurl_create("about:credits", &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + gtk_widget_destroy(gtk_widget_get_toplevel(button)); } @@ -36,7 +51,22 @@ static void nsgtk_about_dialog_licence(GtkWidget *button, gpointer data) { struct browser_window *bw = data; - browser_window_go(bw, "about:licence", 0, true); + nsurl *url; + + if (nsurl_create("about:licence", &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + gtk_widget_destroy(gtk_widget_get_toplevel(button)); } diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 287fed12b..3f027f88f 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -442,16 +442,35 @@ gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data) { struct gtk_scaffolding *g = data; struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - char *url; - if (search_is_url(gtk_entry_get_text(GTK_ENTRY(g->url_bar))) - == false) - url = search_web_from_term(gtk_entry_get_text(GTK_ENTRY( + char *urltxt; + nsurl *url; + nserror error; + + if (search_is_url(gtk_entry_get_text(GTK_ENTRY(g->url_bar))) == false) { + urltxt = search_web_from_term(gtk_entry_get_text(GTK_ENTRY( g->url_bar))); - else - url = strdup(gtk_entry_get_text(GTK_ENTRY(g->url_bar))); - browser_window_go(bw, url, 0, true); - if (url != NULL) - free(url); + } else { + urltxt = strdup(gtk_entry_get_text(GTK_ENTRY(g->url_bar))); + } + + if (urltxt != NULL) { + error = nsurl_create(urltxt, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + free(urltxt); + } + return TRUE; } @@ -525,14 +544,34 @@ static void nsgtk_window_tabs_remove(GtkNotebook *notebook, */ static void nsgtk_openfile_open(const char *filename) { - struct browser_window *bw = nsgtk_get_browser_window( - current_model->top_level); - char url[strlen(filename) + FILE_SCHEME_PREFIX_LEN + 1]; + struct browser_window *bw; + char *urltxt; + nsurl *url; + nserror error; - sprintf(url, FILE_SCHEME_PREFIX"%s", filename); + bw = nsgtk_get_browser_window(current_model->top_level); - browser_window_go(bw, url, 0, true); + urltxt = malloc(strlen(filename) + FILE_SCHEME_PREFIX_LEN + 1); + if (urltxt != NULL) { + sprintf(urltxt, FILE_SCHEME_PREFIX"%s", filename); + + error = nsurl_create(urltxt, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + free(urltxt); + } } /* signal handlers for menu entries */ @@ -898,6 +937,7 @@ MULTIHANDLER(quit) MENUHANDLER(savelink) { + nsurl *url; struct gtk_scaffolding *g = (struct gtk_scaffolding *) data; struct gui_window *gui = g->top_level; struct browser_window *bw = nsgtk_get_browser_window(gui); @@ -905,8 +945,17 @@ MENUHANDLER(savelink) if (current_menu_ctx.link_url == NULL) return FALSE; - browser_window_download(bw, current_menu_ctx.link_url, - current_menu_ctx.link_url); + if (nsurl_create(current_menu_ctx.link_url, &url) == NSERROR_OK) { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return TRUE; } @@ -1365,14 +1414,28 @@ MULTIHANDLER(forward) MULTIHANDLER(home) { static const char *addr = NETSURF_HOMEPAGE; - struct browser_window *bw = - nsgtk_get_browser_window(g->top_level); + struct browser_window *bw = nsgtk_get_browser_window(g->top_level); + nsurl *url; + nserror error; if (nsoption_charp(homepage_url) != NULL) { addr = nsoption_charp(homepage_url); } - browser_window_go(bw, addr, 0, true); + error = nsurl_create(addr, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return TRUE; } @@ -1472,24 +1535,68 @@ MULTIHANDLER(closetab) MULTIHANDLER(contents) { - browser_window_go(nsgtk_get_browser_window(g->top_level), - "http://www.netsurf-browser.org/documentation/", 0, true); + struct browser_window *bw = nsgtk_get_browser_window(g->top_level); + nsurl *url; + nserror error; + + error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return TRUE; } MULTIHANDLER(guide) { - browser_window_go(nsgtk_get_browser_window(g->top_level), - "http://www.netsurf-browser.org/documentation/guide", 0, true); + struct browser_window *bw = nsgtk_get_browser_window(g->top_level); + nsurl *url; + + if (nsurl_create("http://www.netsurf-browser.org/documentation/guide", &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return TRUE; } MULTIHANDLER(info) { - browser_window_go(nsgtk_get_browser_window(g->top_level), - "http://www.netsurf-browser.org/documentation/info", 0, true); + struct browser_window *bw = nsgtk_get_browser_window(g->top_level); + nsurl *url; + + if (nsurl_create("http://www.netsurf-browser.org/documentation/info", &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return TRUE; } diff --git a/javascript/jsapi/location.bnd b/javascript/jsapi/location.bnd index 03687ba18..3cd8898bd 100644 --- a/javascript/jsapi/location.bnd +++ b/javascript/jsapi/location.bnd @@ -59,7 +59,14 @@ operation assign %{ bw = jsapi_get_browser_window(cx); if (bw != NULL) { nsurl_join(private->url, url, &joined); - browser_window_go(bw, nsurl_access(joined), NULL, true); + browser_window_navigate(bw, + joined, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); nsurl_unref(joined); } else { JSLOG("failed to get browser context"); @@ -74,7 +81,13 @@ operation replace %{ bw = jsapi_get_browser_window(cx); if (bw != NULL) { nsurl_join(private->url, url, &joined); - browser_window_go(bw, nsurl_access(joined), NULL, false); + browser_window_navigate(bw, + joined, + NULL, + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); nsurl_unref(joined); } else { JSLOG("failed to get browser context"); @@ -113,7 +126,14 @@ setter href %{ nsurl_join(private->url, url, &joined); - browser_window_go(bw, nsurl_access(joined), NULL, false); + browser_window_navigate(bw, + joined, + NULL, + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(joined); } else { JSLOG("failed to convert string value"); diff --git a/monkey/browser.c b/monkey/browser.c index e6a57d00b..a4a923fac 100644 --- a/monkey/browser.c +++ b/monkey/browser.c @@ -431,9 +431,32 @@ monkey_window_handle_go(int argc, char **argv) if (gw == NULL) { fprintf(stdout, "ERROR WINDOW NUM BAD\n"); } else { - browser_window_go(gw->bw, argv[3], (argc == 5) ? argv[4] : NULL, true); - } + nsurl *url; + nsurl *ref_url = NULL; + nserror error; + error = nsurl_create(argv[3], &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + if (argc == 5) { + error = nsurl_create(argv[4], &ref_url); + } + + browser_window_navigate(gw->bw, + url, + ref_url, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + if (ref_url != NULL) { + nsurl_unref(ref_url); + } + } + } } static void diff --git a/render/form.c b/render/form.c index c2819b479..998d0f293 100644 --- a/render/form.c +++ b/render/form.c @@ -1443,8 +1443,9 @@ void form_submit(nsurl *page_url, struct browser_window *target, { char *data = NULL; struct fetch_multipart_data *success; - nsurl *action; + nsurl *action_url; nsurl *action_query; + nserror error; assert(form != NULL); @@ -1453,6 +1454,14 @@ void form_submit(nsurl *page_url, struct browser_window *target, return; } + /* Decompose action */ + if (nsurl_create(form->action, &action_url) != NSERROR_OK) { + free(data); + fetch_multipart_data_destroy(success); + warn_user("NoMemory", 0); + return; + } + switch (form->method) { case method_GET: data = form_url_encode(form, success, true); @@ -1462,28 +1471,26 @@ void form_submit(nsurl *page_url, struct browser_window *target, return; } - /* Decompose action */ - if (nsurl_create(form->action, &action) != NSERROR_OK) { - free(data); - fetch_multipart_data_destroy(success); - warn_user("NoMemory", 0); - return; - } - /* Replace query segment */ - if (nsurl_replace_query(action, data, &action_query) != - NSERROR_OK) { - nsurl_unref(action); + error = nsurl_replace_query(action_url, data, &action_query); + if (error != NSERROR_OK) { + nsurl_unref(action_query); free(data); fetch_multipart_data_destroy(success); - warn_user("NoMemory", 0); + warn_user(messages_get_errorcode(error), 0); return; } /* Construct submit url */ - browser_window_go(target, nsurl_access(action_query), - nsurl_access(page_url), true); - nsurl_unref(action); + browser_window_navigate(target, + action_query, + page_url, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(action_query); break; @@ -1492,19 +1499,34 @@ void form_submit(nsurl *page_url, struct browser_window *target, if (data == NULL) { fetch_multipart_data_destroy(success); warn_user("NoMemory", 0); + nsurl_unref(action_url); return; } - browser_window_go_post(target, form->action, data, 0, - true, nsurl_access(page_url), false, true, 0); + browser_window_navigate(target, + action_url, + page_url, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + data, + NULL, + NULL); break; case method_POST_MULTIPART: - browser_window_go_post(target, form->action, 0, success, - true, nsurl_access(page_url), false, true, 0); + browser_window_navigate(target, + action_url, + page_url, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + success, + NULL); + break; } + nsurl_unref(action_url); fetch_multipart_data_destroy(success); free(data); } diff --git a/render/html_interaction.c b/render/html_interaction.c index dfebc2577..16e9b1c28 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -704,10 +704,14 @@ void html_mouse_action(struct content *c, struct browser_window *bw, if (mouse & BROWSER_MOUSE_CLICK_1 && mouse & BROWSER_MOUSE_MOD_1) { /* force download of link */ - browser_window_go_post(bw, nsurl_access(url), 0, 0, - false, - nsurl_access(content_get_url(c)), - true, true, 0); + browser_window_navigate(bw, + url, + content_get_url(c), + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); } else if (mouse & BROWSER_MOUSE_CLICK_2 && mouse & BROWSER_MOUSE_MOD_1) { @@ -856,9 +860,14 @@ void html_mouse_action(struct content *c, struct browser_window *bw, gadget->form, gadget); break; case ACTION_GO: - browser_window_go(browser_window_find_target(bw, target, mouse), - nsurl_access(url), - nsurl_access(content_get_url(c)), true); + browser_window_navigate(browser_window_find_target(bw, target, mouse), + url, + content_get_url(c), + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); break; case ACTION_NONE: break; diff --git a/riscos/gui.c b/riscos/gui.c index e786f67d8..a9827c707 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -1495,10 +1495,12 @@ void ro_msg_dataload(wimp_message *message) { int file_type = message->data.data_xfer.file_type; int tree_file_type = file_type; - char *url = 0; + char *urltxt = NULL; char *title = NULL; struct gui_window *g; os_error *error; + nsurl *url; + nserror nserror; g = ro_gui_window_lookup(message->data.data_xfer.w); if (g) { @@ -1513,16 +1515,16 @@ void ro_msg_dataload(wimp_message *message) switch (file_type) { case FILETYPE_ACORN_URI: - url = ro_gui_uri_file_parse(message->data.data_xfer.file_name, + urltxt = ro_gui_uri_file_parse(message->data.data_xfer.file_name, &title); tree_file_type = 0xfaf; break; case FILETYPE_ANT_URL: - url = ro_gui_url_file_parse(message->data.data_xfer.file_name); + urltxt = ro_gui_url_file_parse(message->data.data_xfer.file_name); tree_file_type = 0xfaf; break; case FILETYPE_IEURL: - url = ro_gui_ieurl_file_parse(message->data.data_xfer.file_name); + urltxt = ro_gui_ieurl_file_parse(message->data.data_xfer.file_name); tree_file_type = 0xfaf; break; @@ -1541,27 +1543,47 @@ void ro_msg_dataload(wimp_message *message) case FILETYPE_ARTWORKS: case FILETYPE_SVG: /* display the actual file */ - url = path_to_url(message->data.data_xfer.file_name); + urltxt = path_to_url(message->data.data_xfer.file_name); break; default: return; } - if (!url) + if (!urltxt) /* error has already been reported by one of the * functions called above */ return; - if (g) { - browser_window_go(g->bw, url, 0, true); -// } else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) { -// /* Drop URL into hotlist */ -// ro_gui_hotlist_url_drop(message, url); + + nserror = nsurl_create(urltxt, &url); + if (nserror != NSERROR_OK) { + warn_user(messages_get_errorcode(nserror), 0); } else { - browser_window_create(url, 0, 0, true, false); + if (g) { + browser_window_navigate(g->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + +#if DROPURLHOTLIST /** @todo This was commented out should it be removed? */ + } else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) { + /* Drop URL into hotlist */ + ro_gui_hotlist_url_drop(message, urltxt); +#endif + + } else { + browser_window_create(url, NULL, NULL, true, false); + } + + nsurl_unref(url); } + /* send DataLoadAck */ message->action = message_DATA_LOAD_ACK; message->your_ref = message->my_ref; @@ -1573,7 +1595,7 @@ void ro_msg_dataload(wimp_message *message) return; } - free(url); + free(urltxt); } diff --git a/riscos/gui/url_bar.c b/riscos/gui/url_bar.c index 74fe2806b..eb3483d91 100644 --- a/riscos/gui/url_bar.c +++ b/riscos/gui/url_bar.c @@ -690,19 +690,36 @@ bool ro_gui_url_bar_menu_prepare(struct url_bar *url_bar, wimp_i i, bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i, wimp_menu *menu, wimp_selection *selection, menu_action action) { - const char *url; - struct gui_window *g; + const char *urltxt; + struct gui_window *g; if (url_bar == NULL || url_bar->suggest_icon != i || menu != ro_gui_url_suggest_menu) return false; - url = ro_gui_url_suggest_get_selection(selection); + urltxt = ro_gui_url_suggest_get_selection(selection); g = ro_gui_toolbar_lookup(url_bar->window); - if (url != NULL && g != NULL && g->bw != NULL) { - gui_window_set_url(g, url); - browser_window_go(g->bw, url, 0, true); + if (urltxt != NULL && g != NULL && g->bw != NULL) { + nsurl *url; + nserror error; + + gui_window_set_url(g, urltxt); + + error = nsurl_create(urltxt, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(g->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } return true; diff --git a/riscos/url_complete.c b/riscos/url_complete.c index 4d5f9d213..b804f741a 100644 --- a/riscos/url_complete.c +++ b/riscos/url_complete.c @@ -709,17 +709,22 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer) /** \todo The interaction of components here is hideous */ /* Do NOT make any attempt to use any of the global url - * completion variables after this call to browser_window_go. + * completion variables after this call to browser_window_navigate. * They will be invalidated by (at least): * + gui_window_set_url * + destruction of (i)frames within the current page * Any attempt to use them will probably result in a crash. */ - browser_window_go(g->bw, - nsurl_access(url_complete_matches[ - url_complete_matches_selection]), - 0, true); + browser_window_navigate(g->bw, + url_complete_matches[url_complete_matches_selection], + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + ro_gui_url_complete_close(); /* Adjust just sets the text */ diff --git a/riscos/window.c b/riscos/window.c index 2ad5426e7..a0a64a17f 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -2763,9 +2763,24 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, } break; case BROWSER_LINK_DOWNLOAD: - if (current_menu_url != NULL) - browser_window_download(bw, current_menu_url, - nsurl_access(hlcache_handle_get_url(h))); + if (current_menu_url != NULL) { + nsurl *url; + nserror error; + + error = nsurl_create(current_menu_url, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(bw, + url, + hlcache_handle_get_url(h), + BROWSER_WINDOW_GO_FLAG_DOWNLOAD | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } break; case BROWSER_LINK_NEW_WINDOW: if (current_menu_url != NULL) @@ -3845,16 +3860,34 @@ void ro_gui_window_prepare_objectinfo(hlcache_handle *object, const char *href) * \param url url to be launched */ -void ro_gui_window_launch_url(struct gui_window *g, const char *url) +void ro_gui_window_launch_url(struct gui_window *g, const char *url1) { - char *url2; + char *url2; /** @todo The risc os maintainer needs to examine why the url is copied here */ + nsurl *url; + nserror error; ro_gui_url_complete_close(); - url2 = strdup(url); + url2 = strdup(url1); if (url2 != NULL) { + gui_window_set_url(g, url2); - browser_window_go(g->bw, url2, 0, true); + + error = nsurl_create(url2, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(g->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + free(url2); } } @@ -3885,7 +3918,14 @@ bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) } if (nsurl_compare(current, parent, NSURL_COMPLETE) == false) { - browser_window_go(g->bw, nsurl_access(parent), 0, true); + browser_window_navigate(g->bw, + parent, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); } nsurl_unref(current); @@ -3902,14 +3942,32 @@ bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) void ro_gui_window_action_home(struct gui_window *g) { + static const char *addr = NETSURF_HOMEPAGE; + nsurl *url; + nserror error; + if (g == NULL || g->bw == NULL) return; - if ((nsoption_charp(homepage_url)) && (nsoption_charp(homepage_url)[0])) { - browser_window_go(g->bw, nsoption_charp(homepage_url), 0, true); - } else { - browser_window_go(g->bw, NETSURF_HOMEPAGE, 0, true); + if (nsoption_charp(homepage_url) != NULL) { + addr = nsoption_charp(homepage_url); } + + error = nsurl_create(addr, &url); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(g->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } diff --git a/utils/errors.h b/utils/errors.h index 7fcb5bd09..244de0a6b 100644 --- a/utils/errors.h +++ b/utils/errors.h @@ -65,7 +65,9 @@ typedef enum { NSERROR_CSS_BASE, /**< CSS base sheet failed */ - NSERROR_BAD_URL /**< Bad URL */ + NSERROR_BAD_URL, /**< Bad URL */ + + NSERROR_FRAME_DEPTH /**< Exceeded frame depth */ } nserror; #endif diff --git a/windows/gui.c b/windows/gui.c index e2f8f9afa..6e65816c8 100644 --- a/windows/gui.c +++ b/windows/gui.c @@ -114,15 +114,28 @@ void gui_poll(bool active) bool -nsws_window_go(HWND hwnd, const char *url) +nsws_window_go(HWND hwnd, const char *urltxt) { - struct gui_window * gw; + struct gui_window *gw; + nsurl *url; gw = nsws_get_gui_window(hwnd); if (gw == NULL) return false; - browser_window_go(gw->bw, url, 0, true); + if (nsurl_create(urltxt, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gw->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } return true; } @@ -833,8 +846,24 @@ nsws_window_command(HWND hwnd, break; case IDM_NAV_HOME: - browser_window_go(gw->bw, nsoption_charp(homepage_url), 0, true); + { + nsurl *url; + + if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gw->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } break; + } case IDM_NAV_STOP: browser_window_stop(gw->bw); @@ -979,13 +1008,30 @@ nsws_window_command(HWND hwnd, case IDC_MAIN_LAUNCH_URL: { + nsurl *url; + if (GetFocus() != gw->urlbar) break; + int len = SendMessage(gw->urlbar, WM_GETTEXTLENGTH, 0, 0); char addr[len + 1]; SendMessage(gw->urlbar, WM_GETTEXT, (WPARAM)(len + 1), (LPARAM)addr); LOG(("launching %s\n", addr)); - browser_window_go(gw->bw, addr, 0, true); + + if (nsurl_create(addr, &url) != NSERROR_OK) { + warn_user("NoMemory", 0); + } else { + browser_window_navigate(gw->bw, + url, + NULL, + BROWSER_WINDOW_GO_FLAG_HISTORY | + BROWSER_WINDOW_GO_FLAG_VERIFIABLE, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; }