From b20be8d7f701f364d7199a494c25c2694e40864d Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Wed, 4 Nov 2020 16:04:50 +0200 Subject: Windows: Improvements to file URL/path handling IssueID #23 --- src/app.c | 13 +++++++------ src/gmutil.c | 26 +++++++++++++++++++++++--- src/gmutil.h | 1 + 3 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/app.c b/src/app.c index 8c14c6e6..d6cd34a8 100644 --- a/src/app.c +++ b/src/app.c @@ -362,7 +362,7 @@ static void init_App_(iApp *d, int argc, char **argv) { loadPrefs_App_(d); load_Keys(dataDir_App_); load_Visited(d->visited, dataDir_App_); - load_Bookmarks(d->bookmarks, dataDir_App_); + load_Bookmarks(d->bookmarks, dataDir_App_); if (isFirstRun) { /* Create the default bookmarks for a quick start. */ add_Bookmarks(d->bookmarks, @@ -417,10 +417,10 @@ static void init_App_(iApp *d, int argc, char **argv) { startsWithCase_String(arg, "gemini:") || startsWithCase_String(arg, "file:") || startsWithCase_String(arg, "data:") || startsWithCase_String(arg, "about:"); if (isKnownScheme || fileExists_FileInfo(arg)) { - postCommandf_App("open newtab:%d url:%s%s", + postCommandf_App("open newtab:%d url:%s", newTab, - isKnownScheme ? "" : "file://", - cstr_String(arg)); + isKnownScheme ? cstr_String(arg) + : cstrCollect_String(makeFileUrl_String(arg))); newTab = iTrue; } } @@ -501,7 +501,8 @@ void processEvents_App(enum iAppEventMode eventMode) { postCommandf_App("~open newtab:%d url:%s", newTab, ev.drop.file); } else { - postCommandf_App("~open newtab:%d url:file://%s", newTab, ev.drop.file); + postCommandf_App( + "~open newtab:%d url:%s", newTab, makeFileUrl_CStr(ev.drop.file)); } break; } @@ -908,7 +909,7 @@ iBool handleCommand_App(const char *cmd) { postCommand_App("font.changed"); postCommand_App("window.unfreeze"); return iTrue; - } + } else if (equal_Command(cmd, "zoom.set")) { setFreezeDraw_Window(get_Window(), iTrue); /* no intermediate draws before docs updated */ d->prefs.zoomPercent = arg_Command(cmd); diff --git a/src/gmutil.c b/src/gmutil.c index 4b144097..52fe6b28 100644 --- a/src/gmutil.c +++ b/src/gmutil.c @@ -27,6 +27,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include void init_Url(iUrl *d, const iString *text) { + /* Handle "file:" as a special case since it only has the path part. */ + if (startsWithCase_String(text, "file://")) { + iZap(*d); + const char *cstr = constBegin_String(text); + d->scheme = (iRangecc){ cstr, cstr + 4 }; + d->path = (iRangecc){ cstr + 7, constEnd_String(text) }; + return; + } static iRegExp *absoluteUrlPattern_; static iRegExp *relativeUrlPattern_; if (!absoluteUrlPattern_) { @@ -98,8 +106,11 @@ void cleanUrlPath_String(iString *d) { else if (equal_Rangecc(seg, ".")) { /* Skip it. */ } - else { - appendCStr_String(&clean, "/"); + else if (!isEmpty_Range(&seg)) { + /* Ensure the cleaned path starts with a slash if the original does. */ + if (!isEmpty_String(&clean) || startsWith_Rangecc(parts.path, "/")) { + appendCStr_String(&clean, "/"); + } appendRange_String(&clean, seg); } } @@ -127,6 +138,10 @@ iRangecc urlHost_String(const iString *d) { return url.host; } +static iBool isAbsolutePath_(iRangecc path) { + return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); +} + const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) { iUrl orig; iUrl rel; @@ -155,7 +170,7 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat appendRange_String(absolute, selHost->port); } } - if (isDef_(rel.scheme) || isDef_(rel.host) || startsWith_Rangecc(rel.path, "/")) { + if (isDef_(rel.scheme) || isDef_(rel.host) || isAbsolutePath_(rel.path)) { appendRange_String(absolute, isDef_(rel.path) ? rel.path : range_CStr("/")); /* absolute path */ } else { @@ -180,10 +195,15 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat iString *makeFileUrl_String(const iString *localFilePath) { iString *url = cleaned_Path(localFilePath); replace_Block(&url->chars, '\\', '/'); /* in case it's a Windows path */ + set_String(url, collect_String(urlEncodeExclude_String(url, "/"))); prependCStr_String(url, "file://"); return url; } +const char *makeFileUrl_CStr(const char *localFilePath) { + return cstrCollect_String(makeFileUrl_String(collectNewCStr_String(localFilePath))); +} + void urlEncodeSpaces_String(iString *d) { for (;;) { const size_t pos = indexOfCStr_String(d, " "); diff --git a/src/gmutil.h b/src/gmutil.h index 8b4f7033..97c2d675 100644 --- a/src/gmutil.h +++ b/src/gmutil.h @@ -103,4 +103,5 @@ iRangecc urlScheme_String (const iString *); iRangecc urlHost_String (const iString *); const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); iString * makeFileUrl_String (const iString *localFilePath); +const char * makeFileUrl_CStr (const char *localFilePath); void urlEncodeSpaces_String (iString *); -- cgit v1.2.3