ElyMark: the page hands every link click to the app (M-05)

Preview clicks and Cmd/Ctrl clicks in the editor go through one
click handler; it stops the browser and sends the link mark's own
address, since Milkdown blanks unsafe hrefs in the DOM. Reviews run
at effort xhigh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-10 11:24:05 -04:00
1 parent fa5c0b7a75
commit c5f614d095
12 files changed
+160 -18

No files matched your search

+19 -10
View File
@@ -266,16 +266,7 @@ impl MarkView {
cx.emit(Reported);
}
Event::Query(said, reply) => self.query(said, reply, cx),
// A click on a link: web and mail open outside.
Event::Leave(url) if ely_office::outward(url) => {
log::info!("mark: opens a link outside");
cx.open_url(url);
}
Event::Leave(_) => {
log::info!("mark: a link of another kind was refused");
let said = ely_ui::i18n::text(cx, "office.link.refused", &[]).to_string();
cx.emit(Failed(said));
}
Event::Leave(url) => self.follow(url, cx),
Event::Failed(why) => {
let lapsed = self.tally.lapse();
self.end_renders(lapsed, why, cx);
@@ -301,6 +292,17 @@ impl MarkView {
});
}
/// A clicked link: web and mail open outside.
fn follow(&mut self, url: &str, cx: &mut Context<Self>) {
if ely_office::outward(url) {
log::info!("mark: opens a link outside");
return cx.open_url(url);
}
log::info!("mark: a link of another kind was refused");
let said = ely_ui::i18n::text(cx, "office.link.refused", &[]).to_string();
cx.emit(Failed(said));
}
fn query(&mut self, said: &str, reply: &Reply, cx: &mut Context<Self>) {
let said: Value = match serde_json::from_str(said) {
Ok(said) => said,
@@ -367,6 +369,13 @@ impl MarkView {
return reply.fail("bad search state");
}
},
(Some("link"), ..) => match said["href"].as_str() {
Some(url) => self.follow(url, cx),
None => {
log::error!("mark: the page sent a link without its address");
return reply.fail("bad link");
}
},
(Some("table"), ..) if said["done"] == false => {
let key = match self.mode {
Mode::Visual => "mark.table.none",