mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
implement scroll to anchor without page load
This commit is contained in:
parent
02bfc90a39
commit
36568004e8
1 changed files with 28 additions and 20 deletions
|
|
@ -8,7 +8,7 @@ use gtk::{
|
||||||
TextView, TextWindowType, UriLauncher, Window, WrapMode,
|
TextView, TextWindowType, UriLauncher, Window, WrapMode,
|
||||||
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY, BUTTON_SECONDARY, RGBA},
|
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY, BUTTON_SECONDARY, RGBA},
|
||||||
gio::{Cancellable, SimpleAction, SimpleActionGroup},
|
gio::{Cancellable, SimpleAction, SimpleActionGroup},
|
||||||
glib::{ControlFlow, Uri, idle_add_local, uri_unescape_string, uuid_string_random},
|
glib::{ControlFlow, GString, Uri, idle_add_local, uri_unescape_string, uuid_string_random},
|
||||||
prelude::{PopoverExt, TextBufferExt, TextTagExt, TextViewExt, WidgetExt},
|
prelude::{PopoverExt, TextBufferExt, TextTagExt, TextViewExt, WidgetExt},
|
||||||
};
|
};
|
||||||
use gutter::Gutter;
|
use gutter::Gutter;
|
||||||
|
|
@ -203,7 +203,11 @@ impl Markdown {
|
||||||
for tag in iter.tags() {
|
for tag in iter.tags() {
|
||||||
// Tag is link
|
// Tag is link
|
||||||
if let Some(uri) = links.get(&tag) {
|
if let Some(uri) = links.get(&tag) {
|
||||||
return open_link_in_current_tab(&uri.to_string(), &item_action);
|
return if let Some(fragment) = uri.fragment() {
|
||||||
|
scroll_to_anchor(&text_view, fragment);
|
||||||
|
} else {
|
||||||
|
open_link_in_current_tab(&uri.to_string(), &item_action);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,29 +312,13 @@ impl Markdown {
|
||||||
}
|
}
|
||||||
}); // @TODO may be expensive for CPU, add timeout?
|
}); // @TODO may be expensive for CPU, add timeout?
|
||||||
|
|
||||||
// Anchor auto-scroll behavior (@TODO navigate without page reload)
|
// Anchor auto-scroll behavior
|
||||||
idle_add_local({
|
idle_add_local({
|
||||||
let base = base.clone();
|
let base = base.clone();
|
||||||
let text_view = text_view.clone();
|
let text_view = text_view.clone();
|
||||||
move || {
|
move || {
|
||||||
if let Some(fragment) = base.fragment() {
|
if let Some(fragment) = base.fragment() {
|
||||||
let query = uri_unescape_string(&fragment, None::<&str>)
|
scroll_to_anchor(&text_view, fragment);
|
||||||
.unwrap_or(fragment)
|
|
||||||
.replace("-", " ");
|
|
||||||
let mut cursor = text_view.buffer().start_iter();
|
|
||||||
while let Some((mut match_start, match_end)) =
|
|
||||||
cursor.forward_search(&query, TextSearchFlags::CASE_INSENSITIVE, None)
|
|
||||||
{
|
|
||||||
if match_start
|
|
||||||
.tags()
|
|
||||||
.iter()
|
|
||||||
.any(|t| t.name().is_some_and(|n| n.starts_with("h")))
|
|
||||||
{
|
|
||||||
text_view.scroll_to_iter(&mut match_start, 0.0, true, 0.0, 0.0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cursor = match_end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ControlFlow::Break
|
ControlFlow::Break
|
||||||
}
|
}
|
||||||
|
|
@ -340,6 +328,26 @@ impl Markdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn scroll_to_anchor(text_view: &TextView, fragment: GString) -> bool {
|
||||||
|
let query = uri_unescape_string(&fragment, None::<&str>)
|
||||||
|
.unwrap_or(fragment)
|
||||||
|
.replace("-", " ");
|
||||||
|
let mut cursor = text_view.buffer().start_iter();
|
||||||
|
while let Some((mut match_start, match_end)) =
|
||||||
|
cursor.forward_search(&query, TextSearchFlags::CASE_INSENSITIVE, None)
|
||||||
|
{
|
||||||
|
if match_start
|
||||||
|
.tags()
|
||||||
|
.iter()
|
||||||
|
.any(|t| t.name().is_some_and(|n| n.starts_with("h")))
|
||||||
|
{
|
||||||
|
return text_view.scroll_to_iter(&mut match_start, 0.0, true, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
cursor = match_end;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn is_internal_link(request: &str) -> bool {
|
fn is_internal_link(request: &str) -> bool {
|
||||||
// schemes
|
// schemes
|
||||||
request.starts_with("gemini://")
|
request.starts_with("gemini://")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue