diff options
-rw-r--r-- | res/about/version.gmi | 3 | ||||
-rw-r--r-- | src/history.c | 32 | ||||
-rw-r--r-- | src/history.h | 2 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 30 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 5 |
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 @@ | |||
10 | New features: | 10 | New 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 | ||
13 | Fixes: | ||
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 | ||
257 | iRecentUrl *findUrl_History(iHistory *d, const iString *url) { | 257 | #if 0 |
258 | iRecentUrl *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 | ||
270 | void replace_History(iHistory *d, const iString *url) { | 278 | void 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 *); | |||
71 | iRecentUrl *precedingLocked_History (iHistory *); /* requires manual lock/unlock! */ | 71 | iRecentUrl *precedingLocked_History (iHistory *); /* requires manual lock/unlock! */ |
72 | iRecentUrl *recentUrl_History (iHistory *, size_t pos); | 72 | iRecentUrl *recentUrl_History (iHistory *, size_t pos); |
73 | iRecentUrl *mostRecentUrl_History (iHistory *); | 73 | iRecentUrl *mostRecentUrl_History (iHistory *); |
74 | iRecentUrl *findUrl_History (iHistory *, const iString *url); | 74 | //iRecentUrl *findUrl_History (iHistory *, const iString *url, int timeDir); |
75 | 75 | ||
76 | void clearCache_History (iHistory *); | 76 | void clearCache_History (iHistory *); |
77 | size_t pruneLeastImportant_History (iHistory *); | 77 | size_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 | ||
236 | enum iDocumentLinkOrdinalMode { | 238 | enum 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 | ||
1150 | void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { | 1154 | void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { |
@@ -1743,6 +1747,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, | |||
1743 | } | 1747 | } |
1744 | 1748 | ||
1745 | static void fetch_DocumentWidget_(iDocumentWidget *d) { | 1749 | static 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 | ||
1807 | static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) { | 1813 | static 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 | ||
1918 | static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { | 1926 | static 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) { | |||
5399 | void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) { | 5413 | void 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 *); | |||
48 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); | 48 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); |
49 | int documentWidth_DocumentWidget (const iDocumentWidget *); | 49 | int documentWidth_DocumentWidget (const iDocumentWidget *); |
50 | 50 | ||
51 | //iBool findCachedContent_DocumentWidget(const iDocumentWidget *, const iString *url, | ||
52 | // iString *mime_out, iBlock *data_out); | ||
53 | |||
54 | enum iDocumentWidgetSetUrlFlags { | 51 | enum 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 | ||
59 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); | 56 | void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); |