diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-16 08:33:35 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-16 08:33:35 +0200 |
commit | a50a01da45a8fb6a4d6ee419fc1ad240b1f0dee5 (patch) | |
tree | a9ad9bd8259034a95049f5432599b8497613dd32 | |
parent | 25a3f4fc680fbfd5acdd77361194cd6a2244c8cc (diff) |
Remember redirected URLs as visited
"visited.txt" will now remember URLs that were redirects, but those are not shown in the UI as part of the history. This fixes the issue where redirected URLs were not being shown as visited links in the UI.
Beware if downgrading Lagrange: URLs in the history will get prefixed with "0000 ". Might be a good idea to switch to a forwards compatible format like JSON for these files.
-rw-r--r-- | src/ui/documentwidget.c | 2 | ||||
-rw-r--r-- | src/ui/window.c | 2 | ||||
-rw-r--r-- | src/visited.c | 22 | ||||
-rw-r--r-- | src/visited.h | 11 |
4 files changed, 28 insertions, 9 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 3fc7e841..40f34db4 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
41 | #include "scrollwidget.h" | 41 | #include "scrollwidget.h" |
42 | #include "util.h" | 42 | #include "util.h" |
43 | #include "visbuf.h" | 43 | #include "visbuf.h" |
44 | #include "visited.h" | ||
44 | 45 | ||
45 | #include <the_Foundation/file.h> | 46 | #include <the_Foundation/file.h> |
46 | #include <the_Foundation/fileinfo.h> | 47 | #include <the_Foundation/fileinfo.h> |
@@ -1051,6 +1052,7 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { | |||
1051 | else if (equalCase_Rangecc(urlScheme_String(dstUrl), | 1052 | else if (equalCase_Rangecc(urlScheme_String(dstUrl), |
1052 | cstr_Rangecc(urlScheme_String(d->mod.url)))) { | 1053 | cstr_Rangecc(urlScheme_String(d->mod.url)))) { |
1053 | /* Redirects with the same scheme are automatic. */ | 1054 | /* Redirects with the same scheme are automatic. */ |
1055 | visitUrl_Visited(visited_App(), d->mod.url, transient_VisitedUrlFlag); | ||
1054 | postCommandf_App( | 1056 | postCommandf_App( |
1055 | "open redirect:%d url:%s", d->redirectCount + 1, cstr_String(dstUrl)); | 1057 | "open redirect:%d url:%s", d->redirectCount + 1, cstr_String(dstUrl)); |
1056 | } | 1058 | } |
diff --git a/src/ui/window.c b/src/ui/window.c index a69dd7db..ba6ee869 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -254,7 +254,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
254 | if (equal_Command(cmd, "document.changed")) { | 254 | if (equal_Command(cmd, "document.changed")) { |
255 | iInputWidget *url = findWidget_App("url"); | 255 | iInputWidget *url = findWidget_App("url"); |
256 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); | 256 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); |
257 | visitUrl_Visited(visited_App(), urlStr); | 257 | visitUrl_Visited(visited_App(), urlStr, 0); |
258 | postCommand_App("visited.changed"); /* sidebar will update */ | 258 | postCommand_App("visited.changed"); /* sidebar will update */ |
259 | setText_InputWidget(url, urlStr); | 259 | setText_InputWidget(url, urlStr); |
260 | updateTextCStr_LabelWidget(reloadButton, reloadCStr_); | 260 | updateTextCStr_LabelWidget(reloadButton, reloadCStr_); |
diff --git a/src/visited.c b/src/visited.c index e9dc9b94..b339198e 100644 --- a/src/visited.c +++ b/src/visited.c | |||
@@ -34,6 +34,7 @@ static const size_t maxAgeVisited_Visited_ = 3600 * 24 * 30; /* one month */ | |||
34 | void init_VisitedUrl(iVisitedUrl *d) { | 34 | void init_VisitedUrl(iVisitedUrl *d) { |
35 | initCurrent_Time(&d->when); | 35 | initCurrent_Time(&d->when); |
36 | init_String(&d->url); | 36 | init_String(&d->url); |
37 | d->flags = 0; | ||
37 | } | 38 | } |
38 | 39 | ||
39 | void deinit_VisitedUrl(iVisitedUrl *d) { | 40 | void deinit_VisitedUrl(iVisitedUrl *d) { |
@@ -81,13 +82,14 @@ void save_Visited(const iVisited *d, const char *dirPath) { | |||
81 | iDate date; | 82 | iDate date; |
82 | init_Date(&date, &item->when); | 83 | init_Date(&date, &item->when); |
83 | format_String(line, | 84 | format_String(line, |
84 | "%04d-%02d-%02dT%02d:%02d:%02d %s\n", | 85 | "%04d-%02d-%02dT%02d:%02d:%02d %04x %s\n", |
85 | date.year, | 86 | date.year, |
86 | date.month, | 87 | date.month, |
87 | date.day, | 88 | date.day, |
88 | date.hour, | 89 | date.hour, |
89 | date.minute, | 90 | date.minute, |
90 | date.second, | 91 | date.second, |
92 | item->flags, | ||
91 | cstr_String(&item->url)); | 93 | cstr_String(&item->url)); |
92 | writeData_File(f, cstr_String(line), size_String(line)); | 94 | writeData_File(f, cstr_String(line), size_String(line)); |
93 | } | 95 | } |
@@ -106,11 +108,16 @@ void load_Visited(iVisited *d, const char *dirPath) { | |||
106 | iTime now; | 108 | iTime now; |
107 | initCurrent_Time(&now); | 109 | initCurrent_Time(&now); |
108 | while (nextSplit_Rangecc(src, "\n", &line)) { | 110 | while (nextSplit_Rangecc(src, "\n", &line)) { |
109 | if (isEmpty_Range(&line)) continue; | 111 | if (size_Range(&line) < 22) continue; |
110 | int y, m, D, H, M, S; | 112 | int y, m, D, H, M, S; |
111 | sscanf(line.start, "%04d-%02d-%02dT%02d:%02d:%02d ", &y, &m, &D, &H, &M, &S); | 113 | sscanf(line.start, "%04d-%02d-%02dT%02d:%02d:%02d ", &y, &m, &D, &H, &M, &S); |
112 | if (!y) break; | 114 | if (!y) break; |
113 | iVisitedUrl item; | 115 | iVisitedUrl item; |
116 | const char *urlStart = line.start + 20; | ||
117 | if (*urlStart == '0' && size_Range(&line) >= 25) { | ||
118 | item.flags = strtoul(line.start + 20, NULL, 16); | ||
119 | urlStart += 5; | ||
120 | } | ||
114 | init_VisitedUrl(&item); | 121 | init_VisitedUrl(&item); |
115 | init_Time( | 122 | init_Time( |
116 | &item.when, | 123 | &item.when, |
@@ -118,7 +125,7 @@ void load_Visited(iVisited *d, const char *dirPath) { | |||
118 | if (secondsSince_Time(&now, &item.when) > maxAgeVisited_Visited_) { | 125 | if (secondsSince_Time(&now, &item.when) > maxAgeVisited_Visited_) { |
119 | continue; /* Too old. */ | 126 | continue; /* Too old. */ |
120 | } | 127 | } |
121 | initRange_String(&item.url, (iRangecc){ line.start + 20, line.end }); | 128 | initRange_String(&item.url, (iRangecc){ urlStart, line.end }); |
122 | insert_SortedArray(&d->visited, &item); | 129 | insert_SortedArray(&d->visited, &item); |
123 | } | 130 | } |
124 | unlock_Mutex(d->mtx); | 131 | unlock_Mutex(d->mtx); |
@@ -147,10 +154,11 @@ static size_t find_Visited_(const iVisited *d, const iString *url) { | |||
147 | return pos; | 154 | return pos; |
148 | } | 155 | } |
149 | 156 | ||
150 | void visitUrl_Visited(iVisited *d, const iString *url) { | 157 | void visitUrl_Visited(iVisited *d, const iString *url, uint16_t visitFlags) { |
151 | if (isEmpty_String(url)) return; | 158 | if (isEmpty_String(url)) return; |
152 | iVisitedUrl visit; | 159 | iVisitedUrl visit; |
153 | init_VisitedUrl(&visit); | 160 | init_VisitedUrl(&visit); |
161 | visit.flags = visitFlags; | ||
154 | set_String(&visit.url, url); | 162 | set_String(&visit.url, url); |
155 | size_t pos; | 163 | size_t pos; |
156 | lock_Mutex(d->mtx); | 164 | lock_Mutex(d->mtx); |
@@ -158,6 +166,7 @@ void visitUrl_Visited(iVisited *d, const iString *url) { | |||
158 | iVisitedUrl *old = at_SortedArray(&d->visited, pos); | 166 | iVisitedUrl *old = at_SortedArray(&d->visited, pos); |
159 | if (cmpNewer_VisitedUrl_(&visit, old)) { | 167 | if (cmpNewer_VisitedUrl_(&visit, old)) { |
160 | old->when = visit.when; | 168 | old->when = visit.when; |
169 | old->flags = visitFlags; | ||
161 | unlock_Mutex(d->mtx); | 170 | unlock_Mutex(d->mtx); |
162 | deinit_VisitedUrl(&visit); | 171 | deinit_VisitedUrl(&visit); |
163 | return; | 172 | return; |
@@ -200,7 +209,10 @@ const iArray *list_Visited(const iVisited *d, size_t count) { | |||
200 | iPtrArray *urls = collectNew_PtrArray(); | 209 | iPtrArray *urls = collectNew_PtrArray(); |
201 | iGuardMutex(d->mtx, { | 210 | iGuardMutex(d->mtx, { |
202 | iConstForEach(Array, i, &d->visited.values) { | 211 | iConstForEach(Array, i, &d->visited.values) { |
203 | pushBack_PtrArray(urls, i.value); | 212 | const iVisitedUrl *vis = i.value; |
213 | if (~vis->flags & transient_VisitedUrlFlag) { | ||
214 | pushBack_PtrArray(urls, vis); | ||
215 | } | ||
204 | } | 216 | } |
205 | }); | 217 | }); |
206 | sort_Array(urls, cmpWhenDescending_VisitedUrlPtr_); | 218 | sort_Array(urls, cmpWhenDescending_VisitedUrlPtr_); |
diff --git a/src/visited.h b/src/visited.h index 5a34d008..d9eb02b6 100644 --- a/src/visited.h +++ b/src/visited.h | |||
@@ -32,8 +32,13 @@ iDeclareType(VisitedUrl) | |||
32 | iDeclareTypeConstruction(VisitedUrl) | 32 | iDeclareTypeConstruction(VisitedUrl) |
33 | 33 | ||
34 | struct Impl_VisitedUrl { | 34 | struct Impl_VisitedUrl { |
35 | iString url; | 35 | iString url; |
36 | iTime when; | 36 | iTime when; |
37 | uint16_t flags; | ||
38 | }; | ||
39 | |||
40 | enum iVisitedUrlFlag { | ||
41 | transient_VisitedUrlFlag = 0x1, /* redirected; don't show in history */ | ||
37 | }; | 42 | }; |
38 | 43 | ||
39 | iDeclareType(Visited) | 44 | iDeclareType(Visited) |
@@ -44,7 +49,7 @@ void load_Visited (iVisited *, const char *dirPath); | |||
44 | void save_Visited (const iVisited *, const char *dirPath); | 49 | void save_Visited (const iVisited *, const char *dirPath); |
45 | 50 | ||
46 | iTime urlVisitTime_Visited (const iVisited *, const iString *url); | 51 | iTime urlVisitTime_Visited (const iVisited *, const iString *url); |
47 | void visitUrl_Visited (iVisited *, const iString *url); /* adds URL to the visited URLs set */ | 52 | void visitUrl_Visited (iVisited *, const iString *url, uint16_t visitFlags); /* adds URL to the visited URLs set */ |
48 | void removeUrl_Visited (iVisited *, const iString *url); | 53 | void removeUrl_Visited (iVisited *, const iString *url); |
49 | 54 | ||
50 | const iPtrArray * list_Visited (const iVisited *, size_t count); /* returns collected */ | 55 | const iPtrArray * list_Visited (const iVisited *, size_t count); /* returns collected */ |