summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-02 18:19:30 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-02 18:19:30 +0200
commita4bfb9306343a0801a85cafb20896e2476b31d5c (patch)
tree6f8c964ecf645ee4b1a92c069b4a110a560be6ed /src
parent5dac1beb7bd29604142988961d69ac2c17be1f86 (diff)
Stripping the URL fragment
Lagrange will retain URL fragments when parsing gemtext, but will strip them when making requests or when a DocumentWidget's URL is set. This allows opening URLs with fragments in an external browser. IssueID #128
Diffstat (limited to 'src')
-rw-r--r--src/gmrequest.c2
-rw-r--r--src/gmutil.c13
-rw-r--r--src/gmutil.h1
-rw-r--r--src/ui/documentwidget.c2
4 files changed, 11 insertions, 7 deletions
diff --git a/src/gmrequest.c b/src/gmrequest.c
index a1cf1a8e..8626403f 100644
--- a/src/gmrequest.c
+++ b/src/gmrequest.c
@@ -493,7 +493,7 @@ void deinit_GmRequest(iGmRequest *d) {
493} 493}
494 494
495void setUrl_GmRequest(iGmRequest *d, const iString *url) { 495void setUrl_GmRequest(iGmRequest *d, const iString *url) {
496 set_String(&d->url, url); 496 set_String(&d->url, urlFragmentStripped_String(url));
497 /* Encode hostname to Punycode here because we want to submit the Punycode domain name 497 /* Encode hostname to Punycode here because we want to submit the Punycode domain name
498 in the request. (TODO: Pending possible Gemini spec change.) */ 498 in the request. (TODO: Pending possible Gemini spec change.) */
499 punyEncodeUrlHost_String(&d->url); 499 punyEncodeUrlHost_String(&d->url);
diff --git a/src/gmutil.c b/src/gmutil.c
index 0f1bc803..72074278 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -49,11 +49,12 @@ void init_Url(iUrl *d, const iString *text) {
49 iRegExpMatch m; 49 iRegExpMatch m;
50 init_RegExpMatch(&m); 50 init_RegExpMatch(&m);
51 if (matchString_RegExp(urlPattern_, text, &m)) { 51 if (matchString_RegExp(urlPattern_, text, &m)) {
52 d->scheme = capturedRange_RegExpMatch(&m, 2); 52 d->scheme = capturedRange_RegExpMatch(&m, 2);
53 d->host = capturedRange_RegExpMatch(&m, 4); 53 d->host = capturedRange_RegExpMatch(&m, 4);
54 d->port = (iRangecc){ d->host.end, d->host.end }; 54 d->port = (iRangecc){ d->host.end, d->host.end };
55 d->path = capturedRange_RegExpMatch(&m, 5); 55 d->path = capturedRange_RegExpMatch(&m, 5);
56 d->query = capturedRange_RegExpMatch(&m, 6); 56 d->query = capturedRange_RegExpMatch(&m, 6);
57 d->fragment = capturedRange_RegExpMatch(&m, 8); /* starts with a hash */
57 /* Check if the authority contains a port. */ 58 /* Check if the authority contains a port. */
58 init_RegExpMatch(&m); 59 init_RegExpMatch(&m);
59 if (matchRange_RegExp(authPattern_, d->host, &m)) { 60 if (matchRange_RegExp(authPattern_, d->host, &m)) {
@@ -92,6 +93,7 @@ void stripDefaultUrlPort_String(iString *d) {
92} 93}
93 94
94const iString *urlFragmentStripped_String(const iString *d) { 95const iString *urlFragmentStripped_String(const iString *d) {
96 /* Note: Could use `iUrl` here and leave out the fragment. */
95 const size_t fragPos = indexOf_String(d, '#'); 97 const size_t fragPos = indexOf_String(d, '#');
96 if (fragPos != iInvalidPos) { 98 if (fragPos != iInvalidPos) {
97 return collect_String(newRange_String((iRangecc){ constBegin_String(d), 99 return collect_String(newRange_String((iRangecc){ constBegin_String(d),
@@ -264,6 +266,7 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat
264 appendRange_String(absolute, orig.path); 266 appendRange_String(absolute, orig.path);
265 } 267 }
266 appendRange_String(absolute, rel.query); 268 appendRange_String(absolute, rel.query);
269 appendRange_String(absolute, rel.fragment);
267 normalize_String(absolute); 270 normalize_String(absolute);
268 cleanUrlPath_String(absolute); 271 cleanUrlPath_String(absolute);
269 return absolute; 272 return absolute;
diff --git a/src/gmutil.h b/src/gmutil.h
index 3fd1268d..1caf2445 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -96,6 +96,7 @@ struct Impl_Url {
96 iRangecc port; 96 iRangecc port;
97 iRangecc path; 97 iRangecc path;
98 iRangecc query; 98 iRangecc query;
99 iRangecc fragment;
99}; 100};
100 101
101void init_Url (iUrl *, const iString *text); 102void init_Url (iUrl *, const iString *text);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 7fffc214..79a77f61 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -3345,7 +3345,7 @@ void deserializeState_DocumentWidget(iDocumentWidget *d, iStream *ins) {
3345 3345
3346void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { 3346void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) {
3347 d->flags &= ~showLinkNumbers_DocumentWidgetFlag; 3347 d->flags &= ~showLinkNumbers_DocumentWidgetFlag;
3348 set_String(d->mod.url, url); 3348 set_String(d->mod.url, urlFragmentStripped_String(url));
3349 /* See if there a username in the URL. */ 3349 /* See if there a username in the URL. */
3350 parseUser_DocumentWidget_(d); 3350 parseUser_DocumentWidget_(d);
3351 if (!isFromCache || !updateFromHistory_DocumentWidget_(d)) { 3351 if (!isFromCache || !updateFromHistory_DocumentWidget_(d)) {