summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-11 12:56:14 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-11 12:56:25 +0300
commit9f7a9058d3593d09a8fad9cd42b59f8a15873837 (patch)
tree75efa83e07e2130f45308e9bff627b569086fa3a /src/ui/documentwidget.c
parenta13543aa922647ea2f8cc40cb9f3f797df8758df (diff)
Cache GmDocuments in memory
Navigation history keeps final GmDocuments in memory for quicker restore when navigating; no need to redo layout. Changed the color escape to Vertical Tab so Carriage Returns can be left in the source, reducing need to normalize spaces.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 0314757f..048f8ce4 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -975,13 +975,11 @@ iBool isPinned_DocumentWidget_(const iDocumentWidget *d) {
975 975
976static void showOrHidePinningIndicator_DocumentWidget_(iDocumentWidget *d) { 976static void showOrHidePinningIndicator_DocumentWidget_(iDocumentWidget *d) {
977 iWidget *w = as_Widget(d); 977 iWidget *w = as_Widget(d);
978 showCollapsed_Widget(findChild_Widget(root_Widget(as_Widget(d)), "document.pinned"), 978 showCollapsed_Widget(findChild_Widget(root_Widget(w), "document.pinned"),
979 isPinned_DocumentWidget_(d)); 979 isPinned_DocumentWidget_(d));
980} 980}
981 981
982void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { 982static void documentWasChanged_DocumentWidget_(iDocumentWidget *d) {
983 setUrl_GmDocument(d->doc, d->mod.url);
984 setSource_GmDocument(d->doc, source, documentWidth_DocumentWidget_(d));
985 documentRunsInvalidated_DocumentWidget_(d); 983 documentRunsInvalidated_DocumentWidget_(d);
986 updateWindowTitle_DocumentWidget_(d); 984 updateWindowTitle_DocumentWidget_(d);
987 updateVisible_DocumentWidget_(d); 985 updateVisible_DocumentWidget_(d);
@@ -997,7 +995,23 @@ void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) {
997 d->flags |= otherRootByDefault_DocumentWidgetFlag; 995 d->flags |= otherRootByDefault_DocumentWidgetFlag;
998 } 996 }
999 } 997 }
1000 showOrHidePinningIndicator_DocumentWidget_(d); 998 showOrHidePinningIndicator_DocumentWidget_(d);
999}
1000
1001void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) {
1002 setUrl_GmDocument(d->doc, d->mod.url);
1003 setSource_GmDocument(d->doc,
1004 source,
1005 documentWidth_DocumentWidget_(d),
1006 isFinished_GmRequest(d->request) ? final_GmDocumentUpdate
1007 : partial_GmDocumentUpdate);
1008 documentWasChanged_DocumentWidget_(d);
1009}
1010
1011static void replaceDocument_DocumentWidget_(iDocumentWidget *d, iGmDocument *newDoc) {
1012 iRelease(d->doc);
1013 d->doc = ref_Object(newDoc);
1014 documentWasChanged_DocumentWidget_(d);
1001} 1015}
1002 1016
1003static void updateTheme_DocumentWidget_(iDocumentWidget *d) { 1017static void updateTheme_DocumentWidget_(iDocumentWidget *d) {
@@ -1063,13 +1077,13 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode
1063 setBanner_GmDocument(d->doc, useBanner ? bannerType_DocumentWidget_(d) : none_GmDocumentBanner); 1077 setBanner_GmDocument(d->doc, useBanner ? bannerType_DocumentWidget_(d) : none_GmDocumentBanner);
1064 setFormat_GmDocument(d->doc, gemini_GmDocumentFormat); 1078 setFormat_GmDocument(d->doc, gemini_GmDocumentFormat);
1065 translate_Lang(src); 1079 translate_Lang(src);
1080 d->state = ready_RequestState;
1066 setSource_DocumentWidget(d, src); 1081 setSource_DocumentWidget(d, src);
1067 updateTheme_DocumentWidget_(d); 1082 updateTheme_DocumentWidget_(d);
1068 reset_SmoothScroll(&d->scrollY); 1083 reset_SmoothScroll(&d->scrollY);
1069 init_Anim(&d->sideOpacity, 0); 1084 init_Anim(&d->sideOpacity, 0);
1070 init_Anim(&d->altTextOpacity, 0); 1085 init_Anim(&d->altTextOpacity, 0);
1071 resetWideRuns_DocumentWidget_(d); 1086 resetWideRuns_DocumentWidget_(d);
1072 d->state = ready_RequestState;
1073} 1087}
1074 1088
1075static void updateFetchProgress_DocumentWidget_(iDocumentWidget *d) { 1089static void updateFetchProgress_DocumentWidget_(iDocumentWidget *d) {
@@ -1174,7 +1188,9 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool
1174 } 1188 }
1175} 1189}
1176 1190
1177static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response, 1191static void updateDocument_DocumentWidget_(iDocumentWidget *d,
1192 const iGmResponse *response,
1193 iGmDocument *cachedDoc,
1178 const iBool isInitialUpdate) { 1194 const iBool isInitialUpdate) {
1179 if (d->state == ready_RequestState) { 1195 if (d->state == ready_RequestState) {
1180 return; 1196 return;
@@ -1247,6 +1263,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse
1247 docFormat = gemini_GmDocumentFormat; 1263 docFormat = gemini_GmDocumentFormat;
1248 setRange_String(&d->sourceMime, param); 1264 setRange_String(&d->sourceMime, param);
1249 const iGmLinkId imgLinkId = 1; /* there's only the one link */ 1265 const iGmLinkId imgLinkId = 1; /* there's only the one link */
1266 /* TODO: Do the image loading in `postProcessRequestContent_DocumentWidget_()` */
1250 if ((isAudio && isInitialUpdate) || (!isAudio && isRequestFinished)) { 1267 if ((isAudio && isInitialUpdate) || (!isAudio && isRequestFinished)) {
1251 const char *linkTitle = 1268 const char *linkTitle =
1252 startsWith_String(mimeStr, "image/") ? "Image" : "Audio"; 1269 startsWith_String(mimeStr, "image/") ? "Image" : "Audio";
@@ -1300,7 +1317,10 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse
1300 collect_String(decode_Block(&str.chars, cstr_Rangecc(charset)))); 1317 collect_String(decode_Block(&str.chars, cstr_Rangecc(charset))));
1301 } 1318 }
1302 } 1319 }
1303 if (setSource) { 1320 if (cachedDoc) {
1321 replaceDocument_DocumentWidget_(d, cachedDoc);
1322 }
1323 else if (setSource) {
1304 setSource_DocumentWidget(d, &str); 1324 setSource_DocumentWidget(d, &str);
1305 } 1325 }
1306 deinit_String(&str); 1326 deinit_String(&str);
@@ -1386,7 +1406,8 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
1386 clear_ObjectList(d->media); 1406 clear_ObjectList(d->media);
1387 delete_Gempub(d->sourceGempub); 1407 delete_Gempub(d->sourceGempub);
1388 d->sourceGempub = NULL; 1408 d->sourceGempub = NULL;
1389 reset_GmDocument(d->doc); 1409 iRelease(d->doc);
1410 d->doc = new_GmDocument();
1390 resetWideRuns_DocumentWidget_(d); 1411 resetWideRuns_DocumentWidget_(d);
1391 d->state = fetching_RequestState; 1412 d->state = fetching_RequestState;
1392 /* Do the fetch. */ { 1413 /* Do the fetch. */ {
@@ -1397,10 +1418,11 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
1397 d->sourceStatus = success_GmStatusCode; 1418 d->sourceStatus = success_GmStatusCode;
1398 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); 1419 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached"));
1399 set_Block(&d->sourceContent, &resp->body); 1420 set_Block(&d->sourceContent, &resp->body);
1400 updateDocument_DocumentWidget_(d, resp, iTrue); 1421 updateDocument_DocumentWidget_(d, resp, recent->cachedDoc, iTrue);
1401 postProcessRequestContent_DocumentWidget_(d, iTrue); 1422 setCachedDocument_History(d->mod.history, d->doc);
1402 } 1423 }
1403 d->state = ready_RequestState; 1424 d->state = ready_RequestState;
1425 postProcessRequestContent_DocumentWidget_(d, iTrue);
1404 init_Anim(&d->altTextOpacity, 0); 1426 init_Anim(&d->altTextOpacity, 0);
1405 reset_SmoothScroll(&d->scrollY); 1427 reset_SmoothScroll(&d->scrollY);
1406 init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); 1428 init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y);
@@ -1587,11 +1609,12 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
1587 } 1609 }
1588 case categorySuccess_GmStatusCode: 1610 case categorySuccess_GmStatusCode:
1589 reset_SmoothScroll(&d->scrollY); 1611 reset_SmoothScroll(&d->scrollY);
1590 reset_GmDocument(d->doc); /* new content incoming */ 1612 iRelease(d->doc); /* new content incoming */
1613 d->doc = new_GmDocument();
1591 delete_Gempub(d->sourceGempub); 1614 delete_Gempub(d->sourceGempub);
1592 d->sourceGempub = NULL; 1615 d->sourceGempub = NULL;
1593 resetWideRuns_DocumentWidget_(d); 1616 resetWideRuns_DocumentWidget_(d);
1594 updateDocument_DocumentWidget_(d, resp, iTrue); 1617 updateDocument_DocumentWidget_(d, resp, NULL, iTrue);
1595 break; 1618 break;
1596 case categoryRedirect_GmStatusCode: 1619 case categoryRedirect_GmStatusCode:
1597 if (isEmpty_String(&resp->meta)) { 1620 if (isEmpty_String(&resp->meta)) {
@@ -1642,7 +1665,7 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
1642 switch (category_GmStatusCode(statusCode)) { 1665 switch (category_GmStatusCode(statusCode)) {
1643 case categorySuccess_GmStatusCode: 1666 case categorySuccess_GmStatusCode:
1644 /* More content available. */ 1667 /* More content available. */
1645 updateDocument_DocumentWidget_(d, resp, iFalse); 1668 updateDocument_DocumentWidget_(d, resp, NULL, iFalse);
1646 break; 1669 break;
1647 default: 1670 default:
1648 break; 1671 break;
@@ -2258,6 +2281,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2258 (startsWithCase_String(meta_GmRequest(d->request), "text/") || 2281 (startsWithCase_String(meta_GmRequest(d->request), "text/") ||
2259 !cmp_String(&d->sourceMime, mimeType_Gempub))) { 2282 !cmp_String(&d->sourceMime, mimeType_Gempub))) {
2260 setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request)); 2283 setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request));
2284 setCachedDocument_History(d->mod.history, d->doc); /* keeps a ref */
2261 unlockResponse_GmRequest(d->request); 2285 unlockResponse_GmRequest(d->request);
2262 } 2286 }
2263 } 2287 }