Skip to content

Commit

Permalink
vaev-browser: Simple navigation and view-source support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Nov 26, 2024
1 parent 9b0b999 commit 6ec7a41
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 21 deletions.
74 changes: 59 additions & 15 deletions src/vaev-browser/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <karm-ui/scroll.h>
#include <mdi/alert-decagram.h>
#include <mdi/arrow-left.h>
#include <mdi/arrow-right.h>
#include <mdi/bookmark-outline.h>
#include <mdi/bookmark.h>
#include <mdi/button-cursor.h>
Expand Down Expand Up @@ -45,18 +46,31 @@ enum struct SidePanel {
DEVELOPER_TOOLS,
};

struct State {
struct Navigate {
Mime::Url url;
Mime::Uti action = Mime::Uti::PUBLIC_OPEN;
};

struct State {
usize currentIndex = 0;
Vec<Navigate> history;
Res<Strong<Markup::Document>> dom;
SidePanel sidePanel = SidePanel::CLOSE;
InspectState inspect = {};

State(Navigate nav, Res<Strong<Markup::Document>> dom)
: history{nav}, dom{dom} {}

bool canGoBack() const {
return false;
return currentIndex > 0;
}

bool canGoForward() const {
return false;
return currentIndex < history.len() - 1;
}

Navigate const &currentUrl() const {
return history[currentIndex];
}
};

Expand All @@ -66,23 +80,43 @@ struct GoBack {};

struct GoForward {};

using Action = Union<Reload, GoBack, GoForward, SidePanel, InspectorAction>;
using Action = Union<
Reload,
GoBack,
GoForward,
SidePanel,
InspectorAction,
Navigate>;

void reduce(State &s, Action a) {
a.visit(Visitor{
[&](Reload) {
s.dom = Vaev::Driver::fetchDocument(s.url);
auto const &object = s.currentUrl();
if (object.action == Mime::Uti::PUBLIC_MODIFY) {
s.dom = Vaev::Driver::viewSource(object.url);
} else {
s.dom = Vaev::Driver::fetchDocument(object.url);
}
},
[&](GoBack) {
s.currentIndex--;
reduce(s, Reload{});
},
[&](GoForward) {
s.currentIndex++;
reduce(s, Reload{});
},
[&](SidePanel p) {
s.sidePanel = p;
},
[&](InspectorAction a) {
s.inspect.apply(a);
}
},
[&](Navigate n) {
s.history.pushBack(n);
s.currentIndex++;
reduce(s, Reload{});
},
});
}

