mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 08:35:28 +00:00
implement anchor auto-scroll behavior (on page load)
This commit is contained in:
parent
36f5d29fa4
commit
7d8bce152b
2 changed files with 38 additions and 3 deletions
|
|
@ -4,11 +4,11 @@ mod tags;
|
||||||
use super::{ItemAction, WindowAction};
|
use super::{ItemAction, WindowAction};
|
||||||
use crate::app::browser::window::action::Position;
|
use crate::app::browser::window::action::Position;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
EventControllerMotion, GestureClick, TextBuffer, TextTag, TextTagTable, TextView,
|
EventControllerMotion, GestureClick, TextBuffer, TextSearchFlags, TextTag, TextTagTable,
|
||||||
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::{Uri, uuid_string_random},
|
glib::{ControlFlow, 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;
|
||||||
|
|
@ -308,6 +308,34 @@ 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)
|
||||||
|
idle_add_local({
|
||||||
|
let base = base.clone();
|
||||||
|
let text_view = text_view.clone();
|
||||||
|
move || {
|
||||||
|
if let Some(fragment) = base.fragment() {
|
||||||
|
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")))
|
||||||
|
{
|
||||||
|
text_view.scroll_to_iter(&mut match_start, 0.0, true, 0.0, 0.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor = match_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlFlow::Break
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Self { text_view, title }
|
Self { text_view, title }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@ pub struct Header {
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
// * important to give the tag name here as used in the fragment search
|
||||||
Self {
|
Self {
|
||||||
h1: TextTag::builder()
|
h1: TextTag::builder()
|
||||||
.foreground("#2190a4") // @TODO optional
|
.foreground("#2190a4") // @TODO optional
|
||||||
|
.name("h1")
|
||||||
.scale(1.6)
|
.scale(1.6)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(500)
|
.weight(500)
|
||||||
|
|
@ -27,6 +29,7 @@ impl Header {
|
||||||
.build(),
|
.build(),
|
||||||
h2: TextTag::builder()
|
h2: TextTag::builder()
|
||||||
.foreground("#d56199") // @TODO optional
|
.foreground("#d56199") // @TODO optional
|
||||||
|
.name("h2")
|
||||||
.scale(1.4)
|
.scale(1.4)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(400)
|
.weight(400)
|
||||||
|
|
@ -34,6 +37,7 @@ impl Header {
|
||||||
.build(),
|
.build(),
|
||||||
h3: TextTag::builder()
|
h3: TextTag::builder()
|
||||||
.foreground("#c88800") // @TODO optional
|
.foreground("#c88800") // @TODO optional
|
||||||
|
.name("h3")
|
||||||
.scale(1.2)
|
.scale(1.2)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(400)
|
.weight(400)
|
||||||
|
|
@ -41,6 +45,7 @@ impl Header {
|
||||||
.build(),
|
.build(),
|
||||||
h4: TextTag::builder()
|
h4: TextTag::builder()
|
||||||
.foreground("#c88800") // @TODO optional
|
.foreground("#c88800") // @TODO optional
|
||||||
|
.name("h4")
|
||||||
.scale(1.1)
|
.scale(1.1)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(400)
|
.weight(400)
|
||||||
|
|
@ -48,6 +53,7 @@ impl Header {
|
||||||
.build(),
|
.build(),
|
||||||
h5: TextTag::builder()
|
h5: TextTag::builder()
|
||||||
.foreground("#c88800") // @TODO optional
|
.foreground("#c88800") // @TODO optional
|
||||||
|
.name("h5")
|
||||||
.scale(1.0)
|
.scale(1.0)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(400)
|
.weight(400)
|
||||||
|
|
@ -55,6 +61,7 @@ impl Header {
|
||||||
.build(),
|
.build(),
|
||||||
h6: TextTag::builder()
|
h6: TextTag::builder()
|
||||||
.foreground("#c88800") // @TODO optional
|
.foreground("#c88800") // @TODO optional
|
||||||
|
.name("h6")
|
||||||
.scale(1.0)
|
.scale(1.0)
|
||||||
.sentence(true)
|
.sentence(true)
|
||||||
.weight(300)
|
.weight(300)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue