From 07804493ac17ff430302c7940f44b7525c0620e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= jaakko.keranen@iki.fi
Date: Sat, 29 Jan 2022 18:00:01 +0200
Subject: [PATCH 1/1] Hierarchical navigation with Gopher and Titan
With Gopher, ensure that the item type changes to 1, and with Titan, change to normal Gemini.
res/about/version.gmi | 2 ++
src/gmutil.c | 21 +++++++++++++++++++++
src/gmutil.h | 2 ++
src/gopher.c | 10 ++++++++++
src/gopher.h | 2 ++
src/ui/documentwidget.c | 28 ++++++++++++++++++++--------
6 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/res/about/version.gmi b/res/about/version.gmi
index a0cbe637..df532ab3 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -9,6 +9,8 @@
+* Gopher: Fixed navigating to root, e.g., when clicking on the page top banner. Set item type to 1 to show a gophermap and not the plain source.
+* Titan: When navigating to parent/root, switch URL scheme to "gemini". This action occurs on a Titan response page, so initiating a new upload with the parent/root URL is probably not appropriate.
diff --git a/src/gmutil.c b/src/gmutil.c
index 98e4d4d6..b984950e 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -131,6 +131,16 @@ static iRangecc prevPathSeg_(const char *end, const char *start) {
return seg;
}
+void stripUrlPort_String(iString *d) {
/* Always preceded by a colon. */
remove_Block(&d->chars, parts.port.start - 1 - constBegin_String(d),
size_Range(&parts.port) + 1);
+}
void stripDefaultUrlPort_String(iString *d) {
iUrl parts;
init_Url(&parts, d);
@@ -681,6 +691,17 @@ const iString *withSpacesEncoded_String(const iString *d) {
return d;
}
+const iString *withScheme_String(const iString *d, const char *scheme) {
iString *repl = collectNewCStr_String(scheme);
appendRange_String(repl, (iRangecc){ parts.scheme.end, constEnd_String(d) });
return repl;
+}
const iString *canonicalUrl_String(const iString *d) {
/* The "canonical" form, used for internal storage and comparisons, is:
- all non-reserved characters decoded (i.e., it's an IRI)
diff --git a/src/gmutil.h b/src/gmutil.h
index 15bb7b2e..1594afc4 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -127,6 +127,7 @@ iBool isKnownScheme_Rangecc (iRangecc scheme); /* any URI scheme */
iBool isKnownUrlScheme_Rangecc(iRangecc scheme); /* URL schemes only */
void punyEncodeDomain_Rangecc(iRangecc domain, iString *encoded_out);
void punyEncodeUrlHost_String(iString *absoluteUrl);
+void stripUrlPort_String (iString *);
void stripDefaultUrlPort_String(iString *);
const iString * urlFragmentStripped_String(const iString *);
const iString * urlQueryStripped_String (const iString *);
@@ -138,6 +139,7 @@ const char * makeFileUrl_CStr (const char *localFilePath);
iString * localFilePathFromUrl_String(const iString *);
void urlEncodeSpaces_String (iString *);
const iString * withSpacesEncoded_String(const iString *);
+const iString * withScheme_String (const iString *, const char scheme); / replace URI scheme */
const iString * canonicalUrl_String (const iString *);
const char * mediaType_Path (const iString *path);
diff --git a/src/gopher.c b/src/gopher.c
index 008a7743..0e34fe6a 100644
--- a/src/gopher.c
+++ b/src/gopher.c
@@ -299,3 +299,13 @@ iBool processResponse_Gopher(iGopher *d, const iBlock *data) {
}
return changed;
}
+void setUrlItemType_Gopher(iString *url, char itemType) {
if (parts.path.start && size_Range(&parts.path) >= 2) {
((char *) parts.path.start)[1] = itemType;
}
+}
diff --git a/src/gopher.h b/src/gopher.h
index 3ad7e374..3cad0c21 100644
--- a/src/gopher.h
+++ b/src/gopher.h
@@ -44,3 +44,5 @@ iDeclareTypeConstruction(Gopher)
void open_Gopher (iGopher *, const iString *url);
iBool processResponse_Gopher (iGopher *, const iBlock *data);
void cancel_Gopher (iGopher *);
+void setUrlItemType_Gopher (iString *url, char itemType);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 2e15cdce..86513368 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "gmdocument.h"
#include "gmrequest.h"
#include "gmutil.h"
+#include "gopher.h"
#include "history.h"
#include "indicatorwidget.h"
#include "inputwidget.h"
@@ -4315,20 +4316,31 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
}
iString *parentUrl = collectNewRange_String((iRangecc){ constBegin_String(d->mod.url),
parts.path.end });
if (equalCase_Rangecc(parts.scheme, "gopher")) {
/* Always go to a gophermap. */
iZap(parts);
init_Url(&parts, parentUrl);
if (parts.path.start && size_Range(&parts.path) >= 2) {
((char *) parts.path.start)[1] = '1';
}
/* Always go to a gophermap. */
setUrlItemType_Gopher(parentUrl, '1');
/* Hierarchical navigation doesn't make sense with Titan. */
if (startsWith_String(parentUrl, "titan://")) {
/* We have no way of knowing if the corresponding URL is valid for Gemini,
but let's try anyway. */
set_String(parentUrl, withScheme_String(parentUrl, "gemini"));
stripUrlPort_String(parentUrl);
}
postCommandf_Root(w->root, "open url:%s", cstr_String(parentUrl));
}
return iTrue;
}
else if (equal_Command(cmd, "navigate.root") && document_App() == d) {
postCommandf_Root(w->root, "open url:%s/", cstr_Rangecc(urlRoot_String(d->mod.url)));
iString *rootUrl = collectNewRange_String(urlRoot_String(d->mod.url));
/* Always go to a gophermap. */
setUrlItemType_Gopher(rootUrl, '1');
/* Hierarchical navigation doesn't make sense with Titan. */
if (startsWith_String(rootUrl, "titan://")) {
/* We have no way of knowing if the corresponding URL is valid for Gemini,
but let's try anyway. */
set_String(rootUrl, withScheme_String(rootUrl, "gemini"));
stripUrlPort_String(rootUrl);
}
postCommandf_Root(w->root, "open url:%s/", cstr_String(rootUrl));
return iTrue;
}
else if (equalWidget_Command(cmd, w, "scroll.moved")) {
--
2.25.1
text/plain
This content has been proxied by September (ba2dc).