diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-10 10:58:21 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-10 10:58:21 +0300 |
commit | 9505054c58afccdadc6dcffcb17cd1dd92f8c16e (patch) | |
tree | 5c871e0c995d7bed7635c99465d6646dc672b6ea /src | |
parent | ea3853df206a9a41f11cc81611ac9af594c5f345 (diff) |
DocumentWidget: Check the MIME charset parameter
Diffstat (limited to 'src')
-rw-r--r-- | src/gmdocument.h | 3 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 77 | ||||
-rw-r--r-- | src/ui/window.c | 5 |
3 files changed, 52 insertions, 33 deletions
diff --git a/src/gmdocument.h b/src/gmdocument.h index 7a0f21ee..0c6dd998 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h | |||
@@ -58,7 +58,8 @@ iDeclareClass(GmDocument) | |||
58 | iDeclareObjectConstruction(GmDocument) | 58 | iDeclareObjectConstruction(GmDocument) |
59 | 59 | ||
60 | enum iGmDocumentFormat { | 60 | enum iGmDocumentFormat { |
61 | gemini_GmDocumentFormat, | 61 | undefined_GmDocumentFormat = -1, |
62 | gemini_GmDocumentFormat = 0, | ||
62 | plainText_GmDocumentFormat, | 63 | plainText_GmDocumentFormat, |
63 | }; | 64 | }; |
64 | 65 | ||
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 6313e6df..2e51f253 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -334,9 +334,8 @@ static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | |||
334 | &endPos); | 334 | &endPos); |
335 | updateText_LabelWidget( | 335 | updateText_LabelWidget( |
336 | tabButton, | 336 | tabButton, |
337 | collectNewFormat_String("%s...", | 337 | collectNewFormat_String( |
338 | cstrCollect_String(newRange_String( | 338 | "%s...", cstr_Rangecc((iRangecc){ constBegin_String(text), endPos }))); |
339 | (iRangecc){ constBegin_String(text), endPos })))); | ||
340 | break; | 339 | break; |
341 | } | 340 | } |
342 | remove_StringArray(title, size_StringArray(title) - 1); | 341 | remove_StringArray(title, size_StringArray(title) - 1); |
@@ -402,35 +401,59 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
402 | initBlock_String(&str, &response->body); | 401 | initBlock_String(&str, &response->body); |
403 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { | 402 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { |
404 | /* Check the MIME type. */ | 403 | /* Check the MIME type. */ |
405 | const iString *mime = &response->meta; | 404 | iRangecc charset = range_CStr("utf-8"); |
406 | if (startsWith_String(mime, "text/plain")) { | 405 | enum iGmDocumentFormat docFormat = undefined_GmDocumentFormat; |
407 | setFormat_GmDocument(d->doc, plainText_GmDocumentFormat); | 406 | const iString *mimeStr = collect_String(lower_String(&response->meta)); /* for convenience */ |
408 | } | 407 | iRangecc mime = range_String(mimeStr); |
409 | else if (startsWith_String(mime, "text/gemini")) { | 408 | iRangecc seg = iNullRange; |
410 | setFormat_GmDocument(d->doc, gemini_GmDocumentFormat); | 409 | while (nextSplit_Rangecc(&mime, ";", &seg)) { |
411 | } | 410 | iRangecc param = seg; |
412 | else if (startsWith_String(mime, "image/")) { | 411 | trim_Rangecc(¶m); |
413 | if (!d->request || isFinished_GmRequest(d->request)) { | 412 | if (equal_Rangecc(¶m, "text/plain")) { |
414 | /* Make a simple document with an image. */ | 413 | docFormat = plainText_GmDocumentFormat; |
415 | const char *imageTitle = "Image"; | 414 | } |
416 | iUrl parts; | 415 | else if (equal_Rangecc(¶m, "text/gemini")) { |
417 | init_Url(&parts, d->url); // url_GmRequest(d->request)); | 416 | docFormat = gemini_GmDocumentFormat; |
418 | if (!isEmpty_Range(&parts.path)) { | 417 | } |
419 | imageTitle = baseName_Path(collect_String(newRange_String(parts.path))).start; | 418 | else if (startsWith_Rangecc(¶m, "image/")) { |
419 | docFormat = gemini_GmDocumentFormat; | ||
420 | if (!d->request || isFinished_GmRequest(d->request)) { | ||
421 | /* Make a simple document with an image. */ | ||
422 | const char *imageTitle = "Image"; | ||
423 | iUrl parts; | ||
424 | init_Url(&parts, d->url); | ||
425 | if (!isEmpty_Range(&parts.path)) { | ||
426 | imageTitle = | ||
427 | baseName_Path(collect_String(newRange_String(parts.path))).start; | ||
428 | } | ||
429 | format_String( | ||
430 | &str, "=> %s %s\n", cstr_String(d->url), imageTitle); | ||
431 | setImage_GmDocument(d->doc, 1, mimeStr, &response->body); | ||
432 | } | ||
433 | else { | ||
434 | clear_String(&str); | ||
420 | } | 435 | } |
421 | format_String( | ||
422 | &str, "=> %s %s\n", cstr_String(d->url), imageTitle); | ||
423 | setImage_GmDocument(d->doc, 1, mime, &response->body); | ||
424 | } | 436 | } |
425 | else { | 437 | else if (startsWith_Rangecc(¶m, "charset=")) { |
426 | clear_String(&str); | 438 | charset = (iRangecc){ param.start + 8, param.end }; |
439 | /* Remove whitespace and quotes. */ | ||
440 | trim_Rangecc(&charset); | ||
441 | if (*charset.start == '"' && *charset.end == '"') { | ||
442 | charset.start++; | ||
443 | charset.end--; | ||
444 | } | ||
427 | } | 445 | } |
428 | } | 446 | } |
429 | else { | 447 | if (docFormat == undefined_GmDocumentFormat) { |
430 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode); | 448 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode); |
431 | deinit_String(&str); | 449 | deinit_String(&str); |
432 | return; | 450 | return; |
433 | } | 451 | } |
452 | /* Convert the source to UTF-8 if needed. */ | ||
453 | if (!equal_Rangecc(&charset, "utf-8")) { | ||
454 | set_String(&str, | ||
455 | collect_String(decode_Block(&str.chars, cstr_Rangecc(charset)))); | ||
456 | } | ||
434 | } | 457 | } |
435 | setSource_DocumentWidget_(d, &str); | 458 | setSource_DocumentWidget_(d, &str); |
436 | deinit_String(&str); | 459 | deinit_String(&str); |
@@ -584,11 +607,9 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { | |||
584 | iWidget *dlg = makeValueInput_Widget( | 607 | iWidget *dlg = makeValueInput_Widget( |
585 | as_Widget(d), | 608 | as_Widget(d), |
586 | NULL, | 609 | NULL, |
587 | format_CStr(cyan_ColorEscape "%s", | 610 | format_CStr(cyan_ColorEscape "%s", cstr_Rangecc(parts.host)), |
588 | cstr_String(collect_String(newRange_String(parts.host)))), | ||
589 | isEmpty_String(meta_GmRequest(d->request)) | 611 | isEmpty_String(meta_GmRequest(d->request)) |
590 | ? format_CStr("Please enter input for %s:", | 612 | ? format_CStr("Please enter input for %s:", cstr_Rangecc(parts.path)) |
591 | cstr_String(collect_String(newRange_String(parts.path)))) | ||
592 | : cstr_String(meta_GmRequest(d->request)), | 613 | : cstr_String(meta_GmRequest(d->request)), |
593 | orange_ColorEscape "Send \u21d2", | 614 | orange_ColorEscape "Send \u21d2", |
594 | "document.input.submit"); | 615 | "document.input.submit"); |
diff --git a/src/ui/window.c b/src/ui/window.c index b43ca8ca..010a6707 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -82,16 +82,13 @@ static const iMenuItem fileMenuItems[] = { | |||
82 | { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, | 82 | { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, |
83 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, | 83 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, |
84 | }; | 84 | }; |
85 | #endif | ||
86 | 85 | ||
87 | static const iMenuItem editMenuItems[] = { | 86 | static const iMenuItem editMenuItems[] = { |
88 | #if !defined (iPlatformApple) | ||
89 | { "Preferences...", SDLK_COMMA, KMOD_PRIMARY, "preferences" } | ||
90 | #endif | ||
91 | }; | 87 | }; |
92 | 88 | ||
93 | static const iMenuItem viewMenuItems[] = { | 89 | static const iMenuItem viewMenuItems[] = { |
94 | }; | 90 | }; |
91 | #endif | ||
95 | 92 | ||
96 | static const char *reloadCStr_ = "\U0001f503"; | 93 | static const char *reloadCStr_ = "\U0001f503"; |
97 | static const char *stopCStr_ = orange_ColorEscape "\U0001f310"; | 94 | static const char *stopCStr_ = orange_ColorEscape "\U0001f310"; |