summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2006-04-22 16:38:13 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2006-04-22 16:38:13 +0000
commit2b87a0b14874d9530d9aca3fb18f5bb74259beae (patch)
treeb27d8f6d99b6768b17321a8ab1a2507ca0636db2
parent229731ac822fafb017d767552990706209a55958 (diff)
downloadnetsurf-2b87a0b14874d9530d9aca3fb18f5bb74259beae.tar.gz
netsurf-2b87a0b14874d9530d9aca3fb18f5bb74259beae.tar.bz2
Clone history for child browser windows.
svn path=/trunk/netsurf/; revision=2546
-rw-r--r--desktop/browser.c5
-rw-r--r--desktop/history_core.c90
-rw-r--r--desktop/history_core.h1
3 files changed, 95 insertions, 1 deletions
diff --git a/desktop/browser.c b/desktop/browser.c
index 525d18b5d..dacea8e1d 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -108,7 +108,10 @@ void browser_window_create(const char *url, struct browser_window *clone,
bw->current_content = NULL;
bw->loading_content = NULL;
- bw->history = history_create();
+ if (!clone)
+ bw->history = history_create();
+ else
+ bw->history = history_clone(clone->history);
bw->sel = selection_create(bw);
bw->throbbing = false;
bw->caret_callback = NULL;
diff --git a/desktop/history_core.c b/desktop/history_core.c
index d851423f1..197596853 100644
--- a/desktop/history_core.c
+++ b/desktop/history_core.c
@@ -63,6 +63,8 @@ struct history {
int height;
};
+static bool history_clone_entry(struct history *history,
+ struct history_entry **start);
static void history_free_entry(struct history_entry *entry);
static void history_go(struct browser_window *bw, struct history *history,
struct history_entry *entry, bool new_window);
@@ -99,6 +101,94 @@ struct history *history_create(void)
/**
+ * 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 history *new_history;
+
+ if (!history->start)
+ return history_create();
+
+ new_history = malloc(sizeof *history);
+ if (!new_history)
+ return 0;
+ memcpy(new_history, history, sizeof *history);
+
+ if (!history_clone_entry(new_history, &new_history->start)) {
+ warn_user("NoMemory", 0);
+ return 0;
+ }
+
+ return new_history;
+}
+
+
+/**
+ * Clone a history entry
+ *
+ * \param history opaque history structure, as returned by history_create()
+ * \param start entry to clone
+ *
+ * \return true on success, false otherwise.
+ */
+
+bool history_clone_entry(struct history *history, struct history_entry **start)
+{
+ struct history_entry *child;
+ struct history_entry *sibling;
+ struct history_entry *entry = *start;
+ struct history_entry *new_entry;
+
+ /* clone the entry */
+ new_entry = malloc(sizeof *entry);
+ if (!new_entry)
+ return false;
+ memcpy(new_entry, entry, sizeof *entry);
+ new_entry->url = strdup(entry->url);
+ new_entry->frag_id = strdup(entry->frag_id);
+ new_entry->title = strdup(entry->title);
+ if (((entry->url) && (!new_entry->url)) ||
+ ((entry->title) && (!new_entry->title)) ||
+ ((entry->frag_id) && (!new_entry->frag_id)))
+ return false;
+ if (history->current == entry)
+ history->current = new_entry;
+ *start = new_entry;
+
+ if (entry->back) {
+ /* update all entry->next refrences */
+ for (sibling = entry->back->forward; sibling->next;
+ sibling = sibling->next) {
+ if (sibling->next == entry)
+ sibling->next = new_entry;
+ }
+ /* update all entry->forward, entry->forward_pref, and
+ * entry->forward_last references */
+ if (entry->back->forward == entry)
+ entry->back->forward = new_entry;
+ if (entry->back->forward_pref == entry)
+ entry->back->forward_pref = new_entry;
+ if (entry->back->forward_last == entry)
+ entry->back->forward_last = new_entry;
+ }
+
+ for (child = entry->forward; child; child = child->next) {
+ child->back = new_entry;
+ if (!history_clone_entry(history, &child))
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
* Insert a url into the history tree.
*
* \param history opaque history structure, as returned by history_create()
diff --git a/desktop/history_core.h b/desktop/history_core.h
index 4889ad524..d1f55ad83 100644
--- a/desktop/history_core.h
+++ b/desktop/history_core.h
@@ -19,6 +19,7 @@ struct history;
struct browser_window;
struct history *history_create(void);
+struct history *history_clone(struct history *history);
void history_add(struct history *history, struct content *content,
char *frag_id);
void history_update(struct history *history, struct content *content);