Skip to content

Commit 9e51210

Browse files
committed
vaev-browser: Simple navigation.
1 parent 7ee514f commit 9e51210

File tree

4 files changed

+131
-24
lines changed

4 files changed

+131
-24
lines changed

src/libs/karm-kira/context-menu.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,15 @@ Ui::Child contextMenuDock(Ui::Children children) {
105105
}
106106

107107
Ui::Child contextMenuIcon(Ui::OnPress onPress, Mdi::Icon i) {
108-
return Ui::button(
109-
[onPress = std::move(onPress)](auto &n) {
108+
if (onPress) {
109+
onPress = [onPress = std::move(onPress)](auto &n) {
110110
onPress(n);
111111
Ui::closePopover(n);
112-
},
112+
};
113+
}
114+
115+
return Ui::button(
116+
std::move(onPress),
113117
Ui::ButtonStyle::subtle(),
114118
i
115119
);

src/web/vaev-browser/app.cpp

+59-15
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <karm-ui/scroll.h>
1717
#include <mdi/alert-decagram.h>
1818
#include <mdi/arrow-left.h>
19+
#include <mdi/arrow-right.h>
1920
#include <mdi/bookmark-outline.h>
2021
#include <mdi/bookmark.h>
2122
#include <mdi/button-cursor.h>
@@ -45,18 +46,31 @@ enum struct SidePanel {
4546
DEVELOPER_TOOLS,
4647
};
4748

48-
struct State {
49+
struct Navigate {
4950
Mime::Url url;
51+
Mime::Uti action = Mime::Uti::PUBLIC_OPEN;
52+
};
53+
54+
struct State {
55+
usize currentIndex = 0;
56+
Vec<Navigate> history;
5057
Res<Strong<Markup::Document>> dom;
5158
SidePanel sidePanel = SidePanel::CLOSE;
5259
InspectState inspect = {};
5360

61+
State(Navigate nav, Res<Strong<Markup::Document>> dom)
62+
: history{nav}, dom{dom} {}
63+
5464
bool canGoBack() const {
55-
return false;
65+
return currentIndex > 0;
5666
}
5767

5868
bool canGoForward() const {
59-
return false;
69+
return currentIndex < history.len() - 1;
70+
}
71+
72+
Navigate const &currentUrl() const {
73+
return history[currentIndex];
6074
}
6175
};
6276

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

6781
struct GoForward {};
6882

69-
using Action = Union<Reload, GoBack, GoForward, SidePanel, InspectorAction>;
83+
using Action = Union<
84+
Reload,
85+
GoBack,
86+
GoForward,
87+
SidePanel,
88+
InspectorAction,
89+
Navigate>;
7090

7191
void reduce(State &s, Action a) {
7292
a.visit(Visitor{
7393
[&](Reload) {
74-
s.dom = Vaev::Driver::fetchDocument(s.url);
94+
auto const &object = s.currentUrl();
95+
if (object.action == Mime::Uti::PUBLIC_MODIFY) {
96+
s.dom = Vaev::Driver::viewSource(object.url);
97+
} else {
98+
s.dom = Vaev::Driver::fetchDocument(object.url);
99+
}
75100
},
76101
[&](GoBack) {
102+
s.currentIndex--;
103+
reduce(s, Reload{});
77104
},
78105
[&](GoForward) {
106+
s.currentIndex++;
107+
reduce(s, Reload{});
79108
},
80109
[&](SidePanel p) {
81110
s.sidePanel = p;
82111
},
83112
[&](InspectorAction a) {
84113
s.inspect.apply(a);
85-
}
114+
},
115+
[&](Navigate n) {
116+
s.history.pushBack(n);
117+
s.currentIndex++;
118+
reduce(s, Reload{});
119+
},
86120
});
87121
}
88122

@@ -109,7 +143,11 @@ Ui::Child mainMenu([[maybe_unused]] State const &s) {
109143
),
110144
#ifdef __ck_host__
111145
Kr::contextMenuItem([&](auto &n) {
112-
auto res = Sys::launch(Mime::Uti::PUBLIC_OPEN, s.url);
146+
auto res = Sys::launch({
147+
.action = Mime::Uti::PUBLIC_OPEN,
148+
.objects = {s.currentUrl().url},
149+
});
150+
113151
if (not res)
114152
Ui::showDialog(
115153
n,
@@ -163,17 +201,22 @@ Ui::Child addressBar(Mime::Url const &url) {
163201
Ui::Child contextMenu(State const &s) {
164202
return Kr::contextMenuContent({
165203
Kr::contextMenuDock({
166-
Kr::contextMenuIcon(Ui::NOP, Mdi::ARROW_LEFT),
167-
Kr::contextMenuIcon(Ui::NOP, Mdi::REFRESH),
204+
Kr::contextMenuIcon(Model::bindIf<GoBack>(s.canGoBack()), Mdi::ARROW_LEFT),
205+
Kr::contextMenuIcon(Model::bindIf<GoForward>(s.canGoForward()), Mdi::ARROW_RIGHT),
206+
Kr::contextMenuIcon(Model::bind<Reload>(), Mdi::REFRESH),
168207
}),
169208
Ui::separator(),
170209
Kr::contextMenuItem(
171-
[s](auto &) {
172-
(void)Sys::launch(Mime::Uti::PUBLIC_MODIFY, s.url);
173-
},
210+
Model::bind<Navigate>(
211+
s.currentUrl().url,
212+
Mime::Uti::PUBLIC_MODIFY
213+
),
174214
Mdi::CODE_TAGS, "View Source..."
175215
),
176-
Kr::contextMenuItem(Model::bind(SidePanel::DEVELOPER_TOOLS), Mdi::BUTTON_CURSOR, "Inspect"),
216+
Kr::contextMenuItem(
217+
Model::bind(SidePanel::DEVELOPER_TOOLS),
218+
Mdi::BUTTON_CURSOR, "Inspect"
219+
),
177220
});
178221
}
179222

@@ -250,7 +293,7 @@ Ui::Child appContent(State const &s) {
250293
Ui::Child app(Mime::Url url, Res<Strong<Vaev::Markup::Document>> dom) {
251294
return Ui::reducer<Model>(
252295
{
253-
url,
296+
Navigate{url},
254297
dom,
255298
},
256299
[](State const &s) {
@@ -259,8 +302,9 @@ Ui::Child app(Mime::Url url, Res<Strong<Vaev::Markup::Document>> dom) {
259302
.title = "Vaev"s,
260303
.startTools = slots$(
261304
Ui::button(Model::bindIf<GoBack>(s.canGoBack()), Ui::ButtonStyle::subtle(), Mdi::ARROW_LEFT),
305+
Ui::button(Model::bindIf<GoForward>(s.canGoForward()), Ui::ButtonStyle::subtle(), Mdi::ARROW_RIGHT),
262306
),
263-
.midleTools = slots$(addressBar(s.url) | Ui::grow()),
307+
.midleTools = slots$(addressBar(s.currentUrl().url) | Ui::grow()),
264308
.endTools = slots$(
265309
Ui::button(
266310
[&](Ui::Node &n) {

src/web/vaev-driver/fetcher.cpp

+63-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <karm-mime/mime.h>
2+
#include <karm-sys/dir.h>
23
#include <karm-sys/file.h>
34
#include <vaev-markup/html.h>
45
#include <vaev-markup/xml.h>
@@ -35,6 +36,58 @@ Res<Strong<Markup::Document>> loadDocument(Mime::Url const &, Mime::Mime const &
3536
}
3637
}
3738

39+
Res<Strong<Markup::Document>> viewSource(Mime::Url const &url) {
40+
auto file = try$(Sys::File::open(url));
41+
auto buf = try$(Io::readAllUtf8(file));
42+
43+
auto dom = makeStrong<Markup::Document>();
44+
45+
auto body = makeStrong<Markup::Element>(Html::BODY);
46+
dom->appendChild(body);
47+
48+
auto pre = makeStrong<Markup::Element>(Html::PRE);
49+
body->appendChild(pre);
50+
51+
auto text = makeStrong<Markup::Text>(buf);
52+
pre->appendChild(text);
53+
54+
return Ok(dom);
55+
}
56+
57+
Res<Strong<Markup::Document>> indexOf(Mime::Url const &url) {
58+
auto dom = makeStrong<Markup::Document>();
59+
60+
auto body = makeStrong<Markup::Element>(Html::BODY);
61+
dom->appendChild(body);
62+
63+
auto h1 = makeStrong<Markup::Element>(Html::H1);
64+
body->appendChild(h1);
65+
66+
auto text = makeStrong<Markup::Text>(Io::format("Index of {}", url.path).unwrapOr(""s));
67+
h1->appendChild(text);
68+
69+
auto ul = makeStrong<Markup::Element>(Html::UL);
70+
body->appendChild(ul);
71+
72+
auto dir = try$(Sys::Dir::open(url));
73+
74+
for (auto const &entry : dir.entries()) {
75+
auto li = makeStrong<Markup::Element>(Html::LI);
76+
ul->appendChild(li);
77+
78+
auto a = makeStrong<Markup::Element>(Html::A);
79+
li->appendChild(a);
80+
81+
auto href = url.join(entry.name);
82+
a->setAttribute(Html::HREF_ATTR, href.str());
83+
84+
auto text = makeStrong<Markup::Text>(entry.name);
85+
a->appendChild(text);
86+
}
87+
88+
return Ok(dom);
89+
}
90+
3891
Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url) {
3992
if (url.scheme == "about") {
4093
if (url.path.str() == "blank")
@@ -45,14 +98,18 @@ Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url) {
4598

4699
return Error::invalidInput("unsupported about page");
47100
} else if (url.scheme == "file" or url.scheme == "bundle") {
48-
auto mime = Mime::sniffSuffix(url.path.suffix());
101+
if (try$(Sys::isDir(url))) {
102+
return indexOf(url);
103+
} else {
104+
auto mime = Mime::sniffSuffix(url.path.suffix());
49105

50-
if (not mime.has())
51-
return Error::invalidInput("cannot determine MIME type");
106+
if (not mime.has())
107+
return Error::invalidInput("cannot determine MIME type");
52108

53-
auto dom = makeStrong<Markup::Document>();
54-
auto file = try$(Sys::File::open(url));
55-
return loadDocument(url, *mime, file);
109+
auto dom = makeStrong<Markup::Document>();
110+
auto file = try$(Sys::File::open(url));
111+
return loadDocument(url, *mime, file);
112+
}
56113
} else {
57114
return Error::invalidInput("unsupported url scheme");
58115
}

src/web/vaev-driver/fetcher.h

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ Res<Strong<Markup::Document>> fetchDocument(Mime::Url const &url);
1212

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

15+
Res<Strong<Markup::Document>> viewSource(Mime::Url const &url);
16+
1517
} // namespace Vaev::Driver

0 commit comments

Comments
 (0)