Expand All @@ -109,7 +143,11 @@ Ui::Child mainMenu([[maybe_unused]] State const &s) {
),
#ifdef __ck_host__
Kr::contextMenuItem([&](auto &n) {
auto res = Sys::launch(Mime::Uti::PUBLIC_OPEN, s.url);
auto res = Sys::launch({
.action = Mime::Uti::PUBLIC_OPEN,
.objects = {s.currentUrl().url},
});

if (not res)
Ui::showDialog(
n,
Expand Down Expand Up @@ -163,17 +201,22 @@ Ui::Child addressBar(Mime::Url const &url) {
Ui::Child contextMenu(State const &s) {
return Kr::contextMenuContent({
Kr::contextMenuDock({
Kr::contextMenuIcon(Ui::NOP, Mdi::ARROW_LEFT),
Kr::contextMenuIcon(Ui::NOP, Mdi::REFRESH),
Kr::contextMenuIcon(Model::bindIf<GoBack>(s.canGoBack()), Mdi::ARROW_LEFT),
Kr::contextMenuIcon(Model::bindIf<GoForward>(s.canGoForward()), Mdi::ARROW_RIGHT),
Kr::contextMenuIcon(Model::bind<Reload>(), Mdi::REFRESH),
}),
Ui::separator(),
Kr::contextMenuItem(
[s](auto &) {
(void)Sys::launch(Mime::Uti::PUBLIC_MODIFY, s.url);
},
Model::bind<Navigate>(
s.currentUrl().url,
Mime::Uti::PUBLIC_MODIFY
),
Mdi::CODE_TAGS, "View Source..."
),
Kr::contextMenuItem(Model::bind(SidePanel::DEVELOPER_TOOLS), Mdi::BUTTON_CURSOR, "Inspect"),
Kr::contextMenuItem(
Model::bind(SidePanel::DEVELOPER_TOOLS),
Mdi::BUTTON_CURSOR, "Inspect"
),
});
}

Expand Down Expand Up @@ -250,7 +293,7 @@ Ui::Child appContent(State const &s) {
Ui::Child app(Mime::Url url, Res<Strong<Vaev::Markup::Document>> dom) {
return Ui::reducer<Model>(
{
url,
Navigate{url},
dom,
},
[](State const &s) {
Expand All @@ -259,8 +302,9 @@ Ui::Child app(Mime::Url url, Res<Strong<Vaev::Markup::Document>> dom) {
.title = "Vaev"s,
.startTools = slots$(
Ui::button(Model::bindIf<GoBack>(s.canGoBack()), Ui::ButtonStyle::subtle(), Mdi::ARROW_LEFT),
Ui::button(Model::bindIf<GoForward>(s.canGoForward()), Ui::ButtonStyle::subtle(), Mdi::ARROW_RIGHT),
),
.midleTools = slots$(addressBar(s.url) | Ui::grow()),
.midleTools = slots$(addressBar(s.currentUrl().url) | Ui::grow()),
.endTools = slots$(
Ui::button(
[&](Ui::Node &n) {
Expand Down
69 changes: 63 additions & 6 deletions src/vaev-driver/fetcher.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <karm-mime/mime.h>
#include <karm-sys/dir.h>
#include <karm-sys/file.h>
#include <vaev-markup/html.h>
#include <vaev-markup/xml.h>
Expand Down Expand Up @@ -35,6 +36,58 @@ Res<Strong<Markup::Document>> loadDocument(Mime::Url const &, Mime::Mime const &
}
}

Res<Strong<Markup::Document>> viewSource(Mime::Url const &url) {
auto file = try$(Sys::File::open(url));
auto buf = try$(Io::readAllUtf8(file));

auto dom = makeStrong<Markup::Document>();

auto body = makeStrong<Markup::Element>(Html::BODY);
dom->appendChild(body);

auto pre = makeStrong<Markup::Element>(Html::PRE);
body->appendChild(pre);

auto text = makeStrong<Markup::Text>(buf);
pre->appendChild(text);

return Ok(dom);
}

Res<Strong<Markup::Document>> indexOf(Mime::Url const &url) {
auto dom = makeStrong<Markup::Document>();

auto body = makeStrong<Markup::Element>(Html::BODY);
dom->appendChild(body);

auto h1 = makeStrong<Markup::Element>(Html::H1);
body->appendChild(h1);

auto text = makeStrong<Markup::Text>(Io::format("Index of {}", url.path).unwrapOr(""s));
h1->appendChild(text);

auto ul = makeStrong<Markup::Element>(Html::UL);
body->appendChild(ul);

auto dir = try$(Sys::Dir::open(url));

for (auto const &entry : dir.entries()) {
auto li = makeStrong<Markup::Element>(Html::LI);
ul->appendChild(li);

auto a = makeStrong<Markup::Element>(Html::A);
li->appendChild(a);

auto href = url.join(entry.name);
a->setAttribute(Html::HREF_ATTR, href.str());

auto text = makeStrong<Markup::Text>(entry.name);
a->appendChild(text);
}

return Ok(dom);
}

Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url) {
if (url.scheme == "about") {
if (url.path.str() == "blank")
Expand All @@ -45,14 +98,18 @@ Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url) {

return Error::invalidInput("unsupported about page");
} else if (url.scheme == "file" or url.scheme == "bundle") {
auto mime = Mime::sniffSuffix(url.path.suffix());
if (try$(Sys::isDir(url))) {
return indexOf(url);
} else {
auto mime = Mime::sniffSuffix(url.path.suffix());

if (not mime.has())
return Error::invalidInput("cannot determine MIME type");
if (not mime.has())
return Error::invalidInput("cannot determine MIME type");

auto dom = makeStrong<Markup::Document>();
auto file = try$(Sys::File::open(url));
return loadDocument(url, *mime, file);
auto dom = makeStrong<Markup::Document>();
auto file = try$(Sys::File::open(url));
return loadDocument(url, *mime, file);
}
} else {
return Error::invalidInput("unsupported url scheme");
}
Expand Down
2 changes: 2 additions & 0 deletions src/vaev-driver/fetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url);

Res<Strong<Markup::Document>> loadDocument(Mime::Url const &url, Mime::Mime const &mime, Io::Reader &reader);

Res<Strong<Markup::Document>> viewSource(Mime::Url const &url);

} // namespace Vaev::Driver

0 comments on commit 6ec7a41

Please sign in to comment.