From 0446219d4af092b3791942b8c0e10f45dd8971a3 Mon Sep 17 00:00:00 2001 From: mantou132 <709922234@qq.com> Date: Thu, 18 Jan 2024 16:50:34 +0800 Subject: [PATCH] [gem-book] Add `` --- packages/gem-book/docs/en/README.md | 3 ++ packages/gem-book/docs/zh/003-plugins.md | 15 ++++++++ packages/gem-book/docs/zh/README.md | 3 ++ packages/gem-book/src/bin/builder.ts | 15 +++++--- packages/gem-book/src/bin/utils.ts | 10 +++++- .../gem-book/src/element/elements/homepage.ts | 36 +++++++------------ .../gem-book/src/element/elements/sidebar.ts | 11 ++++-- packages/gem-book/src/element/index.ts | 23 +++++++++--- packages/gem-book/src/plugins/content.ts | 20 +++++++++++ packages/gem/src/elements/base/reflect.ts | 21 +++++++---- packages/gem/src/elements/base/route.ts | 2 +- 11 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 packages/gem-book/src/plugins/content.ts diff --git a/packages/gem-book/docs/en/README.md b/packages/gem-book/docs/en/README.md index 0edebd71..6dff3c11 100644 --- a/packages/gem-book/docs/en/README.md +++ b/packages/gem-book/docs/en/README.md @@ -7,10 +7,13 @@ hero: link: ./guide/README.md features: - title: Out of the box + icon: 📝 desc: Just run the command line to pack all front-end resources, so that all attention can be paid to document writing - title: Performance + icon: /logo.png desc: No redundant dependencies, the entire application will run smoothly with streamlined code - title: Expandable + icon: 👩‍🎨 desc: Can insert custom elements into existing websites; using custom elements can also customize display documents very conveniently --- diff --git a/packages/gem-book/docs/zh/003-plugins.md b/packages/gem-book/docs/zh/003-plugins.md index e9b80eb1..e3157b64 100644 --- a/packages/gem-book/docs/zh/003-plugins.md +++ b/packages/gem-book/docs/zh/003-plugins.md @@ -90,6 +90,21 @@ yarn add gem-book ``` +## `` + +将内容插入 ``,这允许在特定页面自定义 `` 内容,例如自定义侧边栏: + +```md + +
Test
+ +
+``` + ## `` 使用 [Algolia DocSearch](https://docsearch.algolia.com/) 为网站提供搜索,只需要实例化一次,可以使用[插槽](./guide/007-extension.md#插槽)放在想要放置的位置: diff --git a/packages/gem-book/docs/zh/README.md b/packages/gem-book/docs/zh/README.md index 8fce0ad8..cced6907 100644 --- a/packages/gem-book/docs/zh/README.md +++ b/packages/gem-book/docs/zh/README.md @@ -7,10 +7,13 @@ hero: link: ./guide/README.md features: - title: 开箱即用 + icon: 📝 desc: 只需运行一条命令就能构建所有前端资源,让所有注意力都能放在文档编写上。 - title: 高性能 + icon: /logo.png desc: 没有多余的依赖,整个应用将使用精简的代码流畅的运行。 - title: 可插拔可扩展 + icon: 👩‍🎨 desc: 能将自定义元素插入已有的网站中;使用自定义元素也能非常方便的自定义展示文档。 --- diff --git a/packages/gem-book/src/bin/builder.ts b/packages/gem-book/src/bin/builder.ts index ee1dedad..14248278 100644 --- a/packages/gem-book/src/bin/builder.ts +++ b/packages/gem-book/src/bin/builder.ts @@ -1,7 +1,7 @@ import path from 'path'; import { writeFileSync, symlinkSync, renameSync } from 'fs'; -import webpack, { DefinePlugin, Compilation, Compiler, sources } from 'webpack'; +import webpack, { DefinePlugin, Compiler, sources } from 'webpack'; import serveStatic from 'serve-static'; import WebpackDevServer from 'webpack-dev-server'; import HtmlWebpackPlugin from 'html-webpack-plugin'; @@ -158,7 +158,7 @@ export async function build(dir: string, options: Required, boo devtool: debug && 'source-map', plugins: [ new HtmlWebpackPlugin({ - title: bookConfig.title || 'Gem-book App', + title: bookConfig.title || 'GemBook App', ...(template ? { template: path.resolve(process.cwd(), template) } : undefined), // Automatically copied to the output directory favicon: !isRemoteIcon && icon, @@ -167,10 +167,15 @@ export async function build(dir: string, options: Required, boo }, }), new DefinePlugin({ - 'import.meta.url': DefinePlugin.runtimeValue(({ module }) => + // 插件 query 参数传递 + 'import.meta.url': DefinePlugin.runtimeValue(({ module }) => { // 如果是符号链接返回的是原始路径 - JSON.stringify(pluginRecord[module.resource]?.url), - ), + const plugin = + pluginRecord[module.resource] || + // 如果是 GemBook 本身 GEM_BOOK_DEV 模式,路径是 src + pluginRecord[module.resource.replace(/\/src\/plugins\/(\w*)\.ts/, '/plugins/$1.js')]; + return JSON.stringify(plugin ? plugin.url : ''); + }), 'process.env.DEV_MODE': !build, 'process.env.BOOK_CONFIG': JSON.stringify(bookConfig), 'process.env.THEME': JSON.stringify(await importObject(themePath)), diff --git a/packages/gem-book/src/bin/utils.ts b/packages/gem-book/src/bin/utils.ts index 66038cf8..0ddb2251 100644 --- a/packages/gem-book/src/bin/utils.ts +++ b/packages/gem-book/src/bin/utils.ts @@ -193,7 +193,15 @@ export function getMetadata(fullPath: string, displayRank: boolean | undefined) }; const parseMd = (fullPath: string) => { const md = getMdFile(fullPath).content; - const { attributes, body } = fm(md); + let attributes: FrontMatter = {}; + let body = ''; + try { + const fmd = fm(md); + attributes = fmd.attributes; + body = fmd.body; + } catch { + print(chalk.red(`Parse frontmatter error: ${fullPath}`)); + } return { ...(attributes as FrontMatter), title: parseTitle(attributes.title || load(marked(body))('h1').text() || getTitle()).text, diff --git a/packages/gem-book/src/element/elements/homepage.ts b/packages/gem-book/src/element/elements/homepage.ts index b6a5cc3a..faa1ddc3 100644 --- a/packages/gem-book/src/element/elements/homepage.ts +++ b/packages/gem-book/src/element/elements/homepage.ts @@ -24,8 +24,7 @@ export class Homepage extends GemElement { - + `; } diff --git a/packages/gem-book/src/element/index.ts b/packages/gem-book/src/element/index.ts index 4513647b..7df7e710 100644 --- a/packages/gem-book/src/element/index.ts +++ b/packages/gem-book/src/element/index.ts @@ -13,6 +13,7 @@ import { refobject, RefObject, boolattribute, + exportPartsMap, } from '@mantou/gem'; import { GemLightRouteElement, matchPath } from '@mantou/gem/elements/route'; import { mediaQuery } from '@mantou/gem/helper/mediaquery'; @@ -27,12 +28,12 @@ import { checkBuiltInPlugin, joinPath } from './lib/utils'; import { GemBookPluginElement } from './elements/plugin'; import { Loadbar } from './elements/loadbar'; import { Homepage } from './elements/homepage'; +import { SideBar } from './elements/sidebar'; import type { Main } from './elements/main'; import '@mantou/gem/elements/title'; import '@mantou/gem/elements/reflect'; import './elements/nav'; -import './elements/sidebar'; import './elements/footer'; import './elements/edit-link'; import './elements/rel-link'; @@ -68,6 +69,8 @@ export class GemBookElement extends GemElement { @part static relLink: string; @part static footer: string; @part static homepageHero: string; + @part static sidebarContent: string; + @part static sidebarLogo: string; @slot static sidebarBefore: string; @slot static mainBefore: string; @@ -208,7 +211,6 @@ export class GemBookElement extends GemElement { @media ${renderFullWidth ? 'all' : 'not all'} { gem-book-nav { grid-area: 1 / aside / 2 / toc; - box-shadow: 0 0 1.5rem #00000015; } gem-book-homepage, main { @@ -268,14 +270,27 @@ export class GemBookElement extends GemElement { : null} ${mediaQuery.isPhone || !renderFullWidth ? html` - + ` : null} ${renderHomePage - ? html`` + ? html` + + ` : ''}
${renderHomePage ? '' : html``} diff --git a/packages/gem-book/src/plugins/content.ts b/packages/gem-book/src/plugins/content.ts new file mode 100644 index 00000000..7cec97a8 --- /dev/null +++ b/packages/gem-book/src/plugins/content.ts @@ -0,0 +1,20 @@ +import type { GemBookElement } from '../element'; + +customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof GemBookElement) => { + const { Gem } = GemBookPluginElement; + const { customElement, html, attribute } = Gem; + + @customElement('gbp-content') + class _GbpContentElement extends GemBookPluginElement { + @attribute method: 'prepend' | 'append'; + + render() { + const bookEle = document.querySelector('gem-book'); + return html` + + ${[...this.children].map((e) => e.cloneNode(true))} + + `; + } + } +}); diff --git a/packages/gem/src/elements/base/reflect.ts b/packages/gem/src/elements/base/reflect.ts index 378000aa..c6407a0a 100644 --- a/packages/gem/src/elements/base/reflect.ts +++ b/packages/gem/src/elements/base/reflect.ts @@ -7,7 +7,7 @@ * 比如 duoyun-ui 文档站加载示例元素时把 GemReflectElement 渲染的元素清除 */ import { GemElement } from '../../lib/element'; -import { property } from '../../lib/decorators'; +import { attribute, property } from '../../lib/decorators'; const START = 'gem-reflect-start'; const END = 'gem-reflect-end'; @@ -26,8 +26,14 @@ const getReflectFragment = (startNode: Comment) => { }; export class GemReflectElement extends GemElement { + @attribute method: 'prepend' | 'append'; + @property target: HTMLElement = document.head; + get #method() { + return this.method || 'append'; + } + constructor() { super({ isLight: true }); @@ -45,11 +51,14 @@ export class GemReflectElement extends GemElement { this.effect( () => { - if (!childNodes) { - [startNode, ...this.childNodes, endNode].forEach((node) => this.target.append(node)); - } else { - childNodes.forEach((node) => this.target.append(node)); - } + (childNodes || [startNode, ...this.childNodes, endNode]).forEach((node, index, arr) => { + const prev = arr[index - 1]; + if (prev) { + prev.after(node); + } else { + this.target[this.#method](node); + } + }); return () => { childNodes = getReflectFragment(startNode); childNodes.forEach((node) => node.remove()); diff --git a/packages/gem/src/elements/base/route.ts b/packages/gem/src/elements/base/route.ts index 62efe2eb..20a56c88 100644 --- a/packages/gem/src/elements/base/route.ts +++ b/packages/gem/src/elements/base/route.ts @@ -196,7 +196,7 @@ export class GemRouteElement extends GemElement { constructor({ isLight, routes }: ConstructorOptions = {}) { super({ isLight }); - this.routes = routes; + this.routes = this.routes || routes; } state: State = {