Fix tiptap selection sync and toolbar event loop
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
use crate::model::{BlockType, DocumentBlock, DocumentModel};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct OutlineEntry {
|
||||
pub block_id: String,
|
||||
pub level: u8,
|
||||
pub title: String,
|
||||
pub depth: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VisibilitySnapshot {
|
||||
pub visible_block_ids: Vec<String>,
|
||||
pub outline: Vec<OutlineEntry>,
|
||||
}
|
||||
|
||||
impl VisibilitySnapshot {
|
||||
pub fn derive(document: &DocumentModel) -> Self {
|
||||
let mut hidden_ancestor_ids: Vec<String> = Vec::new();
|
||||
let mut visible_block_ids = Vec::new();
|
||||
let mut outline = Vec::new();
|
||||
|
||||
for block in document.blocks() {
|
||||
hidden_ancestor_ids.retain(|ancestor_id| is_ancestor_of(document, ancestor_id, block));
|
||||
let visible = hidden_ancestor_ids.is_empty();
|
||||
if visible {
|
||||
visible_block_ids.push(block.id.clone());
|
||||
}
|
||||
|
||||
if matches!(block.block_type, BlockType::Heading) {
|
||||
let level = block.heading_level.unwrap_or(1);
|
||||
if visible {
|
||||
outline.push(OutlineEntry {
|
||||
block_id: block.id.clone(),
|
||||
level,
|
||||
title: block.content.text.clone(),
|
||||
depth: block.indent as usize,
|
||||
});
|
||||
}
|
||||
if block.collapsed {
|
||||
hidden_ancestor_ids.push(block.id.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
visible_block_ids,
|
||||
outline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ancestor_of(document: &DocumentModel, ancestor_id: &str, block: &DocumentBlock) -> bool {
|
||||
document.is_descendant_of(&block.id, ancestor_id)
|
||||
}
|
||||
Reference in New Issue
Block a user