summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-29 20:08:27 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-29 20:08:27 +0300
commitb49f40e2e2a54db326d28a4cf4c9257f831cf782 (patch)
tree3cad6698b69773171d338c6dc6c6163ae5a97077 /src
parentd9c45cc1d143ce806a28502c31e8ec0eace09d97 (diff)
Utility for making absolute URLs
Diffstat (limited to 'src')
-rw-r--r--src/gmutil.c53
-rw-r--r--src/gmutil.h5
-rw-r--r--src/ui/documentwidget.c61
3 files changed, 60 insertions, 59 deletions
diff --git a/src/gmutil.c b/src/gmutil.c
index 1a8d469f..af090574 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -32,6 +32,59 @@ void init_Url(iUrl *d, const iString *text) {
32 iRelease(absPat); 32 iRelease(absPat);
33} 33}
34 34
35static iRangecc dirPath_(iRangecc path) {
36 const size_t pos = lastIndexOfCStr_Rangecc(&path, "/");
37 if (pos == iInvalidPos) return path;
38 return (iRangecc){ path.start, path.start + pos };
39}
40
41const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelative) {
42 if (indexOfCStr_String(urlMaybeRelative, "://") != iInvalidPos) {
43 /* Already absolute. */
44 return urlMaybeRelative;
45 }
46 iUrl parts;
47 init_Url(&parts, d);
48 iString *absolute = new_String();
49 appendRange_String(absolute, parts.protocol);
50 appendCStr_String(absolute, "://");
51 appendRange_String(absolute, parts.host);
52 if (!isEmpty_Range(&parts.port)) {
53 appendCStr_String(absolute, ":");
54 appendRange_String(absolute, parts.port);
55 }
56 if (startsWith_String(urlMaybeRelative, "/")) {
57 append_String(absolute, urlMaybeRelative);
58 }
59 else {
60 iRangecc relPath = range_String(urlMaybeRelative);
61 iRangecc dir = dirPath_(parts.path);
62 for (;;) {
63 if (equal_Rangecc(&relPath, ".")) {
64 relPath.start++;
65 }
66 else if (startsWith_Rangecc(&relPath, "./")) {
67 relPath.start += 2;
68 }
69 else if (equal_Rangecc(&relPath, "..")) {
70 relPath.start += 2;
71 dir = dirPath_(dir);
72 }
73 else if (startsWith_Rangecc(&relPath, "../")) {
74 relPath.start += 3;
75 dir = dirPath_(dir);
76 }
77 else break;
78 }
79 appendRange_String(absolute, dir);
80 if (!endsWith_String(absolute, "/")) {
81 appendCStr_String(absolute, "/");
82 }
83 appendRange_String(absolute, relPath);
84 }
85 return collect_String(absolute);
86}
87
35void urlEncodeSpaces_String(iString *d) { 88void urlEncodeSpaces_String(iString *d) {
36 for (;;) { 89 for (;;) {
37 const size_t pos = indexOfCStr_String(d, " "); 90 const size_t pos = indexOfCStr_String(d, " ");
diff --git a/src/gmutil.h b/src/gmutil.h
index 41711af7..4a1fdee9 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -13,6 +13,7 @@ struct Impl_Url {
13 iRangecc query; 13 iRangecc query;
14}; 14};
15 15
16void init_Url (iUrl *, const iString *text); 16void init_Url (iUrl *, const iString *text);
17 17
18void urlEncodeSpaces_String (iString *); 18const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative);
19void urlEncodeSpaces_String (iString *);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 52628143..07761aa7 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -409,59 +409,6 @@ static void scrollTo_DocumentWidget_(iDocumentWidget *d, int documentY) {
409 scroll_DocumentWidget_(d, 0); /* clamp it */ 409 scroll_DocumentWidget_(d, 0); /* clamp it */
410} 410}
411 411
412static iRangecc dirPath_(iRangecc path) {
413 const size_t pos = lastIndexOfCStr_Rangecc(&path, "/");
414 if (pos == iInvalidPos) return path;
415 return (iRangecc){ path.start, path.start + pos };
416}
417
418static const iString *absoluteUrl_DocumentWidget_(const iDocumentWidget *d, const iString *url) {
419 if (indexOfCStr_String(url, "://") != iInvalidPos) {
420 /* Already absolute. */
421 return url;
422 }
423 iUrl parts;
424 init_Url(&parts, d->url);
425 iString *absolute = new_String();
426 appendRange_String(absolute, parts.protocol);
427 appendCStr_String(absolute, "://");
428 appendRange_String(absolute, parts.host);
429 if (!isEmpty_Range(&parts.port)) {
430 appendCStr_String(absolute, ":");
431 appendRange_String(absolute, parts.port);
432 }
433 if (startsWith_String(url, "/")) {
434 append_String(absolute, url);
435 }
436 else {
437 iRangecc relPath = range_String(url);
438 iRangecc dir = dirPath_(parts.path);
439 for (;;) {
440 if (equal_Rangecc(&relPath, ".")) {
441 relPath.start++;
442 }
443 else if (startsWith_Rangecc(&relPath, "./")) {
444 relPath.start += 2;
445 }
446 else if (equal_Rangecc(&relPath, "..")) {
447 relPath.start += 2;
448 dir = dirPath_(dir);
449 }
450 else if (startsWith_Rangecc(&relPath, "../")) {
451 relPath.start += 3;
452 dir = dirPath_(dir);
453 }
454 else break;
455 }
456 appendRange_String(absolute, dir);
457 if (!endsWith_String(absolute, "/")) {
458 appendCStr_String(absolute, "/");
459 }
460 appendRange_String(absolute, relPath);
461 }
462 return collect_String(absolute);
463}
464
465static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) { 412static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) {
466 if (!d->request) { 413 if (!d->request) {
467 return; 414 return;
@@ -542,7 +489,7 @@ static iBool requestMedia_DocumentWidget_(iDocumentWidget *d, iGmLinkId linkId)
542 pushBack_ObjectList( 489 pushBack_ObjectList(
543 d->media, 490 d->media,
544 iClob(new_MediaRequest( 491 iClob(new_MediaRequest(
545 d, linkId, absoluteUrl_DocumentWidget_(d, linkUrl_GmDocument(d->doc, linkId))))); 492 d, linkId, absoluteUrl_String(d->url, linkUrl_GmDocument(d->doc, linkId)))));
546 return iTrue; 493 return iTrue;
547 } 494 }
548 return iFalse; 495 return iFalse;
@@ -605,7 +552,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
605 else if (isCommand_Widget(w, ev, "document.copylink")) { 552 else if (isCommand_Widget(w, ev, "document.copylink")) {
606 if (d->hoverLink) { 553 if (d->hoverLink) {
607 SDL_SetClipboardText(cstr_String( 554 SDL_SetClipboardText(cstr_String(
608 absoluteUrl_DocumentWidget_(d, linkUrl_GmDocument(d->doc, d->hoverLink->linkId)))); 555 absoluteUrl_String(d->url, linkUrl_GmDocument(d->doc, d->hoverLink->linkId))));
609 } 556 }
610 else { 557 else {
611 SDL_SetClipboardText(cstr_String(d->url)); 558 SDL_SetClipboardText(cstr_String(d->url));
@@ -820,8 +767,8 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
820 } 767 }
821 else { 768 else {
822 postCommandf_App("open url:%s", 769 postCommandf_App("open url:%s",
823 cstr_String(absoluteUrl_DocumentWidget_( 770 cstr_String(absoluteUrl_String(
824 d, linkUrl_GmDocument(d->doc, linkId)))); 771 d->url, linkUrl_GmDocument(d->doc, linkId))));
825 } 772 }
826 } 773 }
827 if (d->selectMark.start) { 774 if (d->selectMark.start) {