summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-10 09:50:15 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-10 09:50:15 +0200
commit9741611c08d0f481a3f0583419b68b36d8711d1d (patch)
treede161bbc0bf04b47efa12b6b0e3f9b68b0e3085b
parent76259953925d42568c9ac80d6bb7732f1a9475be (diff)
Fixed history with multiple items having the same URL
If there were multiple instances of the same URL in history, only the latest one's content would be used when navigating back/forward.
-rw-r--r--res/about/version.gmi3
-rw-r--r--src/history.c32
-rw-r--r--src/history.h2
-rw-r--r--src/ui/documentwidget.c30
-rw-r--r--src/ui/documentwidget.h5
5 files changed, 46 insertions, 26 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index 506e3ae0..625e4ccb 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -10,6 +10,9 @@
10New features: 10New features:
11* Identity toolbar menu can be used to switch between alternate identities. If you have used multiple identities on one site, this makes it more convenient to switch between them. 11* Identity toolbar menu can be used to switch between alternate identities. If you have used multiple identities on one site, this makes it more convenient to switch between them.
12 12
13Fixes:
14* Fixed a history caching issue: if there were multiple instances of the same URL in history, only the latest one's content would be used when navigating back/forward.
15
13## 1.9.2 16## 1.9.2
14* Windows: Use the correct version number for update checks. 17* Windows: Use the correct version number for update checks.
15* Shorter label for "Mark All as Read" in Feeds sidebar actions. 18* Shorter label for "Mark All as Read" in Feeds sidebar actions.
diff --git a/src/history.c b/src/history.c
index d1a731fb..50db33dd 100644
--- a/src/history.c
+++ b/src/history.c
@@ -254,18 +254,26 @@ const iString *url_History(const iHistory *d, size_t pos) {
254 return collectNew_String(); 254 return collectNew_String();
255} 255}
256 256
257iRecentUrl *findUrl_History(iHistory *d, const iString *url) { 257#if 0
258iRecentUrl *findUrl_History(iHistory *d, const iString *url, int timeDir) {
258 url = canonicalUrl_String(url); 259 url = canonicalUrl_String(url);
260// if (!timeDir) {
261// timeDir = -1;
262// }
259 lock_Mutex(d->mtx); 263 lock_Mutex(d->mtx);
260 iReverseForEach(Array, i, &d->recent) { 264 for (size_t i = size_Array(&d->recent) - 1 - d->recentPos; i < size_Array(&d->recent);
261 if (cmpStringCase_String(url, &((iRecentUrl *) i.value)->url) == 0) { 265 i += timeDir) {
266 iRecentUrl *item = at_Array(&d->recent, i);
267 if (cmpStringCase_String(url, &item->url) == 0) {
262 unlock_Mutex(d->mtx); 268 unlock_Mutex(d->mtx);
263 return i.value; 269 return item; /* FIXME: Returning an internal pointer; should remain locked. */
264 } 270 }
271 if (!timeDir) break;
265 } 272 }
266 unlock_Mutex(d->mtx); 273 unlock_Mutex(d->mtx);
267 return NULL; 274 return NULL;
268} 275}
276#endif
269 277
270void replace_History(iHistory *d, const iString *url) { 278void replace_History(iHistory *d, const iString *url) {
271 url = canonicalUrl_String(url); 279 url = canonicalUrl_String(url);
@@ -405,20 +413,18 @@ void setCachedDocument_History(iHistory *d, iGmDocument *doc, iBool openedFromSi
405 lock_Mutex(d->mtx); 413 lock_Mutex(d->mtx);
406 iRecentUrl *item = mostRecentUrl_History(d); 414 iRecentUrl *item = mostRecentUrl_History(d);
407 if (item) { 415 if (item) {
408 if (equal_String(url_GmDocument(doc), &item->url)) {
409 item->flags.openedFromSidebar = openedFromSidebar;
410 if (item->cachedDoc != doc) {
411 iRelease(item->cachedDoc);
412 item->cachedDoc = ref_Object(doc);
413 }
414 }
415#if !defined (NDEBUG) 416#if !defined (NDEBUG)
416 else { 417 if (!equal_String(url_GmDocument(doc), &item->url)) {
417 printf("[History] Not updating cached document; expecting {%s} but document URL is {%s}\n", 418 printf("[History] Cache mismatch! Expecting data for item {%s} but document URL is {%s}\n",
418 cstr_String(&item->url), 419 cstr_String(&item->url),
419 cstr_String(url_GmDocument(doc))); 420 cstr_String(url_GmDocument(doc)));
420 } 421 }
421#endif 422#endif
423 item->flags.openedFromSidebar = openedFromSidebar;
424 if (item->cachedDoc != doc) {
425 iRelease(item->cachedDoc);
426 item->cachedDoc = ref_Object(doc);
427 }
422 } 428 }
423 unlock_Mutex(d->mtx); 429 unlock_Mutex(d->mtx);
424} 430}
diff --git a/src/history.h b/src/history.h
index 3bb3808e..bfb88cf4 100644
--- a/src/history.h
+++ b/src/history.h
@@ -71,7 +71,7 @@ iBool goForward_History (iHistory *);
71iRecentUrl *precedingLocked_History (iHistory *); /* requires manual lock/unlock! */ 71iRecentUrl *precedingLocked_History (iHistory *); /* requires manual lock/unlock! */
72iRecentUrl *recentUrl_History (iHistory *, size_t pos); 72iRecentUrl *recentUrl_History (iHistory *, size_t pos);
73iRecentUrl *mostRecentUrl_History (iHistory *); 73iRecentUrl *mostRecentUrl_History (iHistory *);
74iRecentUrl *findUrl_History (iHistory *, const iString *url); 74//iRecentUrl *findUrl_History (iHistory *, const iString *url, int timeDir);
75 75
76void clearCache_History (iHistory *); 76void clearCache_History (iHistory *);
77size_t pruneLeastImportant_History (iHistory *); 77size_t pruneLeastImportant_History (iHistory *);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index a9a0e07c..e68af4d8 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -231,6 +231,8 @@ enum iDocumentWidgetFlag {
231 urlChanged_DocumentWidgetFlag = iBit(13), 231 urlChanged_DocumentWidgetFlag = iBit(13),
232 openedFromSidebar_DocumentWidgetFlag = iBit(14), 232 openedFromSidebar_DocumentWidgetFlag = iBit(14),
233 drawDownloadCounter_DocumentWidgetFlag = iBit(15), 233 drawDownloadCounter_DocumentWidgetFlag = iBit(15),
234 fromCache_DocumentWidgetFlag = iBit(16), /* don't write anything to cache */
235 animationPlaceholder_DocumentWidgetFlag = iBit(17), /* avoid slow operations */
234}; 236};
235 237
236enum iDocumentLinkOrdinalMode { 238enum iDocumentLinkOrdinalMode {
@@ -1142,9 +1144,11 @@ static void documentWasChanged_DocumentWidget_(iDocumentWidget *d) {
1142 } 1144 }
1143 } 1145 }
1144 showOrHidePinningIndicator_DocumentWidget_(d); 1146 showOrHidePinningIndicator_DocumentWidget_(d);
1145 setCachedDocument_History(d->mod.history, 1147 if (~d->flags & fromCache_DocumentWidgetFlag) {
1146 d->doc, /* keeps a ref */ 1148 setCachedDocument_History(d->mod.history,
1147 (d->flags & openedFromSidebar_DocumentWidgetFlag) != 0); 1149 d->doc, /* keeps a ref */
1150 (d->flags & openedFromSidebar_DocumentWidgetFlag) != 0);
1151 }
1148} 1152}
1149 1153
1150void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { 1154void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) {
@@ -1743,6 +1747,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1743} 1747}
1744 1748
1745static void fetch_DocumentWidget_(iDocumentWidget *d) { 1749static void fetch_DocumentWidget_(iDocumentWidget *d) {
1750 iAssert(~d->flags & animationPlaceholder_DocumentWidgetFlag);
1746 /* Forget the previous request. */ 1751 /* Forget the previous request. */
1747 if (d->request) { 1752 if (d->request) {
1748 iRelease(d->request); 1753 iRelease(d->request);
@@ -1756,6 +1761,7 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) {
1756 d->certFlags = 0; 1761 d->certFlags = 0;
1757 setLinkNumberMode_DocumentWidget_(d, iFalse); 1762 setLinkNumberMode_DocumentWidget_(d, iFalse);
1758 d->flags &= ~drawDownloadCounter_DocumentWidgetFlag; 1763 d->flags &= ~drawDownloadCounter_DocumentWidgetFlag;
1764 d->flags &= ~fromCache_DocumentWidgetFlag;
1759 d->state = fetching_RequestState; 1765 d->state = fetching_RequestState;
1760 set_Atomic(&d->isRequestUpdated, iFalse); 1766 set_Atomic(&d->isRequestUpdated, iFalse);
1761 d->request = new_GmRequest(certs_App()); 1767 d->request = new_GmRequest(certs_App());
@@ -1805,7 +1811,8 @@ static void cacheRunGlyphs_(void *data, const iGmRun *run) {
1805} 1811}
1806 1812
1807static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) { 1813static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) {
1808 if (isFinishedLaunching_App() && isExposed_Window(get_Window())) { 1814 if (isFinishedLaunching_App() && isExposed_Window(get_Window()) &&
1815 ~d->flags & animationPlaceholder_DocumentWidgetFlag) {
1809 /* Just cache the top of the document, since this is what we usually need. */ 1816 /* Just cache the top of the document, since this is what we usually need. */
1810 int maxY = height_Widget(&d->widget) * 2; 1817 int maxY = height_Widget(&d->widget) * 2;
1811 if (maxY == 0) { 1818 if (maxY == 0) {
@@ -1885,6 +1892,7 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n
1885 d->doc = new_GmDocument(); 1892 d->doc = new_GmDocument();
1886 resetWideRuns_DocumentWidget_(d); 1893 resetWideRuns_DocumentWidget_(d);
1887 d->state = fetching_RequestState; 1894 d->state = fetching_RequestState;
1895 d->flags |= fromCache_DocumentWidgetFlag;
1888 /* Do the fetch. */ { 1896 /* Do the fetch. */ {
1889 d->initNormScrollY = normScrollY; 1897 d->initNormScrollY = normScrollY;
1890 /* Use the cached response data. */ 1898 /* Use the cached response data. */
@@ -1916,7 +1924,8 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n
1916} 1924}
1917 1925
1918static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { 1926static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
1919 const iRecentUrl *recent = findUrl_History(d->mod.history, d->mod.url); 1927 const iRecentUrl *recent = constMostRecentUrl_History(d->mod.history);
1928 iAssert(equalCase_String(&recent->url, d->mod.url));
1920 if (recent && recent->cachedResponse) { 1929 if (recent && recent->cachedResponse) {
1921 iChangeFlags(d->flags, 1930 iChangeFlags(d->flags,
1922 openedFromSidebar_DocumentWidgetFlag, 1931 openedFromSidebar_DocumentWidgetFlag,
@@ -2677,6 +2686,7 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2677 iDocumentWidget *swipeIn = findChild_Widget(swipeParent, "swipein"); 2686 iDocumentWidget *swipeIn = findChild_Widget(swipeParent, "swipein");
2678 if (!swipeIn) { 2687 if (!swipeIn) {
2679 swipeIn = new_DocumentWidget(); 2688 swipeIn = new_DocumentWidget();
2689 swipeIn->flags |= animationPlaceholder_DocumentWidgetFlag;
2680 setId_Widget(as_Widget(swipeIn), "swipein"); 2690 setId_Widget(as_Widget(swipeIn), "swipein");
2681 setFlags_Widget(as_Widget(swipeIn), 2691 setFlags_Widget(as_Widget(swipeIn),
2682 disabled_WidgetFlag | refChildrenOffset_WidgetFlag | 2692 disabled_WidgetFlag | refChildrenOffset_WidgetFlag |
@@ -2718,6 +2728,7 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2718 /* Set up the swipe dummy. */ 2728 /* Set up the swipe dummy. */
2719 iWidget *swipeParent = swipeParent_DocumentWidget_(d); 2729 iWidget *swipeParent = swipeParent_DocumentWidget_(d);
2720 iDocumentWidget *target = new_DocumentWidget(); 2730 iDocumentWidget *target = new_DocumentWidget();
2731 target->flags |= animationPlaceholder_DocumentWidgetFlag;
2721 setId_Widget(as_Widget(target), "swipeout"); 2732 setId_Widget(as_Widget(target), "swipeout");
2722 /* "swipeout" takes `d`'s document and goes underneath. */ 2733 /* "swipeout" takes `d`'s document and goes underneath. */
2723 target->widget.rect.pos = windowToInner_Widget(swipeParent, localToWindow_Widget(w, w->rect.pos)); 2734 target->widget.rect.pos = windowToInner_Widget(swipeParent, localToWindow_Widget(w, w->rect.pos));
@@ -2785,6 +2796,7 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2785 /* What was being shown in the `d` document is now being swapped to 2796 /* What was being shown in the `d` document is now being swapped to
2786 the outgoing page animation. */ 2797 the outgoing page animation. */
2787 iDocumentWidget *target = new_DocumentWidget(); 2798 iDocumentWidget *target = new_DocumentWidget();
2799 target->flags |= animationPlaceholder_DocumentWidgetFlag;
2788 addChildPos_Widget(swipeParent, iClob(target), back_WidgetAddPos); 2800 addChildPos_Widget(swipeParent, iClob(target), back_WidgetAddPos);
2789 setId_Widget(as_Widget(target), "swipeout"); 2801 setId_Widget(as_Widget(target), "swipeout");
2790 swap_DocumentWidget_(target, d->doc, d); 2802 swap_DocumentWidget_(target, d->doc, d);
@@ -2967,7 +2979,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2967 timeVerified_GmCertFlag); 2979 timeVerified_GmCertFlag);
2968 const iBool canTrust = ~d->certFlags & trusted_GmCertFlag && 2980 const iBool canTrust = ~d->certFlags & trusted_GmCertFlag &&
2969 ((d->certFlags & requiredForTrust) == requiredForTrust); 2981 ((d->certFlags & requiredForTrust) == requiredForTrust);
2970 const iRecentUrl *recent = findUrl_History(d->mod.history, d->mod.url); 2982 const iRecentUrl *recent = constMostRecentUrl_History(d->mod.history);
2971 const iString *meta = &d->sourceMime; 2983 const iString *meta = &d->sourceMime;
2972 if (recent && recent->cachedResponse) { 2984 if (recent && recent->cachedResponse) {
2973 meta = &recent->cachedResponse->meta; 2985 meta = &recent->cachedResponse->meta;
@@ -3178,6 +3190,8 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
3178 postProcessRequestContent_DocumentWidget_(d, iFalse); 3190 postProcessRequestContent_DocumentWidget_(d, iFalse);
3179 /* The response may be cached. */ 3191 /* The response may be cached. */
3180 if (d->request) { 3192 if (d->request) {
3193 iAssert(~d->flags & animationPlaceholder_DocumentWidgetFlag);
3194 iAssert(~d->flags & fromCache_DocumentWidgetFlag);
3181 if (!equal_Rangecc(urlScheme_String(d->mod.url), "about") && 3195 if (!equal_Rangecc(urlScheme_String(d->mod.url), "about") &&
3182 (startsWithCase_String(meta_GmRequest(d->request), "text/") || 3196 (startsWithCase_String(meta_GmRequest(d->request), "text/") ||
3183 !cmp_String(&d->sourceMime, mimeType_Gempub))) { 3197 !cmp_String(&d->sourceMime, mimeType_Gempub))) {
@@ -5399,12 +5413,12 @@ void deserializeState_DocumentWidget(iDocumentWidget *d, iStream *ins) {
5399void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) { 5413void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) {
5400 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag, 5414 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag,
5401 (setUrlFlags & openedFromSidebar_DocumentWidgetSetUrlFlag) != 0); 5415 (setUrlFlags & openedFromSidebar_DocumentWidgetSetUrlFlag) != 0);
5402 const iBool isFromCache = (setUrlFlags & useCachedContentIfAvailable_DocumentWidgetSetUrlFlag) != 0; 5416 const iBool allowCache = (setUrlFlags & useCachedContentIfAvailable_DocumentWidgetSetUrlFlag) != 0;
5403 setLinkNumberMode_DocumentWidget_(d, iFalse); 5417 setLinkNumberMode_DocumentWidget_(d, iFalse);
5404 setUrl_DocumentWidget_(d, urlFragmentStripped_String(url)); 5418 setUrl_DocumentWidget_(d, urlFragmentStripped_String(url));
5405 /* See if there a username in the URL. */ 5419 /* See if there a username in the URL. */
5406 parseUser_DocumentWidget_(d); 5420 parseUser_DocumentWidget_(d);
5407 if (!isFromCache || !updateFromHistory_DocumentWidget_(d)) { 5421 if (!allowCache || !updateFromHistory_DocumentWidget_(d)) {
5408 fetch_DocumentWidget_(d); 5422 fetch_DocumentWidget_(d);
5409 } 5423 }
5410} 5424}
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h
index 2df3392b..c97fa0ba 100644
--- a/src/ui/documentwidget.h
+++ b/src/ui/documentwidget.h
@@ -48,12 +48,9 @@ const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *);
48const iString * feedTitle_DocumentWidget (const iDocumentWidget *); 48const iString * feedTitle_DocumentWidget (const iDocumentWidget *);
49int documentWidth_DocumentWidget (const iDocumentWidget *); 49int documentWidth_DocumentWidget (const iDocumentWidget *);
50 50
51//iBool findCachedContent_DocumentWidget(const iDocumentWidget *, const iString *url,
52// iString *mime_out, iBlock *data_out);
53
54enum iDocumentWidgetSetUrlFlags { 51enum iDocumentWidgetSetUrlFlags {
55 useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1), 52 useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1),
56 openedFromSidebar_DocumentWidgetSetUrlFlag = iBit(2), 53 openedFromSidebar_DocumentWidgetSetUrlFlag = iBit(2),
57}; 54};
58 55
59void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); 56void setUrl_DocumentWidget (iDocumentWidget *, const iString *url);