summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c135
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);
358static void prerender_DocumentWidget_ (iAny *); 358static void prerender_DocumentWidget_ (iAny *);
359static void scrollBegan_DocumentWidget_ (iAnyObject *, int, uint32_t); 359static void scrollBegan_DocumentWidget_ (iAnyObject *, int, uint32_t);
360static void refreshWhileScrolling_DocumentWidget_ (iAny *); 360static void refreshWhileScrolling_DocumentWidget_ (iAny *);
361static 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
2411static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool isCached) { 2412static 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 */)) {