diff options
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 135 |
1 files changed, 90 insertions, 45 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index a52e99af..fdc0dd75 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -358,6 +358,7 @@ static void updateSideIconBuf_DocumentWidget_ (const iDocumentWidget *d); | |||
358 | static void prerender_DocumentWidget_ (iAny *); | 358 | static void prerender_DocumentWidget_ (iAny *); |
359 | static void scrollBegan_DocumentWidget_ (iAnyObject *, int, uint32_t); | 359 | static void scrollBegan_DocumentWidget_ (iAnyObject *, int, uint32_t); |
360 | static void refreshWhileScrolling_DocumentWidget_ (iAny *); | 360 | static void refreshWhileScrolling_DocumentWidget_ (iAny *); |
361 | static iBool requestMedia_DocumentWidget_ (iDocumentWidget *d, iGmLinkId linkId, iBool enableFilters); | ||
361 | 362 | ||
362 | /* TODO: The following methods are called from DocumentView, which goes the wrong way. */ | 363 | /* TODO: The following methods are called from DocumentView, which goes the wrong way. */ |
363 | 364 | ||
@@ -1824,7 +1825,7 @@ static void draw_DocumentView_(const iDocumentView *d) { | |||
1824 | } | 1825 | } |
1825 | if (d->drawBufs->flags & updateSideBuf_DrawBufsFlag) { | 1826 | if (d->drawBufs->flags & updateSideBuf_DrawBufsFlag) { |
1826 | updateSideIconBuf_DocumentView_(d); | 1827 | updateSideIconBuf_DocumentView_(d); |
1827 | } | 1828 | } |
1828 | const iRect docBounds = documentBounds_DocumentView_(d); | 1829 | const iRect docBounds = documentBounds_DocumentView_(d); |
1829 | const iRangei vis = visibleRange_DocumentView_(d); | 1830 | const iRangei vis = visibleRange_DocumentView_(d); |
1830 | iDrawContext ctx = { | 1831 | iDrawContext ctx = { |
@@ -2410,6 +2411,20 @@ static const char *zipPageHeading_(const iRangecc mime) { | |||
2410 | 2411 | ||
2411 | static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool isCached) { | 2412 | static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool isCached) { |
2412 | iWidget *w = as_Widget(d); | 2413 | iWidget *w = as_Widget(d); |
2414 | /* Embedded images in data links can be shown immediately as they are already fetched | ||
2415 | data that is part of the document. */ | ||
2416 | if (prefs_App()->openDataUrlImagesOnLoad) { | ||
2417 | iGmDocument *doc = d->view.doc; | ||
2418 | for (size_t linkId = 1; ; linkId++) { | ||
2419 | const int linkFlags = linkFlags_GmDocument(doc, linkId); | ||
2420 | const iString *linkUrl = linkUrl_GmDocument(doc, linkId); | ||
2421 | if (!linkUrl) break; | ||
2422 | if (scheme_GmLinkFlag(linkFlags) == data_GmLinkScheme && | ||
2423 | (linkFlags & imageFileExtension_GmLinkFlag)) { | ||
2424 | requestMedia_DocumentWidget_(d, linkId, 0); | ||
2425 | } | ||
2426 | } | ||
2427 | } | ||
2413 | /* Gempub page behavior and footer actions. */ { | 2428 | /* Gempub page behavior and footer actions. */ { |
2414 | /* TODO: move this to gempub.c */ | 2429 | /* TODO: move this to gempub.c */ |
2415 | delete_Gempub(d->sourceGempub); | 2430 | delete_Gempub(d->sourceGempub); |
@@ -2681,7 +2696,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, | |||
2681 | if (loadArchive_FontPack(fp, zip)) { | 2696 | if (loadArchive_FontPack(fp, zip)) { |
2682 | appendFormat_String(&str, "# " fontpack_Icon "%s\n%s", | 2697 | appendFormat_String(&str, "# " fontpack_Icon "%s\n%s", |
2683 | cstr_String(id_FontPack(fp).id), | 2698 | cstr_String(id_FontPack(fp).id), |
2684 | cstrCollect_String(infoText_FontPack(fp))); | 2699 | cstrCollect_String(infoText_FontPack(fp, iTrue))); |
2685 | } | 2700 | } |
2686 | appendCStr_String(&str, "\n"); | 2701 | appendCStr_String(&str, "\n"); |
2687 | appendCStr_String(&str, cstr_Lang("fontpack.help")); | 2702 | appendCStr_String(&str, cstr_Lang("fontpack.help")); |
@@ -3258,9 +3273,11 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { | |||
3258 | setTextColor_LabelWidget(menu, uiTextAction_ColorId); | 3273 | setTextColor_LabelWidget(menu, uiTextAction_ColorId); |
3259 | } | 3274 | } |
3260 | } | 3275 | } |
3261 | setValidator_InputWidget(findChild_Widget(dlg, "input"), inputQueryValidator_, d); | 3276 | iInputWidget *input = findChild_Widget(dlg, "input"); |
3262 | setSensitiveContent_InputWidget(findChild_Widget(dlg, "input"), | 3277 | setValidator_InputWidget(input, inputQueryValidator_, d); |
3263 | statusCode == sensitiveInput_GmStatusCode); | 3278 | setBackupFileName_InputWidget(input, "inputbackup.txt"); |
3279 | setSelectAllOnFocus_InputWidget(input, iTrue); | ||
3280 | setSensitiveContent_InputWidget(input, statusCode == sensitiveInput_GmStatusCode); | ||
3264 | if (document_App() != d) { | 3281 | if (document_App() != d) { |
3265 | postCommandf_App("tabs.switch page:%p", d); | 3282 | postCommandf_App("tabs.switch page:%p", d); |
3266 | } | 3283 | } |
@@ -3921,12 +3938,12 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
3921 | const char *unchecked = red_ColorEscape "\u2610"; | 3938 | const char *unchecked = red_ColorEscape "\u2610"; |
3922 | const char *checked = green_ColorEscape "\u2611"; | 3939 | const char *checked = green_ColorEscape "\u2611"; |
3923 | const iBool haveFingerprint = (d->certFlags & haveFingerprint_GmCertFlag) != 0; | 3940 | const iBool haveFingerprint = (d->certFlags & haveFingerprint_GmCertFlag) != 0; |
3924 | const int requiredForTrust = (available_GmCertFlag | haveFingerprint_GmCertFlag | | 3941 | const int requiredForTrust = |
3925 | timeVerified_GmCertFlag); | 3942 | (available_GmCertFlag | haveFingerprint_GmCertFlag | timeVerified_GmCertFlag); |
3926 | const iBool canTrust = ~d->certFlags & trusted_GmCertFlag && | 3943 | const iBool canTrust = ~d->certFlags & trusted_GmCertFlag && |
3927 | ((d->certFlags & requiredForTrust) == requiredForTrust); | 3944 | ((d->certFlags & requiredForTrust) == requiredForTrust); |
3928 | const iRecentUrl *recent = constMostRecentUrl_History(d->mod.history); | 3945 | const iRecentUrl *recent = constMostRecentUrl_History(d->mod.history); |
3929 | const iString *meta = &d->sourceMime; | 3946 | const iString *meta = &d->sourceMime; |
3930 | if (recent && recent->cachedResponse) { | 3947 | if (recent && recent->cachedResponse) { |
3931 | meta = &recent->cachedResponse->meta; | 3948 | meta = &recent->cachedResponse->meta; |
3932 | } | 3949 | } |
@@ -3991,6 +4008,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
3991 | if (haveFingerprint) { | 4008 | if (haveFingerprint) { |
3992 | pushBack_Array(items, &(iMenuItem){ "${dlg.cert.fingerprint}", 0, 0, "server.copycert" }); | 4009 | pushBack_Array(items, &(iMenuItem){ "${dlg.cert.fingerprint}", 0, 0, "server.copycert" }); |
3993 | } | 4010 | } |
4011 | const iRangecc root = urlRoot_String(d->mod.url); | ||
4012 | if (!isEmpty_Range(&root)) { | ||
4013 | pushBack_Array(items, &(iMenuItem){ "${pageinfo.settings}", 0, 0, "document.sitespec" }); | ||
4014 | } | ||
3994 | if (!isEmpty_Array(items)) { | 4015 | if (!isEmpty_Array(items)) { |
3995 | pushBack_Array(items, &(iMenuItem){ "---", 0, 0, 0 }); | 4016 | pushBack_Array(items, &(iMenuItem){ "---", 0, 0, 0 }); |
3996 | } | 4017 | } |
@@ -4014,6 +4035,12 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
4014 | addAction_Widget(dlg, SDLK_SPACE, 0, "message.ok"); | 4035 | addAction_Widget(dlg, SDLK_SPACE, 0, "message.ok"); |
4015 | return iTrue; | 4036 | return iTrue; |
4016 | } | 4037 | } |
4038 | else if (equal_Command(cmd, "document.sitespec") && d == document_App()) { | ||
4039 | if (!findWidget_App("sitespec.palette")) { | ||
4040 | makeSiteSpecificSettings_Widget(d->mod.url); | ||
4041 | } | ||
4042 | return iTrue; | ||
4043 | } | ||
4017 | else if (equal_Command(cmd, "server.unexpire") && document_App() == d) { | 4044 | else if (equal_Command(cmd, "server.unexpire") && document_App() == d) { |
4018 | const iRangecc host = urlHost_String(d->mod.url); | 4045 | const iRangecc host = urlHost_String(d->mod.url); |
4019 | const uint16_t port = urlPort_String(d->mod.url); | 4046 | const uint16_t port = urlPort_String(d->mod.url); |
@@ -4922,7 +4949,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
4922 | for (size_t i = 0; i < 64; ++i) { | 4949 | for (size_t i = 0; i < 64; ++i) { |
4923 | setByte_Block(seed, i, iRandom(0, 256)); | 4950 | setByte_Block(seed, i, iRandom(0, 256)); |
4924 | } | 4951 | } |
4925 | setThemeSeed_GmDocument(view->doc, seed); | 4952 | setThemeSeed_GmDocument(view->doc, seed, NULL); |
4926 | delete_Block(seed); | 4953 | delete_Block(seed); |
4927 | invalidate_DocumentWidget_(d); | 4954 | invalidate_DocumentWidget_(d); |
4928 | refresh_Widget(w); | 4955 | refresh_Widget(w); |
@@ -5044,10 +5071,9 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
5044 | iArray items; | 5071 | iArray items; |
5045 | init_Array(&items, sizeof(iMenuItem)); | 5072 | init_Array(&items, sizeof(iMenuItem)); |
5046 | if (d->contextLink) { | 5073 | if (d->contextLink) { |
5047 | /* Context menu for a link. */ | 5074 | /* Construct the link context menu, depending on what kind of link was clicked. */ |
5048 | interactingWithLink_DocumentWidget_(d, d->contextLink->linkId); /* perhaps will be triggered */ | 5075 | interactingWithLink_DocumentWidget_(d, d->contextLink->linkId); /* perhaps will be triggered */ |
5049 | const iString *linkUrl = linkUrl_GmDocument(view->doc, d->contextLink->linkId); | 5076 | const iString *linkUrl = linkUrl_GmDocument(view->doc, d->contextLink->linkId); |
5050 | // const int linkFlags = linkFlags_GmDocument(d->doc, d->contextLink->linkId); | ||
5051 | const iRangecc scheme = urlScheme_String(linkUrl); | 5077 | const iRangecc scheme = urlScheme_String(linkUrl); |
5052 | const iBool isGemini = equalCase_Rangecc(scheme, "gemini"); | 5078 | const iBool isGemini = equalCase_Rangecc(scheme, "gemini"); |
5053 | iBool isNative = iFalse; | 5079 | iBool isNative = iFalse; |
@@ -5059,41 +5085,55 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
5059 | format_CStr("```%s", cstr_String(infoText)), | 5085 | format_CStr("```%s", cstr_String(infoText)), |
5060 | 0, 0, NULL }); | 5086 | 0, 0, NULL }); |
5061 | } | 5087 | } |
5062 | if (willUseProxy_App(scheme) || isGemini || | 5088 | if (isGemini || |
5089 | willUseProxy_App(scheme) || | ||
5090 | equalCase_Rangecc(scheme, "data") || | ||
5063 | equalCase_Rangecc(scheme, "file") || | 5091 | equalCase_Rangecc(scheme, "file") || |
5064 | equalCase_Rangecc(scheme, "finger") || | 5092 | equalCase_Rangecc(scheme, "finger") || |
5065 | equalCase_Rangecc(scheme, "gopher")) { | 5093 | equalCase_Rangecc(scheme, "gopher")) { |
5066 | isNative = iTrue; | 5094 | isNative = iTrue; |
5067 | /* Regular links that we can open. */ | 5095 | /* Regular links that we can open. */ |
5068 | pushBackN_Array( | 5096 | pushBackN_Array(&items, |
5069 | &items, | 5097 | (iMenuItem[]){ |
5070 | (iMenuItem[]){ { openTab_Icon " ${link.newtab}", | 5098 | { openTab_Icon " ${link.newtab}", |
5071 | 0, | 5099 | 0, |
5072 | 0, | 5100 | 0, |
5073 | format_CStr("!open newtab:1 origin:%s url:%s", | 5101 | format_CStr("!open newtab:1 origin:%s url:%s", |
5074 | cstr_String(id_Widget(w)), | 5102 | cstr_String(id_Widget(w)), |
5075 | cstr_String(linkUrl)) }, | 5103 | cstr_String(linkUrl)) }, |
5076 | { openTabBg_Icon " ${link.newtab.background}", | 5104 | { openTabBg_Icon " ${link.newtab.background}", |
5077 | 0, | 5105 | 0, |
5078 | 0, | 5106 | 0, |
5079 | format_CStr("!open newtab:2 origin:%s url:%s", | 5107 | format_CStr("!open newtab:2 origin:%s url:%s", |
5080 | cstr_String(id_Widget(w)), | 5108 | cstr_String(id_Widget(w)), |
5081 | cstr_String(linkUrl)) }, | 5109 | cstr_String(linkUrl)) }, |
5082 | { "${link.side}", | 5110 | { openWindow_Icon " ${link.newwindow}", |
5083 | 0, | 5111 | 0, |
5084 | 0, | 5112 | 0, |
5085 | format_CStr("!open newtab:4 origin:%s url:%s", | 5113 | format_CStr("!open newwindow:1 origin:%s url:%s", |
5086 | cstr_String(id_Widget(w)), | 5114 | cstr_String(id_Widget(w)), |
5087 | cstr_String(linkUrl)) }, | 5115 | cstr_String(linkUrl)) }, |
5088 | { "${link.side.newtab}", | 5116 | { "${link.side}", |
5089 | 0, | 5117 | 0, |
5090 | 0, | 5118 | 0, |
5091 | format_CStr("!open newtab:5 origin:%s url:%s", | 5119 | format_CStr("!open newtab:4 origin:%s url:%s", |
5092 | cstr_String(id_Widget(w)), | 5120 | cstr_String(id_Widget(w)), |
5093 | cstr_String(linkUrl)) } }, | 5121 | cstr_String(linkUrl)) }, |
5094 | 4); | 5122 | { "${link.side.newtab}", |
5123 | 0, | ||
5124 | 0, | ||
5125 | format_CStr("!open newtab:5 origin:%s url:%s", | ||
5126 | cstr_String(id_Widget(w)), | ||
5127 | cstr_String(linkUrl)) }, | ||
5128 | }, | ||
5129 | 5); | ||
5095 | if (deviceType_App() == phone_AppDeviceType) { | 5130 | if (deviceType_App() == phone_AppDeviceType) { |
5096 | removeN_Array(&items, size_Array(&items) - 2, iInvalidSize); | 5131 | /* Phones don't do windows or splits. */ |
5132 | removeN_Array(&items, size_Array(&items) - 3, iInvalidSize); | ||
5133 | } | ||
5134 | else if (deviceType_App() == tablet_AppDeviceType) { | ||
5135 | /* Tablets only do splits. */ | ||
5136 | removeN_Array(&items, size_Array(&items) - 3, 1); | ||
5097 | } | 5137 | } |
5098 | if (equalCase_Rangecc(scheme, "file")) { | 5138 | if (equalCase_Rangecc(scheme, "file")) { |
5099 | pushBack_Array(&items, &(iMenuItem){ "---" }); | 5139 | pushBack_Array(&items, &(iMenuItem){ "---" }); |
@@ -5248,6 +5288,11 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
5248 | "document.upload", | 5288 | "document.upload", |
5249 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "gemini") && | 5289 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "gemini") && |
5250 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "titan")); | 5290 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "titan")); |
5291 | setMenuItemDisabled_Widget( | ||
5292 | d->menu, | ||
5293 | "document.upload copy:1", | ||
5294 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "gemini") && | ||
5295 | !equalCase_Rangecc(urlScheme_String(d->mod.url), "titan")); | ||
5251 | } | 5296 | } |
5252 | processContextMenuEvent_Widget(d->menu, ev, {}); | 5297 | processContextMenuEvent_Widget(d->menu, ev, {}); |
5253 | } | 5298 | } |
@@ -5545,12 +5590,12 @@ static void prerender_DocumentWidget_(iAny *context) { | |||
5545 | } | 5590 | } |
5546 | const iDocumentWidget *d = context; | 5591 | const iDocumentWidget *d = context; |
5547 | iDrawContext ctx = { | 5592 | iDrawContext ctx = { |
5548 | .view = &d->view, | 5593 | .view = &d->view, |
5549 | .docBounds = documentBounds_DocumentView_(&d->view), | 5594 | .docBounds = documentBounds_DocumentView_(&d->view), |
5550 | .vis = visibleRange_DocumentView_(&d->view), | 5595 | .vis = visibleRange_DocumentView_(&d->view), |
5551 | .showLinkNumbers = (d->flags & showLinkNumbers_DocumentWidgetFlag) != 0 | 5596 | .showLinkNumbers = (d->flags & showLinkNumbers_DocumentWidgetFlag) != 0 |
5552 | }; | 5597 | }; |
5553 | // printf("%u prerendering\n", SDL_GetTicks()); | 5598 | // printf("%u prerendering\n", SDL_GetTicks()); |
5554 | if (d->view.visBuf->buffers[0].texture) { | 5599 | if (d->view.visBuf->buffers[0].texture) { |
5555 | makePaletteGlobal_GmDocument(d->view.doc); | 5600 | makePaletteGlobal_GmDocument(d->view.doc); |
5556 | if (render_DocumentView_(&d->view, &ctx, iTrue /* just fill up progressively */)) { | 5601 | if (render_DocumentView_(&d->view, &ctx, iTrue /* just fill up progressively */)) { |