diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-02 18:19:30 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-02 18:19:30 +0200 |
commit | a4bfb9306343a0801a85cafb20896e2476b31d5c (patch) | |
tree | 6f8c964ecf645ee4b1a92c069b4a110a560be6ed | |
parent | 5dac1beb7bd29604142988961d69ac2c17be1f86 (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
-rw-r--r-- | src/gmrequest.c | 2 | ||||
-rw-r--r-- | src/gmutil.c | 13 | ||||
-rw-r--r-- | src/gmutil.h | 1 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 2 |
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 | ||
495 | void setUrl_GmRequest(iGmRequest *d, const iString *url) { | 495 | void 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 | ||
94 | const iString *urlFragmentStripped_String(const iString *d) { | 95 | const 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 | ||
101 | void init_Url (iUrl *, const iString *text); | 102 | void 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 | ||
3346 | void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { | 3346 | void 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)) { |