1 /** Visited URL history managment - NOT dialog_goto_url() history!
12 #include "cache/cache.h"
13 #include "config/options.h"
14 #include "dialogs/status.h"
15 #include "network/connection.h"
16 #include "protocol/uri.h"
17 #include "session/history.h"
18 #include "session/location.h"
19 #include "session/session.h"
20 #include "session/task.h"
21 #include "util/memory.h"
22 #include "util/string.h"
23 #include "viewer/text/view.h"
24 #include "viewer/text/vs.h"
28 free_history(LIST_OF(struct location
) *history
)
30 while (!list_empty(*history
)) {
31 struct location
*loc
= history
->next
;
34 destroy_location(loc
);
39 /** @relates ses_history */
41 create_history(struct ses_history
*history
)
43 init_list(history
->history
);
44 history
->current
= NULL
;
47 /** @relates ses_history */
49 destroy_history(struct ses_history
*history
)
51 free_history(&history
->history
);
52 history
->current
= NULL
;
55 /** @relates ses_history */
57 clean_unhistory(struct ses_history
*history
)
59 if (!history
->current
) return;
61 while (list_has_next(history
->history
, history
->current
)) {
62 struct location
*loc
= history
->current
->next
;
65 destroy_location(loc
);
69 /** @relates ses_history */
71 add_to_history(struct ses_history
*history
, struct location
*loc
)
73 if (!history
->current
) {
74 add_to_list(history
->history
, loc
);
76 add_at_pos(history
->current
, loc
);
79 history
->current
= loc
;
82 /** @relates ses_history */
84 del_from_history(struct ses_history
*history
, struct location
*loc
)
86 if (history
->current
== loc
)
87 history
->current
= loc
->prev
;
89 if (history
->current
== (struct location
*) &history
->history
)
90 history
->current
= loc
->next
;
92 if (history
->current
== (struct location
*) &history
->history
)
93 history
->current
= NULL
;
99 ses_history_move(struct session
*ses
)
101 struct location
*loc
;
106 mem_free_set(&ses
->search_word
, NULL
);
108 /* Does it make sense? */
110 if (!have_location(ses
) || !ses
->task
.target
.location
)
113 if (ses
->task
.target
.location
114 == (struct location
*) &ses
->history
.history
)
119 ses
->history
.current
= ses
->task
.target
.location
;
123 /* There can be only one ... */
124 if (compare_uri(loc
->vs
.uri
, ses
->loading_uri
, 0))
127 /* Remake that location. */
129 del_from_history(&ses
->history
, loc
);
130 destroy_location(loc
);
133 /* Maybe trash the unhistory. */
135 if (get_opt_bool("document.history.keep_unhistory"))
136 clean_unhistory(&ses
->history
);
141 go_history(struct session
*ses
, struct location
*loc
)
143 ses
->reloadlevel
= CACHE_MODE_NORMAL
;
145 if (ses
->task
.type
) {
146 abort_loading(ses
, 0);
147 print_screen_status(ses
);
148 reload(ses
, CACHE_MODE_NORMAL
);
152 if (!have_location(ses
)
153 || loc
== (struct location
*) &ses
->history
.history
) {
154 /* There's no history, at most only the current location. */
158 abort_loading(ses
, 0);
160 set_session_referrer(ses
, NULL
);
162 ses_goto(ses
, loc
->vs
.uri
, NULL
, loc
,
163 CACHE_MODE_ALWAYS
, TASK_HISTORY
, 0);
167 go_history_by_n(struct session
*ses
, int n
)
169 struct location
*loc
= cur_loc(ses
);
174 while (n
-- && list_has_next(ses
->history
.history
, loc
))
177 while (n
++ && list_has_prev(ses
->history
.history
, loc
))
181 go_history(ses
, loc
);
184 /** Go backward in the history. See go_history() description regarding
185 * unpredictable effects on cur_loc() by this function. */
187 go_back(struct session
*ses
)
189 go_history_by_n(ses
, -1);
192 /** Go forward in the history. See go_history() description regarding
193 * unpredictable effects on cur_loc() by this function. */
195 go_unback(struct session
*ses
)
197 go_history_by_n(ses
, 1);