From a38a63a37ef8bdc62661d398fb485296c0bed470 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 15 Feb 2014 18:43:59 +0000 Subject: Make history internal to browser_window module. --- amiga/context_menu.c | 11 +- amiga/gui.c | 6 +- amiga/history_local.c | 16 +- amiga/menu.c | 1 - atari/download.c | 1 - atari/gui.c | 1 - atari/rootwin.c | 1 - atari/statusbar.c | 1 - atari/toolbar.c | 10 +- beos/scaffolding.cpp | 14 +- cocoa/BrowserView.m | 1 - cocoa/BrowserViewController.m | 24 +- cocoa/HistoryView.m | 17 +- cocoa/NetsurfApp.m | 1 - desktop/Makefile | 2 +- desktop/browser.c | 28 +- desktop/browser_history.c | 915 ++++++++++++++++++++++++++++++++++++++++++ desktop/browser_history.h | 141 +++++++ desktop/browser_private.h | 2 +- desktop/frames.c | 1 - desktop/local_history.c | 855 --------------------------------------- desktop/local_history.h | 133 ------ framebuffer/gui.c | 11 +- framebuffer/localhistory.c | 7 +- gtk/scaffolding.c | 36 +- riscos/gui.h | 3 +- riscos/history.c | 25 +- riscos/menus.c | 1 - riscos/window.c | 34 +- windows/gui.c | 14 +- windows/localhistory.c | 17 +- 31 files changed, 1192 insertions(+), 1138 deletions(-) create mode 100644 desktop/browser_history.c create mode 100644 desktop/browser_history.h delete mode 100644 desktop/local_history.c delete mode 100644 desktop/local_history.h diff --git a/amiga/context_menu.c b/amiga/context_menu.c index c7e438fd9..aec89c6e3 100644 --- a/amiga/context_menu.c +++ b/amiga/context_menu.c @@ -39,8 +39,8 @@ #include "amiga/theme.h" #include "amiga/tree.h" #include "amiga/utf8.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" -#include "desktop/local_history.h" #include "desktop/hotlist.h" #include "desktop/searchweb.h" #include "desktop/textinput.h" @@ -607,7 +607,7 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y) gwin->win->MouseX, gwin->win->MouseY)) { gwin->temp = 0; - history_enumerate_back(gwin->bw->history, ami_context_menu_history, gwin); + browser_window_history_enumerate_back(gwin->bw, ami_context_menu_history, gwin); IDoMethod(ctxmenuobj, PM_INSERT, NewObject(POPUPMENU_GetItemClass(), NULL, @@ -630,7 +630,7 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y) gwin->win->MouseX, gwin->win->MouseY)) { gwin->temp = 0; - history_enumerate_forward(gwin->bw->history, ami_context_menu_history, gwin); + browser_window_history_enumerate_forward(gwin->bw, ami_context_menu_history, gwin); IDoMethod(ctxmenuobj, PM_INSERT, NewObject(POPUPMENU_GetItemClass(), NULL, @@ -1247,8 +1247,9 @@ static uint32 ami_context_menu_hook_tree(struct Hook *hook, Object *item, APTR r return itemid; } -static bool ami_context_menu_history(const struct history *history, int x0, int y0, - int x1, int y1, const struct history_entry *entry, void *user_data) +static bool ami_context_menu_history(const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data) { struct gui_window_2 *gwin = (struct gui_window_2 *)user_data; diff --git a/amiga/gui.c b/amiga/gui.c index a9491502e..aedb26c56 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -19,9 +19,9 @@ /* NetSurf core includes */ #include "content/urldb.h" #include "css/utils.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" #include "desktop/hotlist.h" -#include "desktop/local_history.h" #include "desktop/mouse.h" #include "desktop/netsurf.h" #include "utils/nsoption.h" @@ -1065,12 +1065,12 @@ void ami_gui_history(struct gui_window_2 *gwin, bool back) if(back == true) { if(browser_window_back_available(gwin->bw)) - history_back(gwin->bw->history, false); + browser_window_history_back(gwin->bw, false); } else { if(browser_window_forward_available(gwin->bw)) - history_forward(gwin->bw->history, false); + browser_window_history_forward(gwin->bw, false); } ami_update_buttons(gwin); diff --git a/amiga/history_local.c b/amiga/history_local.c index 3eda8874b..56d701d78 100755 --- a/amiga/history_local.c +++ b/amiga/history_local.c @@ -25,8 +25,8 @@ #include #include #include +#include "desktop/browser_history.h" #include "desktop/browser_private.h" -#include "desktop/local_history.h" #include "desktop/plotters.h" #include "amiga/os3support.h" #include "amiga/object.h" @@ -52,7 +52,7 @@ #include #include -static struct history *history_current = 0; +static struct browser_window *history_bw; /* Last position of mouse in window. */ static int mouse_x = 0; /* Last position of mouse in window. */ @@ -78,7 +78,7 @@ void ami_history_open(struct browser_window *bw, struct history *history) assert(history); - history_current = history; + history_bw = bw; if(!hwindow) { @@ -87,7 +87,7 @@ void ami_history_open(struct browser_window *bw, struct history *history) ami_init_layers(&hwindow->gg, scrn->Width, scrn->Height); hwindow->bw = bw; - history_size(history, &width, &height); + browser_window_history_size(bw, &width, &height); hwindow->scrollerhook.h_Entry = (void *)ami_history_scroller_hook; hwindow->scrollerhook.h_Data = hwindow; @@ -173,7 +173,7 @@ void ami_history_redraw(struct history_window *hw) SetRPAttrs(glob->rp, RPTAG_APenColor, 0xffffffff, TAG_DONE); RectFill(glob->rp, 0, 0, bbox->Width - 1, bbox->Height - 1); - history_redraw_rectangle(history_current, xs, ys, + browser_window_history_redraw_rectangle(history_bw, xs, ys, bbox->Width + xs, bbox->Height + ys, 0, 0, &ctx); glob = &browserglob; @@ -210,13 +210,13 @@ bool ami_history_click(struct history_window *hw,uint16 code) switch(code) { case SELECTUP: - history_click(history_current,x,y,false); + browser_window_history_click(history_bw,x,y,false); ami_history_redraw(hw); ami_schedule_redraw(hw->bw->window->shared, true); break; case MIDDLEUP: - history_click(history_current,x,y,true); + browser_window_history_click(history_bw,x,y,true); ami_history_redraw(hw); break; @@ -265,7 +265,7 @@ BOOL ami_history_event(struct history_window *hw) GetAttr(SCROLLER_Top, hw->objects[OID_HSCROLL], (ULONG *)&xs); GetAttr(SCROLLER_Top, hw->objects[OID_VSCROLL], (ULONG *)&ys); - url = history_position_url(history_current, + url = browser_window_history_position_url(history_bw, hw->win->MouseX - bbox->Left + xs, hw->win->MouseY - bbox->Top + ys); diff --git a/amiga/menu.c b/amiga/menu.c index 014f21c25..2c019bd9e 100644 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -61,7 +61,6 @@ #include "desktop/hotlist.h" #include "desktop/browser_private.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/textinput.h" #include "utils/messages.h" #include "utils/schedule.h" diff --git a/atari/download.c b/atari/download.c index 8d4786e23..dc4b7278a 100755 --- a/atari/download.c +++ b/atari/download.c @@ -28,7 +28,6 @@ #include "content/urldb.h" #include "content/fetch.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/netsurf.h" #include "utils/nsoption.h" #include "desktop/save_complete.h" diff --git a/atari/gui.c b/atari/gui.c index fe927e2bd..df029739f 100644 --- a/atari/gui.c +++ b/atari/gui.c @@ -41,7 +41,6 @@ #include "content/fetchers/resource.h" #include "css/utils.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/plotters.h" #include "desktop/netsurf.h" #include "desktop/save_complete.h" diff --git a/atari/rootwin.c b/atari/rootwin.c index 5fc290529..b215d41b3 100755 --- a/atari/rootwin.c +++ b/atari/rootwin.c @@ -38,7 +38,6 @@ #include "utils/log.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/netsurf.h" #include "desktop/browser.h" #include "desktop/browser_private.h" diff --git a/atari/statusbar.c b/atari/statusbar.c index 3bf186c02..bdd4ec158 100755 --- a/atari/statusbar.c +++ b/atari/statusbar.c @@ -29,7 +29,6 @@ #include "utils/log.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/netsurf.h" #include "desktop/browser.h" #include "desktop/mouse.h" diff --git a/atari/toolbar.c b/atari/toolbar.c index aa6aa9167..5a8468114 100644 --- a/atari/toolbar.c +++ b/atari/toolbar.c @@ -29,9 +29,9 @@ #include "utils/log.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/netsurf.h" #include "desktop/browser.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" #include "desktop/mouse.h" #include "desktop/plot_style.h" @@ -947,8 +947,8 @@ void toolbar_back_click(struct s_toolbar *tb) bw = gw->browser->bw; assert(bw != NULL); - if( history_back_available(bw->history) ) - history_back(bw->history, false); + if( browser_window_back_available(bw) ) + browser_window_history_back(bw, false); } void toolbar_reload_click(struct s_toolbar *tb) @@ -974,8 +974,8 @@ void toolbar_forward_click(struct s_toolbar *tb) bw = gw->browser->bw; assert(bw != NULL); - if (history_forward_available(bw->history)) - history_forward(bw->history, false); + if (browser_window_forward_available(bw)) + browser_window_history_forward(bw, false); } void toolbar_home_click(struct s_toolbar *tb) diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index 628debc51..f2ede2529 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -52,8 +52,8 @@ #include extern "C" { #include "content/content.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" -#include "desktop/local_history.h" #include "desktop/gui.h" #include "desktop/netsurf.h" #include "desktop/plotters.h" @@ -973,17 +973,17 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m case B_NETPOSITIVE_BACK: case BROWSER_NAVIGATE_BACK: case 'back': - if (!history_back_available(bw->history)) + if (!browser_window_history_back_available(bw)) break; - history_back(bw->history, false); + browser_window_history_back(bw, false); nsbeos_window_update_back_forward(scaffold); break; case B_NETPOSITIVE_FORWARD: case BROWSER_NAVIGATE_FORWARD: case 'forw': - if (!history_forward_available(bw->history)) + if (!browser_window_history_forward_available(bw)) break; - history_forward(bw->history, false); + browser_window_history_forward(bw->history, false); nsbeos_window_update_back_forward(scaffold); break; case B_NETPOSITIVE_STOP: @@ -1300,8 +1300,8 @@ void nsbeos_window_update_back_forward(struct beos_scaffolding *g) if (!g->top_view->LockLooper()) return; - g->back_button->SetEnabled(history_back_available(bw->history)); - g->forward_button->SetEnabled(history_forward_available(bw->history)); + g->back_button->SetEnabled(browser_window_history_back_available(bw)); + g->forward_button->SetEnabled(browser_window_history_forward_available(bw)); g->top_view->UnlockLooper(); diff --git a/cocoa/BrowserView.m b/cocoa/BrowserView.m index 092c1bfd0..b0042f760 100644 --- a/cocoa/BrowserView.m +++ b/cocoa/BrowserView.m @@ -24,7 +24,6 @@ #import "cocoa/BrowserWindowController.h" #import "desktop/browser_private.h" -#import "desktop/local_history.h" #import "desktop/plotters.h" #import "desktop/textinput.h" #import "utils/nsoption.h" diff --git a/cocoa/BrowserViewController.m b/cocoa/BrowserViewController.m index 4870446b6..b4e436063 100644 --- a/cocoa/BrowserViewController.m +++ b/cocoa/BrowserViewController.m @@ -21,8 +21,8 @@ #import "cocoa/BrowserWindowController.h" #import "cocoa/fetch.h" +#import "desktop/browser_history.h" #import "desktop/browser_private.h" -#import "desktop/local_history.h" #import "desktop/textinput.h" #import "utils/nsoption.h" @@ -116,16 +116,16 @@ - (IBAction) goBack: (id) sender; { - if (browser && history_back_available( browser->history )) { - history_back(browser->history, false); + if (browser && browser_window_history_back_available( browser )) { + browser_window_history_back(browser, false); [self updateBackForward]; } } - (IBAction) goForward: (id) sender; { - if (browser && history_forward_available( browser->history )) { - history_forward(browser->history, false); + if (browser && browser_window_history_forward_available( browser )) { + browser_window_history_forward(browser, false); [self updateBackForward]; } } @@ -272,8 +272,8 @@ static inline bool compare_float( float a, float b ) - (void) updateBackForward; { [browserView updateHistory]; - [self setCanGoBack: browser != NULL && history_back_available( browser->history )]; - [self setCanGoForward: browser != NULL && history_forward_available( browser->history )]; + [self setCanGoBack: browser != NULL && browser_window_history_back_available( browser )]; + [self setCanGoForward: browser != NULL && browser_window_history_forward_available( browser )]; } - (void) contentUpdated; @@ -287,7 +287,7 @@ struct history_add_menu_item_data { id target; }; -static bool history_add_menu_item_cb( const struct history *history, int x0, int y0, int x1, int y1, +static bool history_add_menu_item_cb( const struct browser_window *bw, int x0, int y0, int x1, int y1, const struct history_entry *page, void *user_data ) { struct history_add_menu_item_data *data = user_data; @@ -305,7 +305,7 @@ static bool history_add_menu_item_cb( const struct history *history, int x0, int ++data->index; [item setTarget: data->target]; - [item setTitle: [NSString stringWithUTF8String: history_entry_get_title( page )]]; + [item setTitle: [NSString stringWithUTF8String: browser_window_history_entry_get_title( page )]]; [item setRepresentedObject: [NSValue valueWithPointer: page]]; return true; @@ -314,7 +314,7 @@ static bool history_add_menu_item_cb( const struct history *history, int x0, int - (IBAction) historyItemSelected: (id) sender; { struct history_entry *entry = [[sender representedObject] pointerValue]; - history_go( browser->history, entry, false ); + browser_window_history_go( browser, entry, false ); [self updateBackForward]; } @@ -325,7 +325,7 @@ static bool history_add_menu_item_cb( const struct history *history, int x0, int .menu = menu, .target = self }; - history_enumerate_back( browser->history, history_add_menu_item_cb, &data ); + browser_window_history_enumerate_back( browser, history_add_menu_item_cb, &data ); while (data.index < [menu numberOfItems]) [menu removeItemAtIndex: data.index]; } @@ -336,7 +336,7 @@ static bool history_add_menu_item_cb( const struct history *history, int x0, int .menu = menu, .target = self }; - history_enumerate_forward( browser->history, history_add_menu_item_cb, &data ); + browser_window_history_enumerate_forward( browser, history_add_menu_item_cb, &data ); while (data.index < [menu numberOfItems]) [menu removeItemAtIndex: data.index]; } diff --git a/cocoa/HistoryView.m b/cocoa/HistoryView.m index c7181650b..7b192336e 100644 --- a/cocoa/HistoryView.m +++ b/cocoa/HistoryView.m @@ -23,8 +23,7 @@ #import "cocoa/LocalHistoryController.h" #import "cocoa/BrowserView.h" -#import "desktop/browser_private.h" -#import "desktop/local_history.h" +#import "desktop/browser_history.h" #import "desktop/plotters.h" @implementation HistoryView @@ -41,7 +40,7 @@ - (NSSize) size; { int width, height; - history_size( browser->history, &width, &height ); + browser_window_history_size( browser, &width, &height ); return cocoa_size( width, height ); } @@ -65,14 +64,14 @@ cocoa_set_clip( rect ); - history_redraw( browser->history, &ctx ); + browser_window_history_redraw( browser, &ctx ); } - (void) mouseUp: (NSEvent *)theEvent; { const NSPoint location = [self convertPoint: [theEvent locationInWindow] fromView: nil]; const bool newWindow = [theEvent modifierFlags] & NSCommandKeyMask; - if (history_click( browser->history, + if (browser_window_history_click( browser, cocoa_pt_to_px( location.x ), cocoa_pt_to_px( location.y ), newWindow )) { [browserView setHistoryVisible: NO]; @@ -94,7 +93,7 @@ [[NSCursor arrowCursor] set]; } -static bool cursor_rects_cb( const struct history *history, int x0, int y0, int x1, int y1, +static bool cursor_rects_cb( const struct browser_window *bw, int x0, int y0, int x1, int y1, const struct history_entry *page, void *user_data ) { HistoryView *view = user_data; @@ -102,8 +101,8 @@ static bool cursor_rects_cb( const struct history *history, int x0, int y0, int NSRect rect = NSIntersectionRect( [view visibleRect], cocoa_rect( x0, y0, x1, y1 ) ); if (!NSIsEmptyRect( rect )) { - NSString *toolTip = [NSString stringWithFormat: @"%s\n%s", history_entry_get_title(page), - history_entry_get_url( page )]; + NSString *toolTip = [NSString stringWithFormat: @"%s\n%s", browser_window_history_entry_get_title(page), + browser_window_history_entry_get_url( page )]; [view addToolTipRect: rect owner: toolTip userData: nil]; NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: rect @@ -138,7 +137,7 @@ static bool cursor_rects_cb( const struct history *history, int x0, int y0, int [self removeTrackingArea: area]; } - history_enumerate( browser->history, cursor_rects_cb, self ); + browser_window_history_enumerate( browser, cursor_rects_cb, self ); [super updateTrackingAreas]; } diff --git a/cocoa/NetsurfApp.m b/cocoa/NetsurfApp.m index 88424220d..a1f1564ee 100644 --- a/cocoa/NetsurfApp.m +++ b/cocoa/NetsurfApp.m @@ -28,7 +28,6 @@ #import "content/urldb.h" #import "css/utils.h" #import "desktop/gui.h" -#import "desktop/local_history.h" #import "desktop/mouse.h" #import "desktop/netsurf.h" #import "utils/nsoption.h" diff --git a/desktop/Makefile b/desktop/Makefile index 0e2e460de..a914eb3e4 100644 --- a/desktop/Makefile +++ b/desktop/Makefile @@ -12,7 +12,7 @@ desktop/version.c: testament utils/testament.h # S_BROWSER are sources related to full browsers but are common # between RISC OS, GTK, BeOS and AmigaOS builds -S_BROWSER := browser.c download.c frames.c local_history.c netsurf.c \ +S_BROWSER := browser.c browser_history.c download.c frames.c netsurf.c \ save_complete.c save_text.c selection.c textinput.c gui_factory.c S_BROWSER := $(addprefix desktop/,$(S_BROWSER)) diff --git a/desktop/browser.c b/desktop/browser.c index ca60e9ec1..03c7a8e76 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -41,6 +41,7 @@ #include "content/fetch.h" #include "content/hlcache.h" #include "content/urldb.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" #include "desktop/download.h" #include "desktop/frames.h" @@ -48,7 +49,6 @@ #include "desktop/gui_factory.h" #include "desktop/hotlist.h" #include "desktop/knockout.h" -#include "desktop/local_history.h" #include "utils/nsoption.h" #include "desktop/scrollbar.h" #include "desktop/selection.h" @@ -778,18 +778,22 @@ nserror browser_window_create(enum browser_window_create_flags flags, * \param bw The window to initialise * \param existing The existing window if cloning, else NULL */ -void browser_window_initialise_common(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) { + nserror err; assert(bw); if (flags & BW_CREATE_CLONE) { assert(existing != NULL); - bw->history = history_clone(existing->history, bw); + err = browser_window_history_clone(existing, bw); } else { - bw->history = history_create(bw); + err = browser_window_history_create(bw); } + if (err != NSERROR_OK) + return err; + /* window characteristics */ bw->refresh_interval = -1; @@ -807,6 +811,8 @@ void browser_window_initialise_common(enum browser_window_create_flags flags, bw->status_text_len = 0; bw->status_match = 0; bw->status_miss = 0; + + return NSERROR_OK; } /** @@ -1288,7 +1294,7 @@ static nserror browser_window_callback(hlcache_handle *c, * after, we only leak the thumbnails when urldb does * not add the URL. */ - history_add(bw->history, c, bw->frag_id); + browser_window_history_add(bw, c, bw->frag_id); } /* frames */ @@ -1318,7 +1324,7 @@ static nserror browser_window_callback(hlcache_handle *c, browser_window_stop_throbber(bw); browser_window_update_favicon(c, bw, NULL); - history_update(bw->history, c); + browser_window_history_update(bw, c); hotlist_update_url(hlcache_handle_get_url(c)); if (bw->refresh_interval != -1) @@ -1689,7 +1695,7 @@ void browser_window_destroy_internal(struct browser_window *bw) if (bw->frag_id != NULL) lwc_string_unref(bw->frag_id); - history_destroy(bw->history); + browser_window_history_destroy(bw); free(bw->name); free(bw->status_text); @@ -1882,7 +1888,7 @@ nserror browser_window_navigate(struct browser_window *bw, } if ((flags & BW_NAVIGATE_HISTORY) != 0) { - history_add(bw->history, + browser_window_history_add(bw, bw->current_content, bw->frag_id); } @@ -3047,7 +3053,8 @@ void browser_window_page_drag_start(struct browser_window *bw, int x, int y) bool browser_window_back_available(struct browser_window *bw) { - return (bw && bw->history && history_back_available(bw->history)); + return (bw && bw->history && + browser_window_history_back_available(bw)); } @@ -3060,7 +3067,8 @@ bool browser_window_back_available(struct browser_window *bw) bool browser_window_forward_available(struct browser_window *bw) { - return (bw && bw->history && history_forward_available(bw->history)); + return (bw && bw->history && + browser_window_history_forward_available(bw)); } diff --git a/desktop/browser_history.c b/desktop/browser_history.c new file mode 100644 index 000000000..c52f01c1a --- /dev/null +++ b/desktop/browser_history.c @@ -0,0 +1,915 @@ +/* + * Copyright 2006 James Bursa + * Copyright 2005 Richard Wilson + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * Browser history tree (implementation). + */ + +#include +#include +#include +#include +#include + +#include "content/content.h" +#include "content/hlcache.h" +#include "content/urldb.h" +#include "css/css.h" +#include "desktop/browser_history.h" +#include "desktop/browser_private.h" +#include "desktop/plotters.h" +#include "desktop/thumbnail.h" +#include "image/bitmap.h" +#include "render/font.h" +#include "utils/log.h" +#include "utils/nsurl.h" +#include "utils/utils.h" + + +#define WIDTH 100 +#define HEIGHT 86 +#define RIGHT_MARGIN 50 +#define BOTTOM_MARGIN 30 + +struct history_page { + nsurl *url; /**< Page URL, never 0. */ + lwc_string *frag_id; /** Fragment identifier, or 0. */ + char *title; /**< Page title, never 0. */ +}; + +/** A node in the history tree. */ +struct history_entry { + struct history_page page; + struct history_entry *back; /**< Parent. */ + struct history_entry *next; /**< Next sibling. */ + struct history_entry *forward; /**< First child. */ + struct history_entry *forward_pref; /**< Child in direction of + current entry. */ + struct history_entry *forward_last; /**< Last child. */ + unsigned int children; /**< Number of children. */ + int x; /**< Position of node. */ + int y; /**< Position of node. */ + struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */ +}; + +/** History tree for a window. */ +struct history { + /** First page in tree (page that window opened with). */ + struct history_entry *start; + /** Current position in tree. */ + struct history_entry *current; + /** Width of layout. */ + int width; + /** Height of layout. */ + int height; +}; + + +/** + * Clone a history entry + * + * \param history opaque history structure, as returned by history_create() + * \param start entry to clone + * + * \return a cloned history entry, or 0 on error + */ + +static struct history_entry *browser_window_history__clone_entry( + struct history *history, + struct history_entry *entry) +{ + struct history_entry *child; + struct history_entry *new_child; + struct history_entry *prev = NULL; + struct history_entry *new_entry; + + assert(entry->page.url); + assert(entry->page.title); + + /* clone the entry */ + new_entry = malloc(sizeof *entry); + if (!new_entry) + return NULL; + + memcpy(new_entry, entry, sizeof *entry); + new_entry->page.url = nsurl_ref(entry->page.url); + if (entry->page.frag_id) + new_entry->page.frag_id = lwc_string_ref(entry->page.frag_id); + + new_entry->page.title = strdup(entry->page.title); + if (!new_entry->page.url || !new_entry->page.title || + ((entry->page.frag_id) && (!new_entry->page.frag_id))) { + nsurl_unref(new_entry->page.url); + if (new_entry->page.frag_id) + lwc_string_unref(new_entry->page.frag_id); + free(new_entry->page.title); + free(new_entry); + return NULL; + } + + /* update references */ + if (history->current == entry) + history->current = new_entry; + + /* recurse for all children */ + for (child = new_entry->forward; child; child = child->next) { + new_child = browser_window_history__clone_entry(history, child); + if (new_child) { + new_child->back = new_entry; + } else { + nsurl_unref(new_entry->page.url); + if (new_entry->page.frag_id) + lwc_string_unref(new_entry->page.frag_id); + free(new_entry->page.title); + free(new_entry); + return NULL; + } + if (prev) + prev->next = new_child; + if (new_entry->forward == child) + new_entry->forward = new_child; + if (new_entry->forward_pref == child) + new_entry->forward_pref = new_child; + if (new_entry->forward_last == child) + new_entry->forward_last = new_child; + prev = new_child; + } + return new_entry; +} + + +/** + * Free an entry in the tree recursively. + */ + +static void browser_window_history__free_entry(struct history_entry *entry) +{ + if (!entry) + return; + browser_window_history__free_entry(entry->forward); + browser_window_history__free_entry(entry->next); + nsurl_unref(entry->page.url); + if (entry->page.frag_id) + lwc_string_unref(entry->page.frag_id); + free(entry->page.title); + free(entry); +} + + +/** + * Recursively position a subtree. + * + * \param history history being laid out + * \param entry subtree to position + * \param x x position for entry + * \param y smallest available y + * \param shuffle shuffle layout + * \return greatest y used by subtree + */ + +static int browser_window_history__layout_subtree(struct history *history, + struct history_entry *entry, int x, int y, bool shuffle) +{ + struct history_entry *child; + int y1 = y; + + if (history->width < x + WIDTH) + history->width = x + WIDTH; + + if (!entry->forward) { + entry->x = x; + entry->y = y; + if (shuffle) { + entry->x = rand() % 600; + entry->y = rand() % 400; + } + return y + HEIGHT; + } + + /* layout child subtrees below each other */ + for (child = entry->forward; child; child = child->next) { + y1 = browser_window_history__layout_subtree(history, child, + x + WIDTH + RIGHT_MARGIN, y1, shuffle); + if (child->next) + y1 += BOTTOM_MARGIN; + } + + /* place ourselves in the middle */ + entry->x = x; + entry->y = (y + y1) / 2 - HEIGHT / 2; + if (shuffle) { + entry->x = rand() % 600; + entry->y = rand() % 400; + } + + return y1; +} + + +/** + * Compute node positions. + * + * \param history history to layout + * + * Each node's x and y are filled in. + */ + +static void browser_window_history__layout(struct history *history) +{ + time_t t = time(0); + struct tm *tp = localtime(&t); + bool shuffle = tp->tm_mon == 3 && tp->tm_mday == 1; + + if (!history) + return; + + history->width = 0; + if (history->start) + history->height = browser_window_history__layout_subtree( + history, history->start, + RIGHT_MARGIN / 2, BOTTOM_MARGIN / 2, + shuffle); + else + history->height = 0; + if (shuffle) { + history->width = 600 + WIDTH; + history->height = 400 + HEIGHT; + } + history->width += RIGHT_MARGIN / 2; + history->height += BOTTOM_MARGIN / 2; +} + +/** + * Recursively redraw a history_entry. + * + * \param history history containing the entry + * \param history_entry entry to render + * \param ctx current redraw context + */ + +static bool browser_window_history__redraw_entry(struct history *history, + struct history_entry *entry, + int x0, int y0, int x1, int y1, + int x, int y, bool clip, + const struct redraw_context *ctx) +{ + const struct plotter_table *plot = ctx->plot; + size_t char_offset; + int actual_x; + struct history_entry *child; + colour c = entry == history->current ? + HISTORY_COLOUR_SELECTED : HISTORY_COLOUR_FOREGROUND; + int tailsize = 5; + int xoffset = x - x0; + int yoffset = y - y0; + plot_style_t pstyle_history_rect = { + .stroke_type = PLOT_OP_TYPE_SOLID, + .stroke_colour = c, + .stroke_width = entry == history->current ? 3 : 1, + }; + plot_font_style_t fstyle = *plot_style_font; + + if (clip) { + struct rect rect; + rect.x0 = x0 + xoffset; + rect.y0 = y0 + yoffset; + rect.x1 = x1 + xoffset; + rect.y1 = y1 + yoffset; + if(!plot->clip(&rect)) + return false; + } + + if (!plot->bitmap(entry->x + xoffset, entry->y + yoffset, WIDTH, HEIGHT, + entry->bitmap, 0xffffff, 0)) + return false; + if (!plot->rectangle(entry->x - 1 + xoffset, + entry->y - 1 + yoffset, + entry->x + xoffset + WIDTH, + entry->y + yoffset + HEIGHT, + &pstyle_history_rect)) + return false; + + if (!nsfont.font_position_in_string(plot_style_font, entry->page.title, + strlen(entry->page.title), WIDTH, + &char_offset, &actual_x)) + return false; + + fstyle.background = HISTORY_COLOUR_BACKGROUND; + fstyle.foreground = c; + fstyle.weight = entry == history->current ? 900 : 400; + + if (!plot->text(entry->x + xoffset, entry->y + HEIGHT + 12 + yoffset, + entry->page.title, char_offset, &fstyle)) + return false; + + for (child = entry->forward; child; child = child->next) { + if (!plot->line(entry->x + WIDTH + xoffset, + entry->y + HEIGHT / 2 + yoffset, + entry->x + WIDTH + tailsize + xoffset, + entry->y + HEIGHT / 2 + yoffset, + plot_style_stroke_history)) + return false; + if (!plot->line(entry->x + WIDTH + tailsize + xoffset, + entry->y + HEIGHT / 2 + yoffset, + child->x - tailsize +xoffset, + child->y + HEIGHT / 2 + yoffset, + plot_style_stroke_history)) + return false; + if (!plot->line(child->x - tailsize + xoffset, + child->y + HEIGHT / 2 + yoffset, + child->x + xoffset, child->y + + HEIGHT / 2 + yoffset, + plot_style_stroke_history)) + return false; + if (!browser_window_history__redraw_entry(history, child, + x0, y0, x1, y1, x, y, clip, ctx)) + return false; + } + + return true; +} + + +/** + * Find the history entry at a position. + * + * \param entry entry to search from + * \param x coordinate + * \param y coordinate + * \return an entry if found, 0 if none + */ + +static struct history_entry *browser_window_history__find_position( + struct history_entry *entry, int x, int y) +{ + struct history_entry *child; + struct history_entry *found; + + if (!entry) + return 0; + + if (entry->x <= x && x <= entry->x + WIDTH && + entry->y <= y && y <= entry->y + HEIGHT) + return entry; + + for (child = entry->forward; child; child = child->next) { + found = browser_window_history__find_position(child, x, y); + if (found) + return found; + } + + return 0; +} + +/** + * Enumerate subentries in history + * See also history_enumerate() + * + * \param bw The browser window to enumerate history of + * \param entry entry to start enumeration at + * \param cb callback function + * \param ud context pointer passed to cb + * \return true to continue enumeration, false to cancel + */ +static bool browser_window_history__enumerate_entry( + const struct browser_window *bw, + const struct history_entry *entry, + browser_window_history_enumerate_cb cb, + void *ud) +{ + const struct history_entry *child; + + if (!cb(bw, entry->x, entry->y, + entry->x + WIDTH, entry->y + HEIGHT, + entry, ud)) + return false; + + for (child = entry->forward; child; child = child->next) { + if (!browser_window_history__enumerate_entry(bw, child, + cb, ud)) + return false; + } + + return true; +} + + +/* -------------------------------------------------------------------------- */ + + +/** + * Create a new history tree for a browser window window. + * + * \param bw browser window to create history for. + * + * \return NSERROR_OK or appropriate error otherwise + */ + +nserror browser_window_history_create(struct browser_window *bw) +{ + struct history *history; + + bw->history = NULL; + + history = calloc(1, sizeof *history); + if (!history) { + warn_user("NoMemory", 0); + return NSERROR_NOMEM; + } + history->width = RIGHT_MARGIN / 2; + history->height = BOTTOM_MARGIN / 2; + + bw->history = history; + return NSERROR_OK; +} + + +/** + * Clone a bw's history tree for new bw + * + * \param bw browser window with history to clone. + * \param new browser window to make cloned history for. + * + * \return NSERROR_OK or appropriate error otherwise + */ + +nserror browser_window_history_clone(const struct browser_window *bw, + struct browser_window *new) +{ + struct history *new_history; + + new->history = NULL; + + if (bw == NULL || bw->history == NULL || bw->history->start == NULL) + return browser_window_history_create(new); + + new_history = malloc(sizeof *new_history); + if (!new_history) + return NSERROR_NOMEM; + + new->history = new_history; + memcpy(new_history, bw->history, sizeof *new_history); + + new_history->start = browser_window_history__clone_entry(new_history, + new_history->start); + if (!new_history->start) { + LOG(("Insufficient memory to clone history")); + warn_user("NoMemory", 0); + browser_window_history_destroy(new); + new->history = NULL; + return NSERROR_NOMEM; + } + + return NSERROR_OK; +} + + +/** + * Insert a url into the history tree. + * + * \param bw browser window with history object + * \param content content to add to history + * \param frag_id fragment identifier, or NULL. + * + * The page is added after the current entry and becomes current. + */ + + +void browser_window_history_add(struct browser_window *bw, + struct hlcache_handle *content, lwc_string *frag_id) +{ + struct history *history; + struct history_entry *entry; + nsurl *nsurl = hlcache_handle_get_url(content); + char *title; + struct bitmap *bitmap; + + assert(bw); + assert(bw->history); + assert(content); + + history = bw->history; + + /* allocate space */ + entry = malloc(sizeof *entry); + if (entry == NULL) + return; + + title = strdup(content_get_title(content)); + if (title == NULL) { + warn_user("NoMemory", 0); + free(entry); + return; + } + + entry->page.url = nsurl_ref(nsurl); + entry->page.frag_id = frag_id ? lwc_string_ref(frag_id) : 0; + + entry->page.title = title; + entry->back = history->current; + entry->next = 0; + entry->forward = entry->forward_pref = entry->forward_last = 0; + entry->children = 0; + entry->bitmap = 0; + if (history->current) { + if (history->current->forward_last) + history->current->forward_last->next = entry; + else + history->current->forward = entry; + history->current->forward_pref = entry; + history->current->forward_last = entry; + history->current->children++; + } else { + history->start = entry; + } + history->current = entry; + + /* if we have a thumbnail, don't update until the page has finished + * loading */ + bitmap = urldb_get_thumbnail(nsurl); + if (!bitmap) { + LOG(("Creating thumbnail for %s", nsurl_access(nsurl))); + bitmap = bitmap_create(WIDTH, HEIGHT, + BITMAP_NEW | BITMAP_CLEAR_MEMORY | + BITMAP_OPAQUE); + if (!bitmap) { + warn_user("NoMemory", 0); + return; + } + if (thumbnail_create(content, bitmap, nsurl) == false) { + /* Thumbnailing failed. Ignore it silently */ + bitmap_destroy(bitmap); + bitmap = NULL; + } + } + entry->bitmap = bitmap; + + browser_window_history__layout(history); +} + + +/** + * Update the thumbnail for the current entry. + * + * \param history opaque history structure, as returned by history_create() + * \param content content for current entry + */ + +void browser_window_history_update(struct browser_window *bw, + struct hlcache_handle *content) +{ + struct history *history; + char *title; + + assert(bw != NULL); + + history = bw->history; + + if (!history || !history->current || !history->current->bitmap) + return; + + assert(history->current->page.url); + assert(history->current->page.title); + + title = strdup(content_get_title(content)); + if (!title) { + warn_user("NoMemory", 0); + return; + } + + assert(title); + free(history->current->page.title); + history->current->page.title = title; + + thumbnail_create(content, history->current->bitmap, NULL); +} + + +/** + * Free a history structure. + * + * \param history opaque history structure, as returned by history_create() + */ + +void browser_window_history_destroy(struct browser_window *bw) +{ + assert(bw != NULL); + + if (bw->history == NULL) + return; + + browser_window_history__free_entry(bw->history->start); + free(bw->history); + + bw->history = NULL; +} + + +/** + * Go back in the history. + * + * \param bw browser window + * \param history history of the window + * \param new_window whether to open in new window + */ + +void browser_window_history_back(struct browser_window *bw, bool new_window) +{ + if (!bw || !bw->history || !bw->history->current || + !bw->history->current->back) + return; + browser_window_history_go(bw, bw->history->current->back, new_window); +} + + +/** + * Go forward in the history. + * + * \param bw browser window + * \param history history of the window + * \param new_window whether to open in new window + */ + +void browser_window_history_forward(struct browser_window *bw, bool new_window) +{ + if (!bw || !bw->history || !bw->history->current || + !bw->history->current->forward_pref) + return; + browser_window_history_go(bw, bw->history->current->forward_pref, + new_window); +} + + +/** + * Check whether it is pssible to go back in the history. + * + * \param history history of the window + * \return true if the history can go back, false otherwise + */ + +bool browser_window_history_back_available(struct browser_window *bw) +{ + return (bw && bw->history && bw->history->current && + bw->history->current->back); +} + + +/** + * Check whether it is pssible to go forwards in the history. + * + * \param history history of the window + * \return true if the history can go forwards, false otherwise + */ + +bool browser_window_history_forward_available(struct browser_window *bw) +{ + return (bw && bw->history && bw->history->current && + bw->history->current->forward_pref); +} + + +/* Documented in local_history.h */ +void browser_window_history_go(struct browser_window *bw, + struct history_entry *entry, bool new_window) +{ + struct history *history; + nsurl *url; + struct history_entry *current; + nserror error; + + assert(bw != NULL); + history = bw->history; + + if (entry->page.frag_id) { + error = nsurl_refragment(entry->page.url, + entry->page.frag_id, &url); + + if (error != NSERROR_OK) { + warn_user("NoMemory", 0); + return; + } + } else { + url = nsurl_ref(entry->page.url); + } + + if (new_window) { + current = history->current; + history->current = entry; + + browser_window_create(BW_CREATE_CLONE, + url, NULL, bw, NULL); + history->current = current; + } else { + history->current = entry; + browser_window_navigate(bw, url, NULL, + BW_NAVIGATE_NONE, NULL, NULL, NULL); + } + + nsurl_unref(url); +} + + +/** + * Get the dimensions of a history. + * + * \param history history to measure + * \param width updated to width + * \param height updated to height + */ + +void browser_window_history_size(struct browser_window *bw, + int *width, int *height) +{ + assert(bw != NULL); + assert(bw->history != NULL); + + *width = bw->history->width; + *height = bw->history->height; +} + + +/** + * Redraw a history. + * + * \param history history to render + * \param ctx current redraw context + */ + +bool browser_window_history_redraw(struct browser_window *bw, + const struct redraw_context *ctx) +{ + struct history *history; + + assert(bw != NULL); + history = bw->history; + + if (!history->start) + return true; + return browser_window_history__redraw_entry(history, history->start, + 0, 0, 0, 0, 0, 0, false, ctx); +} + +/** + * Redraw part of a history. + * + * \param history history to render + * \param x0 left X co-ordinate of redraw area + * \param y0 top Y co-ordinate of redraw area + * \param x1 right X co-ordinate of redraw area + * \param y1 lower Y co-ordinate of redraw area + * \param x start X co-ordinate on plot canvas + * \param y start Y co-ordinate on plot canvas + * \param ctx current redraw context + */ + +bool browser_window_history_redraw_rectangle(struct browser_window *bw, + int x0, int y0, int x1, int y1, + int x, int y, const struct redraw_context *ctx) +{ + struct history *history; + + assert(bw != NULL); + history = bw->history; + + if (!history->start) + return true; + return browser_window_history__redraw_entry(history, history->start, + x0, y0, x1, y1, x, y, true, ctx); +} + + +/** + * Handle a mouse click in a history. + * + * \param bw browser window containing history + * \param x click coordinate + * \param y click coordinate + * \param new_window open a new window instead of using bw + * \return true if action was taken, false if click was not on an entry + */ + +bool browser_window_history_click(struct browser_window *bw, + int x, int y, bool new_window) +{ + struct history_entry *entry; + struct history *history; + + assert(bw != NULL); + history = bw->history; + + entry = browser_window_history__find_position(history->start, x, y); + if (!entry) + return false; + if (entry == history->current) + return false; + + browser_window_history_go(bw, entry, new_window); + + return true; +} + + +/** + * Determine the URL of the entry at a position. + * + * \param history history to search + * \param x coordinate + * \param y coordinate + * \return URL, or 0 if no entry at (x, y) + */ + +const char *browser_window_history_position_url(struct browser_window *bw, + int x, int y) +{ + struct history_entry *entry; + struct history *history; + + assert(bw != NULL); + history = bw->history; + + entry = browser_window_history__find_position(history->start, x, y); + if (!entry) + return 0; + + return nsurl_access(entry->page.url); +} + +/* Documented in local_history.h */ +void browser_window_history_enumerate_forward(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data) +{ + struct history_entry *e; + + if (bw == NULL || bw->history == NULL || bw->history->current == NULL) + return; + + e = bw->history->current->forward_pref; + for (; e != NULL; e = e->forward_pref) { + if (!cb(bw, e->x, e->y, e->x + WIDTH, e->y + HEIGHT, + e, user_data)) + break; + } +} + +/* Documented in local_history.h */ +void browser_window_history_enumerate_back(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data) +{ + struct history_entry *e; + + if (bw == NULL || bw->history == NULL || bw->history->current == NULL) + return; + + for (e = bw->history->current->back; e != NULL; e = e->back) { + if (!cb(bw, e->x, e->y, e->x + WIDTH, e->y + HEIGHT, + e, user_data)) + break; + } +} + +/* Documented in local_history.h */ +void browser_window_history_enumerate(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data) +{ + if (bw == NULL || bw->history == NULL) + return; + browser_window_history__enumerate_entry(bw, + bw->history->start, cb, user_data); +} + +/* Documented in local_history.h */ +const char *browser_window_history_entry_get_url( + const struct history_entry *entry) +{ + return nsurl_access(entry->page.url); +} + +/* Documented in local_history.h */ +const char *browser_window_history_entry_get_fragment_id( + const struct history_entry *entry) +{ + return (entry->page.frag_id) ? lwc_string_data(entry->page.frag_id) : 0; +} + +/* Documented in local_history.h */ +const char *browser_window_history_entry_get_title( + const struct history_entry *entry) +{ + return entry->page.title; +} diff --git a/desktop/browser_history.h b/desktop/browser_history.h new file mode 100644 index 000000000..11b58e4dd --- /dev/null +++ b/desktop/browser_history.h @@ -0,0 +1,141 @@ +/* + * Copyright 2006 James Bursa + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * Browser history tree (interface). + */ + +#ifndef _NETSURF_DESKTOP_BROWSER_HISTORY_H_ +#define _NETSURF_DESKTOP_BROWSER_HISTORY_H_ + +#include +#include + +#include "utils/errors.h" + +struct hlcache_handle; +struct browser_window; +struct history_entry; +struct redraw_context; + +nserror browser_window_history_create(struct browser_window *bw); +nserror browser_window_history_clone(const struct browser_window *bw, + struct browser_window *new); +void browser_window_history_add(struct browser_window *bw, + struct hlcache_handle *content, lwc_string *frag_id); +void browser_window_history_update(struct browser_window *bw, + struct hlcache_handle *content); +void browser_window_history_destroy(struct browser_window *bw); +void browser_window_history_back(struct browser_window *bw, bool new_window); +void browser_window_history_forward(struct browser_window *bw, bool new_window); +bool browser_window_history_back_available(struct browser_window *bw); +bool browser_window_history_forward_available(struct browser_window *bw); +void browser_window_history_size(struct browser_window *bw, + int *width, int *height); +bool browser_window_history_redraw(struct browser_window *bw, + const struct redraw_context *ctx); +bool browser_window_history_redraw_rectangle(struct browser_window *bw, + int x0, int y0, int x1, int y1, int x, int y, + const struct redraw_context *ctx); +bool browser_window_history_click(struct browser_window *bw, + int x, int y, bool new_window); +const char *browser_window_history_position_url(struct browser_window *bw, + int x, int y); + +/** + * Callback function type for history enumeration + * + * \param bw The browser window with history being enumerated + * \param x0, y0, x1, y1 Coordinates of entry in history tree view + * \param entry Current history entry + * \return true to continue enumeration, false to cancel enumeration + */ +typedef bool (*browser_window_history_enumerate_cb)( + const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data); + +/** + * Enumerate all entries in the history. + * Do not change the history while it is being enumerated. + * + * \param bw The browser window to enumerate history of + * \param cb callback function + * \param user_data context pointer passed to cb + */ +void browser_window_history_enumerate(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data); + +/** + * Enumerate all entries that will be reached by the 'forward' button + * + * \param bw The browser window to enumerate history of + * \param cb The callback function + * \param user_data Data passed to the callback + */ +void browser_window_history_enumerate_forward(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data); + +/** + * Enumerate all entries that will be reached by the 'back' button + * + * \param bw The browser window to enumerate history of + * \param cb The callback function + * \param user_data Data passed to the callback + */ +void browser_window_history_enumerate_back(const struct browser_window *bw, + browser_window_history_enumerate_cb cb, void *user_data); + +/** + * Returns the URL to a history entry + * + * \param entry the history entry to retrieve the URL from + * \return the URL + */ +const char *browser_window_history_entry_get_url( + const struct history_entry *entry); + +/** + * Returns the URL to a history entry + * + * \param entry the history entry to retrieve the fragment id from + * \return the fragment id + */ +const char *browser_window_history_entry_get_fragment_id( + const struct history_entry *entry); + +/** + * Returns the title of a history entry + * + * \param entry the history entry to retrieve the title from + * \return the title + */ +const char *browser_window_history_entry_get_title( + const struct history_entry *entry); + +/** + * Navigate to specified history entry, optionally in new window + * + * \param bw browser window + * \param entry entry to open + * \param new_window open entry in new window + */ +void browser_window_history_go(struct browser_window *bw, + struct history_entry *entry, bool new_window); + +#endif diff --git a/desktop/browser_private.h b/desktop/browser_private.h index 9007007a8..339bc46ee 100644 --- a/desktop/browser_private.h +++ b/desktop/browser_private.h @@ -165,7 +165,7 @@ struct browser_window { -void browser_window_initialise_common(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); /** diff --git a/desktop/frames.c b/desktop/frames.c index ab5f8171c..534cca4f7 100644 --- a/desktop/frames.c +++ b/desktop/frames.c @@ -33,7 +33,6 @@ #include "content/hlcache.h" #include "desktop/browser_private.h" #include "desktop/frames.h" -#include "desktop/local_history.h" #include "desktop/scrollbar.h" #include "desktop/selection.h" #include "utils/log.h" diff --git a/desktop/local_history.c b/desktop/local_history.c deleted file mode 100644 index 687d4c754..000000000 --- a/desktop/local_history.c +++ /dev/null @@ -1,855 +0,0 @@ -/* - * Copyright 2006 James Bursa - * Copyright 2005 Richard Wilson - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Browser history tree (implementation). - */ - -#include -#include -#include -#include -#include - -#include "content/content.h" -#include "content/hlcache.h" -#include "content/urldb.h" -#include "css/css.h" -#include "desktop/browser.h" -#include "desktop/local_history.h" -#include "desktop/plotters.h" -#include "desktop/thumbnail.h" -#include "image/bitmap.h" -#include "render/font.h" -#include "utils/log.h" -#include "utils/nsurl.h" -#include "utils/utils.h" - - -#define WIDTH 100 -#define HEIGHT 86 -#define RIGHT_MARGIN 50 -#define BOTTOM_MARGIN 30 - -struct history_page { - nsurl *url; /**< Page URL, never 0. */ - lwc_string *frag_id; /** Fragment identifier, or 0. */ - char *title; /**< Page title, never 0. */ -}; - -/** A node in the history tree. */ -struct history_entry { - struct history_page page; - struct history_entry *back; /**< Parent. */ - struct history_entry *next; /**< Next sibling. */ - struct history_entry *forward; /**< First child. */ - struct history_entry *forward_pref; /**< Child in direction of - current entry. */ - struct history_entry *forward_last; /**< Last child. */ - unsigned int children; /**< Number of children. */ - int x; /**< Position of node. */ - int y; /**< Position of node. */ - struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */ -}; - -/** History tree for a window. */ -struct history { - /** First page in tree (page that window opened with). */ - struct history_entry *start; - /** Current position in tree. */ - struct history_entry *current; - /** Width of layout. */ - int width; - /** Height of layout. */ - int height; - /** Browser window that local history belongs to */ - struct browser_window *bw; -}; - -static struct history_entry *history_clone_entry(struct history *history, - struct history_entry *entry); -static void history_free_entry(struct history_entry *entry); -static void history_layout(struct history *history); -static int history_layout_subtree(struct history *history, - struct history_entry *entry, int x, int y, bool shuffle); -static bool history_redraw_entry(struct history *history, - struct history_entry *entry, - int x0, int y0, int x1, int y1, - int x, int y, bool clip, const struct redraw_context *ctx); -static struct history_entry *history_find_position(struct history_entry *entry, - int x, int y); -static bool history_enumerate_entry(const struct history *history, - const struct history_entry *entry, history_enumerate_cb cb, void *ud); - - -/** - * Create a new history tree for a window. - * - * \return pointer to an opaque history structure, 0 on failure. - */ - -struct history *history_create(struct browser_window *bw) -{ - struct history *history; - - history = calloc(1, sizeof *history); - if (!history) { - warn_user("NoMemory", 0); - return 0; - } - history->width = RIGHT_MARGIN / 2; - history->height = BOTTOM_MARGIN / 2; - history->bw = bw; - return history; -} - - -/** - * Clone a history tree - * - * \param history opaque history structure, as returned by history_create() - * - * \return pointer to an opaque history structure, 0 on failure. - */ - -struct history *history_clone(struct history *history, - struct browser_window *bw) -{ - struct history *new_history; - - if (!history->start) - return history_create(bw); - - new_history = malloc(sizeof *history); - if (!new_history) - return 0; - memcpy(new_history, history, sizeof *history); - - new_history->start = history_clone_entry(new_history, - new_history->start); - if (!history->start) { - LOG(("Insufficient memory to clone history")); - warn_user("NoMemory", 0); - history_destroy(new_history); - return 0; - } - - new_history->bw = bw; - - return new_history; -} - - -/** - * Clone a history entry - * - * \param history opaque history structure, as returned by history_create() - * \param start entry to clone - * - * \return a cloned history entry, or 0 on error - */ - -struct history_entry *history_clone_entry(struct history *history, - struct history_entry *entry) -{ - struct history_entry *child; - struct history_entry *new_child; - struct history_entry *prev = NULL; - struct history_entry *new_entry; - - assert(entry->page.url); - assert(entry->page.title); - - /* clone the entry */ - new_entry = malloc(sizeof *entry); - if (!new_entry) - return NULL; - - memcpy(new_entry, entry, sizeof *entry); - new_entry->page.url = nsurl_ref(entry->page.url); - if (entry->page.frag_id) - new_entry->page.frag_id = lwc_string_ref(entry->page.frag_id); - - new_entry->page.title = strdup(entry->page.title); - if (!new_entry->page.url || !new_entry->page.title || - ((entry->page.frag_id) && (!new_entry->page.frag_id))) { - nsurl_unref(new_entry->page.url); - if (new_entry->page.frag_id) - lwc_string_unref(new_entry->page.frag_id); - free(new_entry->page.title); - free(new_entry); - return NULL; - } - - /* update references */ - if (history->current == entry) - history->current = new_entry; - - /* recurse for all children */ - for (child = new_entry->forward; child; child = child->next) { - new_child = history_clone_entry(history, child); - if (new_child) { - new_child->back = new_entry; - } else { - nsurl_unref(new_entry->page.url); - if (new_entry->page.frag_id) - lwc_string_unref(new_entry->page.frag_id); - free(new_entry->page.title); - free(new_entry); - return NULL; - } - if (prev) - prev->next = new_child; - if (new_entry->forward == child) - new_entry->forward = new_child; - if (new_entry->forward_pref == child) - new_entry->forward_pref = new_child; - if (new_entry->forward_last == child) - new_entry->forward_last = new_child; - prev = new_child; - } - return new_entry; -} - - -/** - * Insert a url into the history tree. - * - * \param history opaque history structure, as returned by history_create() - * \param content content to add to history - * \param frag_id fragment identifier, or NULL. - * - * The page is added after the current entry and becomes current. - */ - -void history_add(struct history *history, hlcache_handle *content, - lwc_string *frag_id) -{ - struct history_entry *entry; - nsurl *nsurl = hlcache_handle_get_url(content); - char *title; - struct bitmap *bitmap; - - assert(history); - assert(content); - - /* allocate space */ - entry = malloc(sizeof *entry); - if (entry == NULL) - return; - - title = strdup(content_get_title(content)); - if (title == NULL) { - warn_user("NoMemory", 0); - free(entry); - return; - } - - entry->page.url = nsurl_ref(nsurl); - entry->page.frag_id = frag_id ? lwc_string_ref(frag_id) : 0; - - entry->page.title = title; - entry->back = history->current; - entry->next = 0; - entry->forward = entry->forward_pref = entry->forward_last = 0; - entry->children = 0; - entry->bitmap = 0; - if (history->current) { - if (history->current->forward_last) - history->current->forward_last->next = entry; - else - history->current->forward = entry; - history->current->forward_pref = entry; - history->current->forward_last = entry; - history->current->children++; - } else { - history->start = entry; - } - history->current = entry; - - /* if we have a thumbnail, don't update until the page has finished - * loading */ - bitmap = urldb_get_thumbnail(nsurl); - if (!bitmap) { - LOG(("Creating thumbnail for %s", nsurl_access(nsurl))); - bitmap = bitmap_create(WIDTH, HEIGHT, - BITMAP_NEW | BITMAP_CLEAR_MEMORY | - BITMAP_OPAQUE); - if (!bitmap) { - warn_user("NoMemory", 0); - return; - } - if (thumbnail_create(content, bitmap, nsurl) == false) { - /* Thumbnailing failed. Ignore it silently */ - bitmap_destroy(bitmap); - bitmap = NULL; - } - } - entry->bitmap = bitmap; - - history_layout(history); -} - - -/** - * Update the thumbnail for the current entry. - * - * \param history opaque history structure, as returned by history_create() - * \param content content for current entry - */ - -void history_update(struct history *history, hlcache_handle *content) -{ - char *title; - - if (!history || !history->current || !history->current->bitmap) - return; - - assert(history->current->page.url); - assert(history->current->page.title); - - title = strdup(content_get_title(content)); - if (!title) { - warn_user("NoMemory", 0); - return; - } - - assert(title); - free(history->current->page.title); - history->current->page.title = title; - - thumbnail_create(content, history->current->bitmap, NULL); -} - - -/** - * Free a history structure. - * - * \param history opaque history structure, as returned by history_create() - */ - -void history_destroy(struct history *history) -{ - if (!history) - return; - history_free_entry(history->start); - free(history); -} - - -/** - * Free an entry in the tree recursively. - */ - -void history_free_entry(struct history_entry *entry) -{ - if (!entry) - return; - history_free_entry(entry->forward); - history_free_entry(entry->next); - nsurl_unref(entry->page.url); - if (entry->page.frag_id) - lwc_string_unref(entry->page.frag_id); - free(entry->page.title); - free(entry); -} - - -/** - * Go back in the history. - * - * \param bw browser window - * \param history history of the window - * \param new_window whether to open in new window - */ - -void history_back(struct history *history, bool new_window) -{ - if (!history || !history->current || !history->current->back) - return; - history_go(history, history->current->back, new_window); -} - - -/** - * Go forward in the history. - * - * \param bw browser window - * \param history history of the window - * \param new_window whether to open in new window - */ - -void history_forward(struct history *history, bool new_window) -{ - if (!history || !history->current || !history->current->forward_pref) - return; - history_go(history, history->current->forward_pref, new_window); -} - - -/** - * Check whether it is pssible to go back in the history. - * - * \param history history of the window - * \return true if the history can go back, false otherwise - */ - -bool history_back_available(struct history *history) -{ - return (history && history->current && history->current->back); -} - - -/** - * Check whether it is pssible to go forwards in the history. - * - * \param history history of the window - * \return true if the history can go forwards, false otherwise - */ - -bool history_forward_available(struct history *history) -{ - return (history && history->current && history->current->forward_pref); -} - - -/* Documented in local_history.h */ -void history_go(struct history *history, struct history_entry *entry, - bool new_window) -{ - 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) { - error = nsurl_refragment(entry->page.url, - entry->page.frag_id, &url); - - if (error != NSERROR_OK) { - warn_user("NoMemory", 0); - return; - } - } else { - url = nsurl_ref(entry->page.url); - } - - if (new_window) { - current = history->current; - history->current = entry; - - browser_window_create(BW_CREATE_CLONE, - url, NULL, history->bw, NULL); - history->current = current; - } else { - history->current = entry; - browser_window_navigate(history->bw, url, NULL, - BW_NAVIGATE_NONE, NULL, NULL, NULL); - } - - nsurl_unref(url); -} - - -/** - * Compute node positions. - * - * \param history history to layout - * - * Each node's x and y are filled in. - */ - -void history_layout(struct history *history) -{ - time_t t = time(0); - struct tm *tp = localtime(&t); - bool shuffle = tp->tm_mon == 3 && tp->tm_mday == 1; - - if (!history) - return; - - history->width = 0; - if (history->start) - history->height = history_layout_subtree(history, - history->start, RIGHT_MARGIN / 2, BOTTOM_MARGIN / 2, - shuffle); - else - history->height = 0; - if (shuffle) { - history->width = 600 + WIDTH; - history->height = 400 + HEIGHT; - } - history->width += RIGHT_MARGIN / 2; - history->height += BOTTOM_MARGIN / 2; -} - - -/** - * Recursively position a subtree. - * - * \param history history being laid out - * \param entry subtree to position - * \param x x position for entry - * \param y smallest available y - * \param shuffle shuffle layout - * \return greatest y used by subtree - */ - -int history_layout_subtree(struct history *history, - struct history_entry *entry, int x, int y, bool shuffle) -{ - struct history_entry *child; - int y1 = y; - - if (history->width < x + WIDTH) - history->width = x + WIDTH; - - if (!entry->forward) { - entry->x = x; - entry->y = y; - if (shuffle) { - entry->x = rand() % 600; - entry->y = rand() % 400; - } - return y + HEIGHT; - } - - /* layout child subtrees below each other */ - for (child = entry->forward; child; child = child->next) { - y1 = history_layout_subtree(history, child, - x + WIDTH + RIGHT_MARGIN, y1, shuffle); - if (child->next) - y1 += BOTTOM_MARGIN; - } - - /* place ourselves in the middle */ - entry->x = x; - entry->y = (y + y1) / 2 - HEIGHT / 2; - if (shuffle) { - entry->x = rand() % 600; - entry->y = rand() % 400; - } - - return y1; -} - - -/** - * Get the dimensions of a history. - * - * \param history history to measure - * \param width updated to width - * \param height updated to height - */ - -void history_size(struct history *history, int *width, int *height) -{ - *width = history->width; - *height = history->height; -} - - -/** - * Redraw a history. - * - * \param history history to render - * \param ctx current redraw context - */ - -bool history_redraw(struct history *history, const struct redraw_context *ctx) -{ - if (!history->start) - return true; - return history_redraw_entry(history, history->start, 0, 0, 0, 0, 0, 0, - false, ctx); -} - -/** - * Redraw part of a history. - * - * \param history history to render - * \param x0 left X co-ordinate of redraw area - * \param y0 top Y co-ordinate of redraw area - * \param x1 right X co-ordinate of redraw area - * \param y1 lower Y co-ordinate of redraw area - * \param x start X co-ordinate on plot canvas - * \param y start Y co-ordinate on plot canvas - * \param ctx current redraw context - */ - -bool history_redraw_rectangle(struct history *history, - int x0, int y0, int x1, int y1, - int x, int y, const struct redraw_context *ctx) -{ - if (!history->start) - return true; - return history_redraw_entry(history, history->start, - x0, y0, x1, y1, x, y, true, ctx); -} - -/** - * Recursively redraw a history_entry. - * - * \param history history containing the entry - * \param history_entry entry to render - * \param ctx current redraw context - */ - -bool history_redraw_entry(struct history *history, - struct history_entry *entry, - int x0, int y0, int x1, int y1, - int x, int y, bool clip, const struct redraw_context *ctx) -{ - const struct plotter_table *plot = ctx->plot; - size_t char_offset; - int actual_x; - struct history_entry *child; - colour c = entry == history->current ? HISTORY_COLOUR_SELECTED : HISTORY_COLOUR_FOREGROUND; - int tailsize = 5; - int xoffset = x - x0; - int yoffset = y - y0; - plot_style_t pstyle_history_rect = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_colour = c, - .stroke_width = entry == history->current ? 3 : 1, - }; - plot_font_style_t fstyle = *plot_style_font; - - if (clip) { - struct rect rect; - rect.x0 = x0 + xoffset; - rect.y0 = y0 + yoffset; - rect.x1 = x1 + xoffset; - rect.y1 = y1 + yoffset; - if(!plot->clip(&rect)) - return false; - } - - if (!plot->bitmap(entry->x + xoffset, entry->y + yoffset, WIDTH, HEIGHT, - entry->bitmap, 0xffffff, 0)) - return false; - if (!plot->rectangle(entry->x - 1 + xoffset, - entry->y - 1 + yoffset, - entry->x + xoffset + WIDTH, - entry->y + yoffset + HEIGHT, - &pstyle_history_rect)) - return false; - - if (!nsfont.font_position_in_string(plot_style_font, entry->page.title, - strlen(entry->page.title), WIDTH, - &char_offset, &actual_x)) - return false; - - fstyle.background = HISTORY_COLOUR_BACKGROUND; - fstyle.foreground = c; - fstyle.weight = entry == history->current ? 900 : 400; - - if (!plot->text(entry->x + xoffset, entry->y + HEIGHT + 12 + yoffset, - entry->page.title, char_offset, &fstyle)) - return false; - - for (child = entry->forward; child; child = child->next) { - if (!plot->line(entry->x + WIDTH + xoffset, - entry->y + HEIGHT / 2 + yoffset, - entry->x + WIDTH + tailsize + xoffset, - entry->y + HEIGHT / 2 + yoffset, - plot_style_stroke_history)) - return false; - if (!plot->line(entry->x + WIDTH + tailsize + xoffset, - entry->y + HEIGHT / 2 + yoffset, - child->x - tailsize +xoffset, - child->y + HEIGHT / 2 + yoffset, - plot_style_stroke_history)) - return false; - if (!plot->line(child->x - tailsize + xoffset, - child->y + HEIGHT / 2 + yoffset, - child->x + xoffset, child->y + HEIGHT / 2 + yoffset, - plot_style_stroke_history)) - return false; - if (!history_redraw_entry(history, child, x0, y0, x1, y1, x, y, - clip, ctx)) - return false; - } - - return true; -} - - -/** - * Handle a mouse click in a history. - * - * \param bw browser window containing history - * \param history history that was clicked in - * \param x click coordinate - * \param y click coordinate - * \param new_window open a new window instead of using bw - * \return true if action was taken, false if click was not on an entry - */ - -bool history_click(struct history *history, int x, int y, bool new_window) -{ - struct history_entry *entry; - - entry = history_find_position(history->start, x, y); - if (!entry) - return false; - if (entry == history->current) - return false; - - history_go(history, entry, new_window); - - return true; -} - - -/** - * Determine the URL of the entry at a position. - * - * \param history history to search - * \param x coordinate - * \param y coordinate - * \return URL, or 0 if no entry at (x, y) - */ - -const char *history_position_url(struct history *history, int x, int y) -{ - struct history_entry *entry; - - entry = history_find_position(history->start, x, y); - if (!entry) - return 0; - - return nsurl_access(entry->page.url); -} - - -/** - * Find the history entry at a position. - * - * \param entry entry to search from - * \param x coordinate - * \param y coordinate - * \return an entry if found, 0 if none - */ - -struct history_entry *history_find_position(struct history_entry *entry, - int x, int y) -{ - struct history_entry *child; - struct history_entry *found; - - if (!entry) - return 0; - - if (entry->x <= x && x <= entry->x + WIDTH && - entry->y <= y && y <= entry->y + HEIGHT) - return entry; - - for (child = entry->forward; child; child = child->next) { - found = history_find_position(child, x, y); - if (found) - return found; - } - - return 0; -} - -/* Documented in local_history.h */ -void history_enumerate_forward(struct history *history, - history_enumerate_cb cb, void *user_data) -{ - struct history_entry *entry; - - if (history == NULL || history->current == NULL) return; - - for (entry = history->current->forward_pref; entry != NULL; entry = entry->forward_pref) { - if (!cb(history, entry->x, entry->y, entry->x + WIDTH, - entry->y + HEIGHT, entry, user_data)) - break; - } -} - -/* Documented in local_history.h */ -void history_enumerate_back(struct history *history, - history_enumerate_cb cb, void *user_data) -{ - struct history_entry *entry; - - if (history == NULL || history->current == NULL) return; - - for (entry = history->current->back; entry != NULL; entry = entry->back) { - if (!cb(history, entry->x, entry->y, entry->x + WIDTH, - entry->y + HEIGHT, entry, user_data)) - break; - } -} - -/* Documented in local_history.h */ -void history_enumerate(const struct history *history, history_enumerate_cb cb, - void *user_data) -{ - history_enumerate_entry(history, history->start, cb, user_data); -} - -/** - * Enumerate subentries in history - * See also history_enumerate() - * - * \param history history to enumerate - * \param entry entry to start enumeration at - * \param cb callback function - * \param ud context pointer passed to cb - * \return true to continue enumeration, false to cancel - */ -static bool history_enumerate_entry(const struct history *history, - const struct history_entry *entry, history_enumerate_cb cb, void *ud) -{ - const struct history_entry *child; - - if (!cb(history, entry->x, entry->y, entry->x + WIDTH, entry->y + HEIGHT, - entry, ud)) return false; - - for (child = entry->forward; child; child = child->next) { - if (!history_enumerate_entry(history, child, cb, ud)) - return false; - } - - return true; -} - -/* Documented in local_history.h */ -const char *history_entry_get_url(const struct history_entry *entry) -{ - return nsurl_access(entry->page.url); -} - -/* Documented in local_history.h */ -const char *history_entry_get_fragment_id(const struct history_entry *entry) -{ - return (entry->page.frag_id) ? lwc_string_data(entry->page.frag_id) : 0; -} - -/* Documented in local_history.h */ -const char *history_entry_get_title(const struct history_entry *entry) -{ - return entry->page.title; -} diff --git a/desktop/local_history.h b/desktop/local_history.h deleted file mode 100644 index b3e177b28..000000000 --- a/desktop/local_history.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2006 James Bursa - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Browser history tree (interface). - */ - -#ifndef _NETSURF_DESKTOP_HISTORY_H_ -#define _NETSURF_DESKTOP_HISTORY_H_ - -#include -#include - -struct hlcache_handle; -struct history; -struct browser_window; -struct history_entry; -struct redraw_context; - -struct history *history_create(struct browser_window *bw); -struct history *history_clone(struct history *history, - struct browser_window *bw); -void history_add(struct history *history, struct hlcache_handle *content, - lwc_string *frag_id); -void history_update(struct history *history, struct hlcache_handle *content); -void history_destroy(struct history *history); -void history_back(struct history *history, bool new_window); -void history_forward(struct history *history, bool new_window); -bool history_back_available(struct history *history); -bool history_forward_available(struct history *history); -void history_size(struct history *history, int *width, int *height); -bool history_redraw(struct history *history, const struct redraw_context *ctx); -bool history_redraw_rectangle(struct history *history, - int x0, int y0, int x1, int y1, int x, int y, - const struct redraw_context *ctx); -bool history_click(struct history *history, int x, int y, bool new_window); -const char *history_position_url(struct history *history, int x, int y); - -/** - * Callback function type for history enumeration - * - * \param history history being enumerated - * \param x0, y0, x1, y1 Coordinates of entry in history tree view - * \param entry Current history entry - * \return true to continue enumeration, false to cancel enumeration - */ -typedef bool (*history_enumerate_cb)(const struct history *history, - int x0, int y0, - int x1, int y1, - const struct history_entry *entry, void *user_data); - -/** - * Enumerate all entries in the history. - * Do not change the history while it is being enumerated. - * - * \param history history to enumerate - * \param cb callback function - * \param user_data context pointer passed to cb - */ -void history_enumerate(const struct history *history, - history_enumerate_cb cb, void *user_data); - -/** - * Enumerate all entries that will be reached by the 'forward' button - * - * \param history The history object to enumerate in - * \param cb The callback function - * \param user_data Data passed to the callback - */ -void history_enumerate_forward( struct history *history, - history_enumerate_cb cb, void *user_data); - -/** - * Enumerate all entries that will be reached by the 'back' button - * - * \param history The history object to enumerate in - * \param cb The callback function - * \param user_data Data passed to the callback - */ -void history_enumerate_back( struct history *history, - history_enumerate_cb cb, void *user_data); - -/** - * Returns the URL to a history entry - * - * \param entry the history entry to retrieve the URL from - * \return the URL - */ -const char *history_entry_get_url(const struct history_entry *entry); - -/** - * Returns the URL to a history entry - * - * \param entry the history entry to retrieve the fragment id from - * \return the fragment id - */ -const char *history_entry_get_fragment_id(const struct history_entry *entry); - -/** - * Returns the title of a history entry - * - * \param entry the history entry to retrieve the title from - * \return the title - */ -const char *history_entry_get_title(const struct history_entry *entry); - -/** - * Open a history entry in the specified browser window - * - * \param bw browser window - * \param history history containing entry - * \param entry entry to open - * \param new_window open entry in new window - */ -void history_go(struct history *history, struct history_entry *entry, - bool new_window); - -#endif diff --git a/framebuffer/gui.c b/framebuffer/gui.c index 5b4f7a686..fe33827f7 100644 --- a/framebuffer/gui.c +++ b/framebuffer/gui.c @@ -31,7 +31,7 @@ #include #include -#include "desktop/browser_private.h" +#include "desktop/browser_history.h" #include "desktop/gui.h" #include "desktop/mouse.h" #include "desktop/plotters.h" @@ -58,7 +58,6 @@ #include "framebuffer/fetch.h" #include "content/urldb.h" -#include "desktop/local_history.h" #include "content/fetch.h" #define NSFB_TOOLBAR_DEFAULT_LAYOUT "blfsrutc" @@ -988,8 +987,8 @@ fb_leftarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) if (cbi->event->type != NSFB_EVENT_KEY_UP) return 0; - if (history_back_available(bw->history)) - history_back(bw->history, false); + if (browser_window_back_available(bw)) + browser_window_history_back(bw, false); fb_update_back_forward(gw); @@ -1006,8 +1005,8 @@ fb_rightarrow_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) if (cbi->event->type != NSFB_EVENT_KEY_UP) return 0; - if (history_forward_available(bw->history)) - history_forward(bw->history, false); + if (browser_window_forward_available(bw)) + browser_window_history_forward(bw, false); fb_update_back_forward(gw); return 1; diff --git a/framebuffer/localhistory.c b/framebuffer/localhistory.c index bb2736dd9..d7390abad 100644 --- a/framebuffer/localhistory.c +++ b/framebuffer/localhistory.c @@ -31,7 +31,7 @@ #include #include -#include "desktop/browser_private.h" +#include "desktop/browser_history.h" #include "desktop/gui.h" #include "desktop/plotters.h" #include "desktop/netsurf.h" @@ -52,7 +52,6 @@ #include "framebuffer/font.h" #include "content/urldb.h" -#include "desktop/local_history.h" #include "content/fetch.h" static int @@ -77,7 +76,7 @@ localhistory_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) nsfb_plot_rectangle_fill(fbtk_get_nsfb(widget), &rbox, 0xffffffff); - history_redraw_rectangle(glh->bw->history, + browser_window_history_redraw_rectangle(glh->bw, glh->scrollx, glh->scrolly, fbtk_get_width(widget) + glh->scrollx, @@ -97,7 +96,7 @@ localhistory_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) if (cbi->event->type != NSFB_EVENT_KEY_UP) return 0; - history_click(glh->bw->history, cbi->x, cbi->y, false); + browser_window_history_click(glh->bw, cbi->x, cbi->y, false); fbtk_set_mapping(glh->window, false); diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index e9ef9a4c1..36ba13a85 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -30,8 +30,8 @@ #include "utils/url.h" #include "utils/log.h" #include "utils/nsoption.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" -#include "desktop/local_history.h" #include "desktop/hotlist.h" #include "desktop/netsurf.h" #include "desktop/plotters.h" @@ -296,9 +296,9 @@ static void nsgtk_window_update_back_forward(struct gtk_scaffolding *g) struct browser_window *bw = nsgtk_get_browser_window(g->top_level); g->buttons[BACK_BUTTON]->sensitivity = - history_back_available(bw->history); - g->buttons[FORWARD_BUTTON]->sensitivity = history_forward_available( - bw->history); + browser_window_history_back_available(bw); + g->buttons[FORWARD_BUTTON]->sensitivity = + browser_window_history_forward_available(bw); nsgtk_scaffolding_set_sensitivity(g); @@ -308,7 +308,7 @@ static void nsgtk_window_update_back_forward(struct gtk_scaffolding *g) /* update the local history window, as well as queuing a redraw * for it. */ - history_size(bw->history, &width, &height); + browser_window_history_size(bw, &width, &height); gtk_widget_set_size_request(GTK_WIDGET(g->history_window->drawing_area), width, height); gtk_widget_queue_draw(GTK_WIDGET(g->history_window->drawing_area)); @@ -434,13 +434,9 @@ gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data) if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } else { - browser_window_navigate(bw, - url, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); + browser_window_navigate(bw, url, NULL, + BW_NAVIGATE_HISTORY, NULL, + NULL, NULL); nsurl_unref(url); } free(urltxt); @@ -1403,7 +1399,7 @@ MULTIHANDLER(back) struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - if ((bw == NULL) || (!history_back_available(bw->history))) + if ((bw == NULL) || (!browser_window_history_back_available(bw))) return TRUE; /* clear potential search effects */ @@ -1412,7 +1408,7 @@ MULTIHANDLER(back) nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); - history_back(bw->history, false); + browser_window_history_back(bw, false); nsgtk_window_update_back_forward(g); return TRUE; @@ -1423,7 +1419,7 @@ MULTIHANDLER(forward) struct browser_window *bw = nsgtk_get_browser_window(g->top_level); - if ((bw == NULL) || (!history_forward_available(bw->history))) + if ((bw == NULL) || (!browser_window_history_forward_available(bw))) return TRUE; /* clear potential search effects */ @@ -1432,7 +1428,7 @@ MULTIHANDLER(forward) nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); - history_forward(bw->history, false); + browser_window_history_forward(bw, false); nsgtk_window_update_back_forward(g); return TRUE; @@ -1474,7 +1470,7 @@ MULTIHANDLER(localhistory) /* if entries of the same url but different frag_ids have been added * the history needs redrawing (what throbber code normally does) */ - history_size(bw->history, &width, &height); + browser_window_history_size(bw, &width, &height); nsgtk_window_update_back_forward(g); gtk_window_get_position(g->window, &x, &y); gtk_window_get_size(g->window, &mainwidth, &mainheight); @@ -1674,7 +1670,7 @@ nsgtk_history_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) ctx.plot->clip(&clip); - history_redraw(bw->history, &ctx); + browser_window_history_redraw(bw, &ctx); current_widget = NULL; @@ -1707,7 +1703,7 @@ nsgtk_history_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer g) clip.y1 = event->area.y + event->area.height; ctx.plot->clip(&clip); - history_redraw(bw->history, &ctx); + browser_window_history_redraw(bw, &ctx); cairo_destroy(current_cr); @@ -1727,7 +1723,7 @@ static gboolean nsgtk_history_button_press_event(GtkWidget *widget, LOG(("X=%g, Y=%g", event->x, event->y)); - history_click(bw->history, event->x, event->y, false); + browser_window_history_click(bw, event->x, event->y, false); return TRUE; } diff --git a/riscos/gui.h b/riscos/gui.h index c201ab091..dbf6373c0 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -169,8 +169,7 @@ void gui_create_form_select_menu(struct browser_window *bw, struct form_control /* in history.c */ void ro_gui_history_init(void); -void ro_gui_history_open(struct browser_window *bw, struct history *history, - bool pointer); +void ro_gui_history_open(struct gui_window *g, bool pointer); /* in filetype.c */ const char *fetch_filetype(const char *unix_path); diff --git a/riscos/history.c b/riscos/history.c index 959f4ce38..c5bdfcb62 100644 --- a/riscos/history.c +++ b/riscos/history.c @@ -27,10 +27,9 @@ #include #include #include "oslib/wimp.h" -#include "desktop/local_history.h" +#include "desktop/browser_history.h" #include "desktop/plotters.h" #include "riscos/dialog.h" -#include "desktop/browser_private.h" #include "utils/nsoption.h" #include "riscos/gui.h" #include "riscos/mouse.h" @@ -43,7 +42,6 @@ static struct browser_window *history_bw; -static struct history *history_current = 0; /* Last position of mouse in window. */ static int mouse_x = 0; /* Last position of mouse in window. */ @@ -82,20 +80,20 @@ void ro_gui_history_init(void) * \param at_pointer open the window at the pointer */ -void ro_gui_history_open(struct browser_window *bw, - struct history *history, bool at_pointer) +void ro_gui_history_open(struct gui_window *g, bool at_pointer) { + struct browser_window *bw; int width, height; os_box box = {0, 0, 0, 0}; wimp_window_state state; os_error *error; - assert(history); - - history_current = history; + assert(g != NULL); + assert(g->bw != NULL); + bw = g->bw; history_bw = bw; - history_size(history, &width, &height); + browser_window_history_size(bw, &width, &height); width *= 2; height *= 2; @@ -132,8 +130,7 @@ void ro_gui_history_open(struct browser_window *bw, return; } - ro_gui_dialog_open_persistent(bw->window->window, history_window, - at_pointer); + ro_gui_dialog_open_persistent(g->window, history_window, at_pointer); } @@ -161,7 +158,7 @@ void ro_gui_history_redraw(wimp_draw *redraw) while (more) { ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; - history_redraw(history_current, &ctx); + browser_window_history_redraw(history_bw, &ctx); error = xwimp_get_rectangle(redraw, &more); if (error) { LOG(("xwimp_get_rectangle: 0x%x: %s", @@ -237,7 +234,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data) x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; - url = history_position_url(history_current, x, y); + url = browser_window_history_position_url(history_bw, x, y); if (!url) { /* not over a tree entry => close tooltip window. */ error = xwimp_close_window(dialog_tooltip); @@ -348,7 +345,7 @@ bool ro_gui_history_click(wimp_pointer *pointer) x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; - history_click(history_current, x, y, + browser_window_history_click(history_bw, x, y, pointer->buttons == wimp_CLICK_ADJUST); return true; diff --git a/riscos/menus.c b/riscos/menus.c index a0baca087..2ed06c37b 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -43,7 +43,6 @@ #include "desktop/cookie_manager.h" #include "desktop/browser.h" #include "desktop/gui.h" -#include "desktop/local_history.h" #include "desktop/netsurf.h" #include "desktop/textinput.h" diff --git a/riscos/window.c b/riscos/window.c index bf0529805..771f3f5bb 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -53,11 +53,11 @@ #include "content/hlcache.h" #include "content/urldb.h" #include "css/css.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" #include "desktop/cookie_manager.h" #include "desktop/scrollbar.h" #include "desktop/frames.h" -#include "desktop/local_history.h" #include "desktop/mouse.h" #include "desktop/plotters.h" #include "desktop/textinput.h" @@ -2404,9 +2404,9 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, ro_gui_menu_set_entry_shaded(menu, HOTLIST_ADD_URL, h == NULL); ro_gui_menu_set_entry_shaded(menu, HISTORY_SHOW_LOCAL, - (bw == NULL || (bw->history == NULL) || - !(h != NULL || history_back_available(bw->history) || - history_forward_available(bw->history)))); + (bw == NULL || + !(h != NULL || browser_window_back_available(bw) || + browser_window_forward_available(bw)))); /* Help Submenu */ @@ -2938,12 +2938,12 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, ro_gui_window_action_home(g); break; case BROWSER_NAVIGATE_BACK: - if (bw != NULL && bw->history != NULL) - history_back(bw->history, false); + if (bw != NULL) + browser_window_history_back(bw, false); break; case BROWSER_NAVIGATE_FORWARD: - if (bw != NULL && bw->history != NULL) - history_forward(bw->history, false); + if (bw != NULL) + browser_window_history_forward(bw, false); break; case BROWSER_NAVIGATE_UP: if (bw != NULL && h != NULL) @@ -3636,23 +3636,23 @@ void ro_gui_window_toolbar_click(void *data, switch (action.button) { case TOOLBAR_BUTTON_BACK: - if (g->bw != NULL && g->bw->history != NULL) - history_back(g->bw->history, false); + if (g->bw != NULL) + browser_window_history_back(g->bw, false); break; case TOOLBAR_BUTTON_BACK_NEW: - if (g->bw != NULL && g->bw->history != NULL) - history_back(g->bw->history, true); + if (g->bw != NULL) + browser_window_history_back(g->bw, true); break; case TOOLBAR_BUTTON_FORWARD: - if (g->bw != NULL && g->bw->history != NULL) - history_forward(g->bw->history, false); + if (g->bw != NULL) + browser_window_history_forward(g->bw, false); break; case TOOLBAR_BUTTON_FORWARD_NEW: - if (g->bw != NULL && g->bw->history != NULL) - history_forward(g->bw->history, true); + if (g->bw != NULL) + browser_window_history_forward(g->bw, true); break; case TOOLBAR_BUTTON_STOP: @@ -4127,7 +4127,7 @@ void ro_gui_window_action_new_window(struct gui_window *g) void ro_gui_window_action_local_history(struct gui_window *g) { if (g != NULL && g->bw != NULL && g->bw->history != NULL) - ro_gui_history_open(g->bw, g->bw->history, true); + ro_gui_history_open(g, true); } diff --git a/windows/gui.c b/windows/gui.c index 2559bf21e..92ff400ba 100644 --- a/windows/gui.c +++ b/windows/gui.c @@ -32,8 +32,8 @@ #include "content/urldb.h" #include "content/fetch.h" #include "css/utils.h" +#include "desktop/browser_history.h" #include "desktop/browser_private.h" -#include "desktop/local_history.h" #include "desktop/mouse.h" #include "desktop/netsurf.h" #include "utils/nsoption.h" @@ -342,8 +342,8 @@ static void nsws_window_update_forward_back(struct gui_window *w) if (w->bw == NULL) return; - bool forward = history_forward_available(w->bw->history); - bool back = history_back_available(w->bw->history); + bool forward = browser_window_history_forward_available(w->bw); + bool back = browser_window_history_back_available(w->bw); if (w->mainmenu != NULL) { EnableMenuItem(w->mainmenu, IDM_NAV_FORWARD, @@ -851,16 +851,16 @@ nsws_window_command(HWND hwnd, case IDM_NAV_BACK: if ((gw->bw != NULL) && - (history_back_available(gw->bw->history))) { - history_back(gw->bw->history, false); + (browser_window_history_back_available(gw->bw))) { + browser_window_history_back(gw->bw, false); } nsws_window_update_forward_back(gw); break; case IDM_NAV_FORWARD: if ((gw->bw != NULL) && - (history_forward_available(gw->bw->history))) { - history_forward(gw->bw->history, false); + (browser_window_history_forward_available(gw->bw))) { + browser_window_history_forward(gw->bw, false); } nsws_window_update_forward_back(gw); break; diff --git a/windows/localhistory.c b/windows/localhistory.c index d2be2c377..fb582b4aa 100644 --- a/windows/localhistory.c +++ b/windows/localhistory.c @@ -22,8 +22,7 @@ #include #include -#include "desktop/browser_private.h" -#include "desktop/local_history.h" +#include "desktop/browser_history.h" #include "desktop/plotters.h" #include "utils/utils.h" #include "utils/log.h" @@ -56,7 +55,7 @@ static void nsws_localhistory_scroll_check(struct nsws_localhistory *l, struct g if ((gw->bw == NULL) || (l->hwnd == NULL)) return; - history_size(gw->bw->history, &(l->width), &(l->height)); + browser_window_history_size(gw->bw, &(l->width), &(l->height)); si.cbSize = sizeof(si); si.fMask = SIF_ALL; @@ -97,7 +96,7 @@ static void nsws_localhistory_up(struct nsws_localhistory *l, struct gui_window tmp_hdc = plot_hdc; plot_hdc = GetDC(l->hwnd); - history_redraw(gw->bw->history, &ctx); + browser_window_history_redraw(gw->bw, &ctx); ReleaseDC(l->hwnd, plot_hdc); @@ -167,7 +166,7 @@ nsws_localhistory_event_callback(HWND hwnd, UINT msg, x = GET_X_LPARAM(lparam); y = GET_Y_LPARAM(lparam); - if (history_click(gw->bw->history, + if (browser_window_history_click(gw->bw, gw->localhistory->hscroll + x, gw->localhistory->vscroll + y, false)) { @@ -179,8 +178,6 @@ nsws_localhistory_event_callback(HWND hwnd, UINT msg, case WM_MOUSEMOVE: x = GET_X_LPARAM(lparam); y = GET_Y_LPARAM(lparam); -/* if (gw->bw != NULL) - history_hover(gw->bw->history, x, y, (void *)hwnd);*/ return DefWindowProc(hwnd, msg, wparam, lparam); break; @@ -286,7 +283,7 @@ nsws_localhistory_event_callback(HWND hwnd, UINT msg, tmp_hdc = plot_hdc; plot_hdc = hdc; - history_redraw_rectangle(gw->bw->history, + browser_window_history_redraw_rectangle(gw->bw, gw->localhistory->hscroll + ps.rcPaint.left, gw->localhistory->vscroll + ps.rcPaint.top, gw->localhistory->hscroll + (ps.rcPaint.right - ps.rcPaint.left), @@ -346,8 +343,8 @@ struct nsws_localhistory *nsws_window_create_localhistory(struct gui_window *gw) localhistory->width = 0; localhistory->height = 0; - if ((gw->bw != NULL) && (gw->bw->history != NULL)) { - history_size(gw->bw->history, + if (gw->bw != NULL) { + browser_window_history_size(gw->bw, &(localhistory->width), &(localhistory->height)); } -- cgit v1.2.3