Files
ElyOffice/apps/ely-pdf/src/links.rs
T
ZacharyZhang-NY d59159cea2 Fixes for M-02 to M-14, G-01 to G-14, K-02 to K-04, X-04 to X-14, not yet reviewed
Committed before review so Windows and WSL builds can start.
Each fix was tested and mutation-checked here; the codex review
of each item is still to come, so tasks/BUGS.md stays unticked.

M-02 is mid-review: round 1 findings are fixed (apps/ely-mark/src/tally.rs).
K-01 stays deferred. The ElyMark window test mark-outside.sh failed
once at its crash-recovery step in the last run; not yet looked into.
2026-10-10 02:29:19 -04:00

59 lines
1.8 KiB
Rust

//! Links: followed, drawn, retargeted, deleted (PDF-07).
use ely_pdf_engine::{Link, Target};
use gpui::Context;
use crate::view::{Failed, PdfView};
/// A target as typed: a page number or an address.
pub fn parse(typed: &str, pages: usize) -> Option<Target> {
let typed = typed.trim();
match typed.parse::<usize>() {
Ok(n) => (1..=pages).contains(&n).then(|| Target::Page(n - 1, 0.0)),
Err(_) => ely_office::outward(typed).then(|| Target::Web(typed.to_string())),
}
}
/// A link's target as a person types it.
pub fn typed(link: &Link) -> String {
match link.page {
Some(page) => (page + 1).to_string(),
None => link.uri.clone(),
}
}
impl PdfView {
/// Goes where `link` points; only web and mail leave.
pub fn follow(&mut self, link: &Link, cx: &mut Context<Self>) {
match link.page {
Some(page) => {
log::info!("pdf: follows a link to page {}", page + 1);
self.show(page, link.y, cx)
}
None if ely_office::outward(&link.uri) => {
log::info!("pdf: opens a link outside");
cx.open_url(&link.uri)
}
None => {
let text = crate::viewer::Viewer::text(cx, "office.link.refused", &[]);
cx.emit(Failed(text.to_string()))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_target_is_a_page_in_range_or_a_web_or_mail_address() {
assert_eq!(parse(" 3 ", 5), Some(Target::Page(2, 0.0)));
assert_eq!(parse("9", 5), None);
assert_eq!(parse("0", 5), None);
assert_eq!(parse("https://a.b", 5), Some(Target::Web("https://a.b".into())));
assert_eq!(parse("javascript:x", 5), None);
assert_eq!(parse("file:///etc", 5), None);
}
}