chore: reduce component overhead (#3)

Reviewed-on: reya/gpui-native-kit#3
This commit is contained in:
2026-11-09 10:09:56 +00:00
parent 6815585528
commit 1c091db699
44 changed files with 1376 additions and 1241 deletions
+21 -44
View File
@@ -18,7 +18,7 @@ use pulldown_cmark::{CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag, T
use std::ops::Range;
use crate::highlight::{HighlightedCode, highlight_with_tree, plain};
use crate::highlight::{HighlightedCode, highlight, plain};
use crate::utils::{code_line, grammar_language};
/// Heading scale steps relative to the root font size, H1 first.
@@ -101,8 +101,6 @@ pub enum InlineStyle {
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct MarkdownTableCell {
pub spans: Vec<InlineSpan>,
/// 1-based column position, so renderers can align to the table's columns.
pub column: usize,
}
/// A table row; the header row precedes the body rows.
@@ -277,7 +275,8 @@ impl Render for MarkdownViewState {
.size_full()
.child(blocks)
.child(
Scrollbar::vertical(self.handle.clone()).visibility(ScrollbarVisibility::Platform),
Scrollbar::vertical((self.id.clone(), "v-scrollbar"), self.handle.clone())
.visibility(ScrollbarVisibility::Platform),
)
.when_some(self.a11y_label.clone(), |view, label| {
view.aria_label(label)
@@ -292,24 +291,6 @@ struct ListFrame {
task: Option<bool>,
}
/// The table being assembled, when the parser is inside one.
enum TableBuilder {
None,
Body { rows: Vec<MarkdownTableRow> },
}
/// One open code block, accumulating its raw text.
#[derive(Default)]
struct CodeBuilder {
text: String,
}
impl CodeBuilder {
fn push(&mut self, text: &str) {
self.text.push_str(text);
}
}
/// Accumulates inline spans across inline events.
#[derive(Default)]
struct InlineBuilder {
@@ -402,8 +383,8 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
// Whether each open list item already flushed content rows.
let mut items: Vec<bool> = Vec::new();
let mut quote_depth = 0usize;
let mut table = TableBuilder::None;
let mut code: Option<CodeBuilder> = None;
let mut table: Option<Vec<MarkdownTableRow>> = None;
let mut code: Option<String> = None;
// The fence info string arrives on Start, its text follows.
let mut code_language: Option<SharedString> = None;
@@ -468,7 +449,7 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
&mut blocks,
quote_depth,
);
code = Some(CodeBuilder::default());
code = Some(String::new());
if let CodeBlockKind::Fenced(info) = kind {
let info = info.trim();
code_language =
@@ -483,10 +464,10 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
&mut blocks,
quote_depth,
);
table = TableBuilder::Body { rows: Vec::new() }
table = Some(Vec::new())
}
Tag::TableHead => {
if let TableBuilder::Body { rows } = &mut table {
if let Some(rows) = &mut table {
rows.push(MarkdownTableRow {
cells: Vec::new(),
header: true,
@@ -494,7 +475,7 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
}
}
Tag::TableRow => {
if let TableBuilder::Body { rows } = &mut table {
if let Some(rows) = &mut table {
rows.push(MarkdownTableRow {
cells: Vec::new(),
header: false,
@@ -582,13 +563,13 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
}
TagEnd::CodeBlock => {
let built = code.take().unwrap_or_default();
let text = built.text.trim_end_matches('\n');
let text = built.trim_end_matches('\n');
let language = code_language.take();
let lines = match highlight_code
.then(|| language.as_deref().and_then(grammar_language))
.flatten()
{
Some(grammar) => highlight_with_tree(text, grammar, None).0,
Some(grammar) => highlight(text, grammar),
None => plain(text),
};
blocks.push(MarkdownBlock::Code {
@@ -599,8 +580,7 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
});
}
TagEnd::Table => {
let built = std::mem::replace(&mut table, TableBuilder::None);
if let TableBuilder::Body { rows } = built {
if let Some(rows) = table.take() {
blocks.push(MarkdownBlock::Table {
table: MarkdownTable { rows },
indent: lists.len(),
@@ -610,16 +590,13 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
}
TagEnd::TableCell => {
let spans = inline.finish();
let TableBuilder::Body { rows } = &mut table else {
let Some(rows) = &mut table else {
continue;
};
let Some(row) = rows.last_mut() else {
continue;
};
row.cells.push(MarkdownTableCell {
spans,
column: row.cells.len() + 1,
});
row.cells.push(MarkdownTableCell { spans });
}
TagEnd::Emphasis
| TagEnd::Strong
@@ -629,8 +606,8 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
_ => {}
},
Event::Text(text) => {
if let Some(built) = code.as_mut() {
built.push(&text);
if let Some(buffer) = code.as_mut() {
buffer.push_str(&text);
} else {
inline.push_text(&text);
}
@@ -659,9 +636,9 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
frame.task = Some(checked);
}
}
Event::FootnoteReference(label) => inline.push_text(&label),
// HTML and math render nothing in this view.
Event::InlineHtml(_)
// Footnotes are disabled in the parser options.
Event::FootnoteReference(_)
| Event::InlineHtml(_)
| Event::Html(_)
| Event::InlineMath(_)
| Event::DisplayMath(_) => {}
@@ -783,8 +760,8 @@ fn block_frame(
let theme = cx.theme();
let content = div()
.debug_selector({
let name = SharedString::from(format!("{id}"));
move || name.to_string()
let id = id.clone();
move || id.to_string()
})
.w_full()
.flex()