This commit is contained in:
yumoqing 2026-06-03 13:00:27 +08:00
parent 6fe0919f8a
commit b37d2811da
2 changed files with 119 additions and 40 deletions

View File

@ -12,7 +12,7 @@ bricks.ApiDoc = class extends bricks.VBox {
constructor(options) { constructor(options) {
if (!options) options = {}; if (!options) options = {};
super(options); super(options);
this.md_url = bricks.absurl(this.opts.md_url); this.md_url = bricks.absurl(this.opts.md_url, this);
this.api_title = this.opts.title || 'API Documentation'; this.api_title = this.opts.title || 'API Documentation';
this.api_base_url = this.opts.base_url || ''; this.api_base_url = this.opts.base_url || '';
this.sections = []; this.sections = [];
@ -81,29 +81,73 @@ bricks.ApiDoc = class extends bricks.VBox {
var tmp = document.createElement('div'); var tmp = document.createElement('div');
tmp.innerHTML = html; tmp.innerHTML = html;
// Extract sections (h2 elements = API endpoints) // Extract structure: H1 = category groups, H2 = API endpoint sections
var sections = []; var categories = [];
var current = null; var current_cat = null;
var current_sec = null;
var preamble = [];
var children = tmp.children; var children = tmp.children;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
var el = children[i]; var el = children[i];
if (el.tagName === 'H2') { if (el.tagName === 'H1') {
if (current) sections.push(current); // Finalize previous section into category
current = { if (current_sec) {
if (!current_cat) {
current_cat = { heading: '', id: 'api-cat-uncat', sections: [] };
categories.push(current_cat);
}
current_cat.sections.push(current_sec);
current_sec = null;
}
current_cat = {
heading: el.textContent.trim(), heading: el.textContent.trim(),
id: 'api-sec-' + sections.length, id: 'api-cat-' + categories.length,
sections: []
};
categories.push(current_cat);
} else if (el.tagName === 'H2') {
// Finalize previous section
if (current_sec) {
if (!current_cat) {
current_cat = { heading: '', id: 'api-cat-uncat', sections: [] };
categories.push(current_cat);
}
current_cat.sections.push(current_sec);
}
var all_secs = categories.reduce(function(a, c) { return a.concat(c.sections); }, []);
current_sec = {
heading: el.textContent.trim(),
id: 'api-sec-' + all_secs.length,
elements: [] elements: []
}; };
} else if (current) { } else if (current_sec) {
current.elements.push(el); current_sec.elements.push(el);
} else {
// Elements before any H1/H2 go to preamble
preamble.push(el);
} }
} }
if (current) sections.push(current); // Finalize last section
if (current_sec) {
if (!current_cat) {
current_cat = { heading: '', id: 'api-cat-uncat', sections: [] };
categories.push(current_cat);
}
current_cat.sections.push(current_sec);
}
this.sections = sections; this.categories = categories;
// Flatten sections for content rendering
var all_sections = [];
for (var i = 0; i < categories.length; i++) {
for (var j = 0; j < categories[i].sections.length; j++) {
all_sections.push(categories[i].sections[j]);
}
}
this.sections = all_sections;
this._build_sidebar(); this._build_sidebar();
this._build_content(sections); this._build_content(all_sections);
// Highlight code blocks // Highlight code blocks
if (typeof hljs !== 'undefined') { if (typeof hljs !== 'undefined') {
@ -127,8 +171,20 @@ bricks.ApiDoc = class extends bricks.VBox {
sidebar.innerHTML = ''; sidebar.innerHTML = '';
var self = this; var self = this;
for (var i = 0; i < this.sections.length; i++) { for (var c = 0; c < this.categories.length; c++) {
var sec = this.sections[i]; var cat = this.categories[c];
// Category header (H1)
if (cat.heading) {
var cat_label = document.createElement('div');
cat_label.className = 'bricks-apidoc-nav-category';
cat_label.textContent = cat.heading;
sidebar.appendChild(cat_label);
}
// Sections under this category
for (var s = 0; s < cat.sections.length; s++) {
var sec = cat.sections[s];
var item = document.createElement('div'); var item = document.createElement('div');
item.className = 'bricks-apidoc-nav-item'; item.className = 'bricks-apidoc-nav-item';
item.setAttribute('data-section', sec.id); item.setAttribute('data-section', sec.id);
@ -159,6 +215,7 @@ bricks.ApiDoc = class extends bricks.VBox {
sidebar.appendChild(item); sidebar.appendChild(item);
} }
} }
}
_build_content(sections) { _build_content(sections) {
var content = this.content_el; var content = this.content_el;
@ -296,7 +353,7 @@ bricks.ApiDoc = class extends bricks.VBox {
render(params) { render(params) {
if (params && params.md_url) { if (params && params.md_url) {
this.md_url = bricks.absurl(params.md_url); this.md_url = bricks.absurl(params.md_url, this);
this._load(); this._load();
} }
} }

View File

@ -283,3 +283,25 @@
display: none; display: none;
} }
} }
/* Category group label in sidebar (H1) */
.bricks-apidoc-nav-category {
padding: 12px 16px 4px 16px;
font-size: 0.75em;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
color: var(--text-dim, #777);
margin-top: 8px;
border-top: 1px solid var(--border-color, rgba(255,255,255,0.06));
}
.bricks-apidoc-nav-category:first-child {
margin-top: 0;
border-top: none;
}
/* Indent nav items under a category */
.bricks-apidoc-nav-category ~ .bricks-apidoc-nav-item {
padding-left: 24px;
}