Skip to content

Commit

Permalink
[gem-book] Add loadbar
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Nov 28, 2023
1 parent 62b3a90 commit 62d4c14
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 14 deletions.
2 changes: 1 addition & 1 deletion packages/gem-book/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"jimp": "^0.16.1",
"jsdom": "^16.5.3",
"lodash": "^4.17.21",
"marked": "^2.0.3",
"marked": "^10.0.0",
"mkdirp": "^1.0.4",
"parse-github-url": "^1.0.2",
"ts-loader": "^9.1.2",
Expand Down
6 changes: 3 additions & 3 deletions packages/gem-book/src/bin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { createHash } from 'crypto';
import gitRemoteOriginUrl from 'git-remote-origin-url';
import parseGithub from 'parse-github-url';
import { JSDOM } from 'jsdom';
import marked from 'marked';
import { marked } from 'marked';
import fm from 'front-matter';
import YAML from 'yaml';
import { startCase } from 'lodash';
import Jimp from 'jimp/es';

import { NavItem } from '../common/config';
import { FrontMatter } from '../common/frontmatter';
import { isIndexFile, parseFilename, CUSTOM_HEADING_REG } from '../common/utils';
import { isIndexFile, parseFilename, CUSTOM_HEADING_REG, createId } from '../common/utils';

