summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/about/version.gmi3
-rw-r--r--src/app.c16
-rw-r--r--src/gmrequest.c6
-rw-r--r--src/gmutil.c36
-rw-r--r--src/gmutil.h2
-rw-r--r--src/prefs.c1
-rw-r--r--src/prefs.h1
-rw-r--r--src/ui/sidebarwidget.c9
-rw-r--r--src/ui/util.c4
9 files changed, 73 insertions, 5 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index 50ade298..42475e13 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -8,6 +8,9 @@
8 8
9## 0.13 9## 0.13
10* Support for Internationalized Domain Names (IDN) in network requests. 10* Support for Internationalized Domain Names (IDN) in network requests.
11* IDNs show up in decoded form in the UI.
12* Percent-encoded Unicode characters in URL paths are decoded for the UI, and encoded in outgoing requests.
13* Added option to disable decoding of percent-encoded paths.
11* Quick search via URL bar shows entries from subscribed feeds. 14* Quick search via URL bar shows entries from subscribed feeds.
12* Added keybindings for zooming. 15* Added keybindings for zooming.
13* Improved usability of page content searching (${CTRL+}F, Escape). 16* Improved usability of page content searching (${CTRL+}F, Escape).
diff --git a/src/app.c b/src/app.c
index 8a6b2a66..ae21d078 100644
--- a/src/app.c
+++ b/src/app.c
@@ -188,6 +188,7 @@ static iString *serializePrefs_App_(const iApp *d) {
188 appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent); 188 appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent);
189 appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling); 189 appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling);
190 appendFormat_String(str, "imageloadscroll arg:%d\n", d->prefs.loadImageInsteadOfScrolling); 190 appendFormat_String(str, "imageloadscroll arg:%d\n", d->prefs.loadImageInsteadOfScrolling);
191 appendFormat_String(str, "decodeurls arg:%d\n", d->prefs.decodeUserVisibleURLs);
191 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); 192 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth);
192 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); 193 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph);
193 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon); 194 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon);
@@ -836,6 +837,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
836 isSelected_Widget(findChild_Widget(d, "prefs.imageloadscroll"))); 837 isSelected_Widget(findChild_Widget(d, "prefs.imageloadscroll")));
837 postCommandf_App("ostheme arg:%d", 838 postCommandf_App("ostheme arg:%d",
838 isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); 839 isSelected_Widget(findChild_Widget(d, "prefs.ostheme")));
840 postCommandf_App("decodeurls arg:%d",
841 isSelected_Widget(findChild_Widget(d, "prefs.decodeurls")));
839 postCommandf_App("proxy.gemini address:%s", 842 postCommandf_App("proxy.gemini address:%s",
840 cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.gemini")))); 843 cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.gemini"))));
841 postCommandf_App("proxy.gopher address:%s", 844 postCommandf_App("proxy.gopher address:%s",
@@ -1094,6 +1097,10 @@ iBool handleCommand_App(const char *cmd) {
1094 d->prefs.smoothScrolling = arg_Command(cmd); 1097 d->prefs.smoothScrolling = arg_Command(cmd);
1095 return iTrue; 1098 return iTrue;
1096 } 1099 }
1100 else if (equal_Command(cmd, "decodeurls")) {
1101 d->prefs.decodeUserVisibleURLs = arg_Command(cmd);
1102 return iTrue;
1103 }
1097 else if (equal_Command(cmd, "imageloadscroll")) { 1104 else if (equal_Command(cmd, "imageloadscroll")) {
1098 d->prefs.loadImageInsteadOfScrolling = arg_Command(cmd); 1105 d->prefs.loadImageInsteadOfScrolling = arg_Command(cmd);
1099 return iTrue; 1106 return iTrue;
@@ -1184,7 +1191,7 @@ iBool handleCommand_App(const char *cmd) {
1184 return iTrue; 1191 return iTrue;
1185 } 1192 }
1186 else if (equal_Command(cmd, "open")) { 1193 else if (equal_Command(cmd, "open")) {
1187 const iString *url = collectNewCStr_String(suffixPtr_Command(cmd, "url")); 1194 iString *url = collectNewCStr_String(suffixPtr_Command(cmd, "url"));
1188 const iBool noProxy = argLabel_Command(cmd, "noproxy"); 1195 const iBool noProxy = argLabel_Command(cmd, "noproxy");
1189 iUrl parts; 1196 iUrl parts;
1190 init_Url(&parts, url); 1197 init_Url(&parts, url);
@@ -1214,6 +1221,12 @@ iBool handleCommand_App(const char *cmd) {
1214 setInitialScroll_DocumentWidget(doc, argfLabel_Command(cmd, "scroll")); 1221 setInitialScroll_DocumentWidget(doc, argfLabel_Command(cmd, "scroll"));
1215 setRedirectCount_DocumentWidget(doc, redirectCount); 1222 setRedirectCount_DocumentWidget(doc, redirectCount);
1216 setFlags_Widget(findWidget_App("document.progress"), hidden_WidgetFlag, iTrue); 1223 setFlags_Widget(findWidget_App("document.progress"), hidden_WidgetFlag, iTrue);
1224 if (prefs_App()->decodeUserVisibleURLs) {
1225 urlDecodePath_String(url);
1226 }
1227 else {
1228 urlEncodePath_String(url);
1229 }
1217 setUrlFromCache_DocumentWidget(doc, url, isHistory); 1230 setUrlFromCache_DocumentWidget(doc, url, isHistory);
1218 /* Optionally, jump to a text in the document. This will only work if the document 1231 /* Optionally, jump to a text in the document. This will only work if the document
1219 is already available, e.g., it's from "about:" or restored from cache. */ 1232 is already available, e.g., it's from "about:" or restored from cache. */
@@ -1332,6 +1345,7 @@ iBool handleCommand_App(const char *cmd) {
1332 dlg, format_CStr("prefs.saturation.%d", (int) (d->prefs.saturation * 3.99f))), 1345 dlg, format_CStr("prefs.saturation.%d", (int) (d->prefs.saturation * 3.99f))),
1333 selected_WidgetFlag, 1346 selected_WidgetFlag,
1334 iTrue); 1347 iTrue);
1348 setToggle_Widget(findChild_Widget(dlg, "prefs.decodeurls"), d->prefs.decodeUserVisibleURLs);
1335 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gemini"), &d->prefs.geminiProxy); 1349 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gemini"), &d->prefs.geminiProxy);
1336 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), &d->prefs.gopherProxy); 1350 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), &d->prefs.gopherProxy);
1337 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"), &d->prefs.httpProxy); 1351 setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"), &d->prefs.httpProxy);
diff --git a/src/gmrequest.c b/src/gmrequest.c
index 991485bc..1f922142 100644
--- a/src/gmrequest.c
+++ b/src/gmrequest.c
@@ -482,8 +482,6 @@ void deinit_GmRequest(iGmRequest *d) {
482 deinit_Gopher(&d->gopher); 482 deinit_Gopher(&d->gopher);
483 delete_Audience(d->finished); 483 delete_Audience(d->finished);
484 delete_Audience(d->updated); 484 delete_Audience(d->updated);
485// delete_GmResponse(d->respPub);
486// deinit_GmResponse(&d->respInt);
487 delete_GmResponse(d->resp); 485 delete_GmResponse(d->resp);
488 deinit_String(&d->url); 486 deinit_String(&d->url);
489 delete_Mutex(d->mtx); 487 delete_Mutex(d->mtx);
@@ -494,6 +492,10 @@ void setUrl_GmRequest(iGmRequest *d, const iString *url) {
494 /* Encode hostname to Punycode here because we want to submit the Punycode domain name 492 /* Encode hostname to Punycode here because we want to submit the Punycode domain name
495 in the request. (TODO: Pending possible Gemini spec change.) */ 493 in the request. (TODO: Pending possible Gemini spec change.) */
496 punyEncodeUrlHost_String(&d->url); 494 punyEncodeUrlHost_String(&d->url);
495 /* TODO: Gemini spec allows UTF-8 encoded URLs, but still need to percent-encode non-ASCII
496 characters? Could be a server-side issue, e.g., if they're using a URL parser meant for
497 the web. */
498 urlEncodePath_String(&d->url);
497 urlEncodeSpaces_String(&d->url); 499 urlEncodeSpaces_String(&d->url);
498} 500}
499 501
diff --git a/src/gmutil.c b/src/gmutil.c
index 68525be9..afca4978 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -151,6 +151,42 @@ static iString *punyDecodeHost_(iRangecc host) {
151 return result; 151 return result;
152} 152}
153 153
154void urlDecodePath_String(iString *d) {
155 iUrl url;
156 init_Url(&url, d);
157 if (isEmpty_Range(&url.path)) {
158 return;
159 }
160 iString *decoded = new_String();
161 appendRange_String(decoded, (iRangecc){ constBegin_String(d), url.path.start });
162 iString *path = newRange_String(url.path);
163 iString *decPath = urlDecode_String(path);
164 append_String(decoded, decPath);
165 delete_String(decPath);
166 delete_String(path);
167 appendRange_String(decoded, (iRangecc){ url.path.end, constEnd_String(d) });
168 set_String(d, decoded);
169 delete_String(decoded);
170}
171
172void urlEncodePath_String(iString *d) {
173 iUrl url;
174 init_Url(&url, d);
175 if (isEmpty_Range(&url.path)) {
176 return;
177 }
178 iString *encoded = new_String();
179 appendRange_String(encoded , (iRangecc){ constBegin_String(d), url.path.start });
180 iString *path = newRange_String(url.path);
181 iString *encPath = urlEncodeExclude_String(path, "%/ ");
182 append_String(encoded, encPath);
183 delete_String(encPath);
184 delete_String(path);
185 appendRange_String(encoded, (iRangecc){ url.path.end, constEnd_String(d) });
186 set_String(d, encoded);
187 delete_String(encoded);
188}
189
154const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { 190const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) {
155 iUrl orig; 191 iUrl orig;
156 iUrl rel; 192 iUrl rel;
diff --git a/src/gmutil.h b/src/gmutil.h
index bbadbafd..88ed1f32 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -104,6 +104,8 @@ iRangecc urlScheme_String (const iString *);
104iRangecc urlHost_String (const iString *); 104iRangecc urlHost_String (const iString *);
105const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); 105const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative);
106void punyEncodeUrlHost_String(iString *); 106void punyEncodeUrlHost_String(iString *);
107void urlDecodePath_String (iString *);
108void urlEncodePath_String (iString *);
107iString * makeFileUrl_String (const iString *localFilePath); 109iString * makeFileUrl_String (const iString *localFilePath);
108const char * makeFileUrl_CStr (const char *localFilePath); 110const char * makeFileUrl_CStr (const char *localFilePath);
109void urlEncodeSpaces_String (iString *); 111void urlEncodeSpaces_String (iString *);
diff --git a/src/prefs.c b/src/prefs.c
index 574e07d0..31ffe03b 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -33,6 +33,7 @@ void init_Prefs(iPrefs *d) {
33 d->hoverOutline = iFalse; 33 d->hoverOutline = iFalse;
34 d->smoothScrolling = iTrue; 34 d->smoothScrolling = iTrue;
35 d->loadImageInsteadOfScrolling = iFalse; 35 d->loadImageInsteadOfScrolling = iFalse;
36 d->decodeUserVisibleURLs = iTrue;
36 d->font = nunito_TextFont; 37 d->font = nunito_TextFont;
37 d->headingFont = nunito_TextFont; 38 d->headingFont = nunito_TextFont;
38 d->monospaceGemini = iFalse; 39 d->monospaceGemini = iFalse;
diff --git a/src/prefs.h b/src/prefs.h
index 3f4f534f..e95a32da 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -48,6 +48,7 @@ struct Impl_Prefs {
48 iBool smoothScrolling; 48 iBool smoothScrolling;
49 iBool loadImageInsteadOfScrolling; 49 iBool loadImageInsteadOfScrolling;
50 /* Network */ 50 /* Network */
51 iBool decodeUserVisibleURLs;
51 iString geminiProxy; 52 iString geminiProxy;
52 iString gopherProxy; 53 iString gopherProxy;
53 iString httpProxy; 54 iString httpProxy;
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 8024b240..1167ebe3 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -240,6 +240,13 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) {
240 const iVisitedUrl *visit = i.ptr; 240 const iVisitedUrl *visit = i.ptr;
241 iSidebarItem *item = new_SidebarItem(); 241 iSidebarItem *item = new_SidebarItem();
242 set_String(&item->url, &visit->url); 242 set_String(&item->url, &visit->url);
243 set_String(&item->label, &visit->url);
244 if (prefs_App()->decodeUserVisibleURLs) {
245 urlDecodePath_String(&item->label);
246 }
247 else {
248 urlEncodePath_String(&item->label);
249 }
243 iDate date; 250 iDate date;
244 init_Date(&date, &visit->when); 251 init_Date(&date, &visit->when);
245 if (date.day != on.day || date.month != on.month || date.year != on.year) { 252 if (date.day != on.day || date.month != on.month || date.year != on.year) {
@@ -1211,7 +1218,7 @@ static void draw_SidebarItem_(const iSidebarItem *d, iPaint *p, iRect itemRect,
1211 } 1218 }
1212 else { 1219 else {
1213 iUrl parts; 1220 iUrl parts;
1214 init_Url(&parts, &d->url); 1221 init_Url(&parts, &d->label);
1215 const iBool isAbout = equalCase_Rangecc(parts.scheme, "about"); 1222 const iBool isAbout = equalCase_Rangecc(parts.scheme, "about");
1216 const iBool isGemini = equalCase_Rangecc(parts.scheme, "gemini"); 1223 const iBool isGemini = equalCase_Rangecc(parts.scheme, "gemini");
1217 draw_Text(font, 1224 draw_Text(font,
diff --git a/src/ui/util.c b/src/ui/util.c
index 1ad3f30e..6c9d75dc 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1136,7 +1136,9 @@ iWidget *makePreferences_Widget(void) {
1136 addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede"))); 1136 addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede")));
1137 } 1137 }
1138 /* Proxies. */ { 1138 /* Proxies. */ {
1139 appendTwoColumnPage_(tabs, "Proxies", '5', &headings, &values); 1139 appendTwoColumnPage_(tabs, "Network", '5', &headings, &values);
1140 addChild_Widget(headings, iClob(makeHeading_Widget("Decode paths:")));
1141 addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls")));
1140 addChild_Widget(headings, iClob(makeHeading_Widget("Gemini proxy:"))); 1142 addChild_Widget(headings, iClob(makeHeading_Widget("Gemini proxy:")));
1141 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini"); 1143 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini");
1142 addChild_Widget(headings, iClob(makeHeading_Widget("Gopher proxy:"))); 1144 addChild_Widget(headings, iClob(makeHeading_Widget("Gopher proxy:")));