export async function getGithubUrl() {
const repoDir = process.cwd();
Expand Down Expand Up @@ -154,7 +154,7 @@ export function getMetadata(fullPath: string, displayRank: boolean | undefined):
const [, text, customId] = (heading.textContent as string).match(CUSTOM_HEADING_REG) as RegExpMatchArray;
return {
title: text,
link: `#${customId || heading.id}`,
link: `#${customId || createId(text)}`,
type: 'heading',
} as NavItem;
})
Expand Down
4 changes: 4 additions & 0 deletions packages/gem-book/src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export const CUSTOM_HEADING_REG = /^(.*?)\s*(?:{#(.*)})?$/s;

export function createId(text: string) {
return text.toLowerCase().replace(/\s+/g, '-');
}

export function parseFilename(filename: string) {
const [, rank, title] = filename.match(/^(\d*-)?(.*)/) || [];
return { rank, title };
Expand Down
87 changes: 87 additions & 0 deletions packages/gem-book/src/element/elements/loadbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { adoptedStyle, customElement } from '@mantou/gem/lib/decorators';
import { GemElement, html } from '@mantou/gem/lib/element';
import { createCSSSheet, css } from '@mantou/gem/lib/utils';

import { theme } from '../helper/theme';

const style = createCSSSheet(css`
:host {
z-index: 22222222;
position: fixed;
display: flex;
justify-content: flex-end;
align-items: flex-end;
top: 0;
left: 0;
height: 2px;
transition: width 0.3s;
background-color: ${theme.primaryColor};
}
.head {
width: 300px;
height: 400%;
background-color: inherit;
border-start-start-radius: 50%;
border-end-start-radius: 50%;
filter: drop-shadow(0 0 4px ${theme.primaryColor});
}
`);

/**
* @customElement gem-book-loadbar
*/
@customElement('gem-book-loadbar')
@adoptedStyle(style)
export class GemBookLoadbarElement extends GemElement {
static instance?: GemBookLoadbarElement;
static timer = 0;

static async start({ delay = 100 }: { delay?: number } = {}) {
clearInterval(Loadbar.timer);
Loadbar.timer = window.setTimeout(() => {
const instance = Loadbar.instance || new Loadbar();
instance.setState({ progress: 0 });
Loadbar.timer = window.setInterval(() => {
instance.setState({ progress: instance.state.progress + (95 - instance.state.progress) * 0.1 });
}, 100);
}, delay);
}

static async end() {
clearInterval(Loadbar.timer);
const instance = Loadbar.instance;
if (instance) {
instance.setState({ progress: 100 });
await new Promise((res) => setTimeout(res, 300));
instance.remove();
}
}

constructor() {
super();
document.body.append(this);
this.internals.role = 'progressbar';
}

state = {
progress: 0,
};

mounted = () => {
Loadbar.instance = this;
return () => (Loadbar.instance = undefined);
};

render = () => {
return html`
<style>
:host {
width: ${this.state.progress}%;
}
</style>
<div class="head"></div>
`;
};
}

export const Loadbar = GemBookLoadbarElement;
4 changes: 2 additions & 2 deletions packages/gem-book/src/element/elements/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GemElement, connectStore } from '@mantou/gem';
import * as Gem from '@mantou/gem';
import marked from 'marked';
import { marked } from 'marked';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';

import { theme } from '../helper/theme';
Expand All @@ -10,7 +10,7 @@ import { container } from '../elements/icons';

@connectStore(bookStore)
export class GemBookPluginElement<T = any> extends GemElement<T> {
static devMode = process.env.DEV_MODE;
static devMode = bookStore.devMode;
static marked = marked;
static Gem = Gem;
static theme = theme;
Expand Down
11 changes: 11 additions & 0 deletions packages/gem-book/src/element/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
state,
refobject,
RefObject,
boolattribute,
} from '@mantou/gem';
import { GemLightRouteElement } from '@mantou/gem/elements/route';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
Expand All @@ -22,6 +23,7 @@ import { BookConfig } from '../common/config';
import { GemBookPluginElement } from './elements/plugin';
import { theme, changeTheme, Theme } from './helper/theme';
import { bookStore, updateBookConfig, locationStore } from './store';
import { Loadbar } from './elements/loadbar';

import '@mantou/gem/elements/title';
import '@mantou/gem/elements/reflect';
Expand All @@ -47,6 +49,8 @@ export class GemBookElement extends GemElement {
@refobject routeRef: RefObject<GemLightRouteElement>;

@attribute src: string;
// process.env.DEV_MODE 只能用于 website 模式,不能用在单元素中
@boolattribute dev: boolean;

@property config: BookConfig | undefined;
@property theme: Partial<Theme> | undefined;
Expand Down Expand Up @@ -79,7 +83,12 @@ export class GemBookElement extends GemElement {
return changeTheme(newTheme);
}

#onLoading = () => {
Loadbar.start();
};

#onRouteChange = (e: CustomEvent) => {
Loadbar.end();
document.body.scroll(0, 0);
this.routechange(e.detail);
};
Expand Down Expand Up @@ -226,6 +235,7 @@ export class GemBookElement extends GemElement {
}
</style>
<gem-book-meta aria-hidden="true"></gem-book-meta>
${hasNavbar
? html`
<div class="nav-shadow" part=${this.navShadow}></div>
Expand All @@ -244,6 +254,7 @@ export class GemBookElement extends GemElement {
.locationStore=${locationStore}
.key=${lang}
.routes=${routes}
@loading=${this.#onLoading}
@routechange=${this.#onRouteChange}
></gem-light-route>
<gem-book-edit-link role="complementary" part=${this.editLink}></gem-book-edit-link>
Expand Down
8 changes: 4 additions & 4 deletions packages/gem-book/src/element/lib/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { Renderer } from 'marked';

import { anchorIcon, linkIcon } from '../elements/icons';
import { CUSTOM_HEADING_REG } from '../../common/utils';
import { createId, CUSTOM_HEADING_REG } from '../../common/utils';

import { getRemotePath, isSameOrigin, getUserLink, escapeHTML } from './utils';

export function getRenderer({ lang, link, displayRank }: { lang: string; link: string; displayRank?: boolean }) {
const renderer = new Renderer();
// https://github.com/markedjs/marked/blob/ed18cd58218ed4ab98d3457bec2872ba1f71230e/lib/marked.esm.js#L986
renderer.heading = function (fullText, level, r, slugger) {
// https://marked.js.org/using_pro#renderer
renderer.heading = function (fullText, level) {
// # heading {#custom-id}
const [, text, customId] = fullText.match(CUSTOM_HEADING_REG) as RegExpMatchArray;
const tag = `h${level}`;
const id = customId || `${this.options.headerPrefix}${slugger.slug(r)}`;
const id = customId || createId(text);
return `<${tag} class="markdown-header" id="${id}"><a class="header-anchor" aria-hidden="true" href="#${id}">${anchorIcon}</a>${text}</${tag}>`;
};

Expand Down
3 changes: 3 additions & 0 deletions packages/gem-book/src/element/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import './elements/main';
import './elements/404';

interface CurrentBookConfig {
devMode: boolean;
config: BookConfig;

links: NavItemWithLink[];
Expand Down Expand Up @@ -119,6 +120,7 @@ function getRouter(links: NavItemWithLink[], title: string, lang: string, displa
async getContent() {
const renderer = getRenderer({ lang, link: originLink, displayRank });
const content = await fetchDocument(originLink, lang, hash);
if (bookStore.devMode) await new Promise((res) => setTimeout(res, 1000));
return html`<gem-book-main role="article" .renderer=${renderer} .content=${content}></gem-book-main>`;
},
data: item,
Expand Down Expand Up @@ -227,6 +229,7 @@ export function updateBookConfig(config: BookConfig | undefined, gemBookElement?
});
if (gemBookElement) {
updateStore(bookStore, {
devMode: gemBookElement.dev,
getCurrentLink: () => {
return gemBookElement?.routeRef.element?.currentRoute?.data as NavItemWithLink;
},
Expand Down
1 change: 1 addition & 0 deletions packages/gem-book/src/website/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const theme = JSON.parse(String(process.env.THEME));
const devRender = () => {
const book = document.querySelector<GemBookElement>('gem-book') || new GemBookElement();
book.src = `/${DEFAULT_FILE}`;
book.dev = true;
if (theme) {
fetch(`/${DEV_THEME_FILE}`)
.then((res) => res.json())
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8988,10 +8988,10 @@ map-obj@^4.0.0:
resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz"
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==

marked@^2.0.3:
version "2.1.3"
resolved "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz"
integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
marked@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-10.0.0.tgz#7fe1805bb908433d760e2de0fcc8841a2b2d745c"
integrity sha512-YiGcYcWj50YrwBgNzFoYhQ1hT6GmQbFG8SksnYJX1z4BXTHSOrz1GB5/Jm2yQvMg4nN1FHP4M6r03R10KrVUiA==

marky@^1.2.2:
version "1.2.2"
Expand Down

0 comments on commit 62d4c14

Please sign in to comment.