amateras 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -26
- package/index.ts +1 -0
- package/package.json +32 -27
- package/packages/core/package.json +32 -0
- package/packages/core/src/env.browser.ts +21 -0
- package/packages/core/src/env.node.ts +21 -0
- package/packages/core/src/global.ts +18 -0
- package/packages/core/src/index.ts +96 -0
- package/packages/core/src/lib/assignNodeProperties.ts +11 -0
- package/packages/core/src/lib/assignProperties.ts +57 -0
- package/packages/core/src/lib/chain.ts +17 -0
- package/packages/core/src/lib/dom.ts +20 -0
- package/packages/core/src/main.ts +4 -0
- package/{src → packages/core/src}/node/$Element.ts +25 -47
- package/packages/core/src/node/$EventTarget.ts +48 -0
- package/{src → packages/core/src}/node/$HTMLElement.ts +1 -1
- package/{src → packages/core/src}/node/$Node.ts +64 -73
- package/packages/core/src/node/$Virtual.ts +65 -0
- package/packages/css/package.json +17 -0
- package/{ext/css/src/lib → packages/css/src/ext}/colors/amber.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/blackwhite.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/blue.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/cyan.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/emerald.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/fuchsia.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/gray.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/green.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/indigo.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/lime.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/neutral.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/orange.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/pink.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/purple.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/red.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/rose.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/sky.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/slate.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/stone.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/teal.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/violet.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/yellow.ts +2 -2
- package/{ext/css/src/lib → packages/css/src/ext}/colors/zinc.ts +2 -2
- package/packages/css/src/ext/container.ts +32 -0
- package/packages/css/src/ext/keyframes.ts +54 -0
- package/packages/css/src/ext/media.ts +32 -0
- package/packages/css/src/ext/property.ts +48 -0
- package/packages/css/src/ext/variable.ts +51 -0
- package/{ext → packages}/css/src/index.ts +107 -183
- package/{ext → packages}/css/src/lib/colorAssign.ts +1 -1
- package/packages/css/src/lib/utils.ts +11 -0
- package/{ext → packages}/css/src/structure/$CSSContainerRule.ts +1 -1
- package/{ext → packages}/css/src/structure/$CSSKeyframesRule.ts +0 -1
- package/{ext → packages}/css/src/structure/$CSSMediaRule.ts +1 -1
- package/packages/css/src/structure/$CSSProperty.ts +19 -0
- package/{ext → packages}/css/src/structure/$CSSRule.ts +1 -1
- package/{ext → packages}/css/src/structure/$CSSStyleRule.ts +1 -1
- package/packages/css/src/structure/$CSSVariable.ts +30 -0
- package/packages/dom/package.json +20 -0
- package/packages/dom/src/lib/HTMLElementMap.ts +213 -0
- package/packages/dom/src/lib/assignAttributes.ts +16 -0
- package/packages/dom/src/structure/CSS.ts +7 -0
- package/packages/dom/src/structure/CSSStyleSheet.ts +10 -0
- package/packages/dom/src/structure/DOMTokenList.ts +19 -0
- package/packages/dom/src/structure/Document.ts +36 -0
- package/packages/dom/src/structure/Element.ts +106 -0
- package/packages/dom/src/structure/HTMLElement.ts +34 -0
- package/packages/dom/src/structure/History.ts +11 -0
- package/packages/dom/src/structure/Location.ts +9 -0
- package/packages/dom/src/structure/Node.ts +51 -0
- package/packages/dom/src/structure/NodeList.ts +10 -0
- package/packages/dom/src/structure/Storage.ts +8 -0
- package/packages/dom/src/structure/Text.ts +20 -0
- package/packages/dom/src/structure/Window.ts +14 -0
- package/packages/dom/src/structure/html/HTMLAbbrElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLAddressElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLAnchorElement.ts +25 -0
- package/packages/dom/src/structure/html/HTMLAreaElement.ts +26 -0
- package/packages/dom/src/structure/html/HTMLArticleElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLAsideElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLAudioElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLBDIElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLBDOElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLBElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLBRElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLBaseElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLBodyElement.ts +22 -0
- package/packages/dom/src/structure/html/HTMLButtonElement.ts +26 -0
- package/packages/dom/src/structure/html/HTMLCanvasElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLCiteElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLCodeElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLDDElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLDFNElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLDListElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLDTElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLDataElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLDataListElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLDetailsElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLDialogElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLDivElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLEMElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLEmbedElement.ts +20 -0
- package/packages/dom/src/structure/html/HTMLFieldSetElement.ts +19 -0
- package/packages/dom/src/structure/html/HTMLFigCaptionElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLFigureElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLFooterElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLFormElement.ts +24 -0
- package/packages/dom/src/structure/html/HTMLHGroupElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLHRElement.ts +21 -0
- package/packages/dom/src/structure/html/HTMLHeadElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLHeaderElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLHeadingElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLHtmlElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLIElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLIFrameElement.ts +31 -0
- package/packages/dom/src/structure/html/HTMLImageElement.ts +38 -0
- package/packages/dom/src/structure/html/HTMLInputElement.ts +55 -0
- package/packages/dom/src/structure/html/HTMLKBDElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLLIElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLLabelElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLLegendElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLLinkElement.ts +31 -0
- package/packages/dom/src/structure/html/HTMLMainElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLMapElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLMarkElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLMediaElement.ts +48 -0
- package/packages/dom/src/structure/html/HTMLMenuElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLMetaElement.ts +22 -0
- package/packages/dom/src/structure/html/HTMLMeterElement.ts +23 -0
- package/packages/dom/src/structure/html/HTMLModElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLNavElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLNoscriptElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLOListElement.ts +20 -0
- package/packages/dom/src/structure/html/HTMLObjectElement.ts +34 -0
- package/packages/dom/src/structure/html/HTMLOptGroupElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLOptionElement.ts +20 -0
- package/packages/dom/src/structure/html/HTMLOutputElement.ts +20 -0
- package/packages/dom/src/structure/html/HTMLParagraphElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLPictureElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLPreElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLProgressElement.ts +19 -0
- package/packages/dom/src/structure/html/HTMLQuoteElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLRPElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLRTElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLRubyElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSampElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLScriptElement.ts +27 -0
- package/packages/dom/src/structure/html/HTMLSectionElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSelectElement.ts +27 -0
- package/packages/dom/src/structure/html/HTMLSlotElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLSmallElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSourceElement.ts +21 -0
- package/packages/dom/src/structure/html/HTMLSpanElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLStrongElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLStyleElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLSubElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSummaryElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLSupElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLTableCaptionElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLTableCellElement.ts +31 -0
- package/packages/dom/src/structure/html/HTMLTableColElement.ts +23 -0
- package/packages/dom/src/structure/html/HTMLTableElement.ts +26 -0
- package/packages/dom/src/structure/html/HTMLTableRowElement.ts +23 -0
- package/packages/dom/src/structure/html/HTMLTableSectionElement.ts +20 -0
- package/packages/dom/src/structure/html/HTMLTemplateElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLTextAreaElement.ts +33 -0
- package/packages/dom/src/structure/html/HTMLTimeElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLTitleElement.ts +17 -0
- package/packages/dom/src/structure/html/HTMLTrackElement.ts +21 -0
- package/packages/dom/src/structure/html/HTMLUElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLUListElement.ts +18 -0
- package/packages/dom/src/structure/html/HTMLVarElement.ts +16 -0
- package/packages/dom/src/structure/html/HTMLVideoElement.ts +22 -0
- package/packages/dom/src/structure/html/HTMLWBRElement.ts +16 -0
- package/packages/html/package.json +18 -0
- package/{ext/html/html.ts → packages/html/src/index.ts} +1 -1
- package/{ext/html → packages/html/src}/node/$Anchor.ts +4 -4
- package/packages/html/src/node/$Canvas.ts +38 -0
- package/{ext/html → packages/html/src}/node/$Dialog.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Form.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Image.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Input.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Label.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Media.ts +4 -4
- package/{ext/html → packages/html/src}/node/$OptGroup.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Option.ts +4 -4
- package/{ext/html → packages/html/src}/node/$Select.ts +4 -4
- package/{ext/html → packages/html/src}/node/$TextArea.ts +4 -4
- package/{ext → packages}/i18n/README.md +20 -0
- package/packages/i18n/package.json +19 -0
- package/packages/i18n/src/index.ts +140 -0
- package/{ext → packages}/i18n/src/structure/I18n.ts +12 -8
- package/{ext → packages}/i18n/src/structure/I18nDictionary.ts +1 -1
- package/packages/i18n/src/structure/I18nTranslation.ts +41 -0
- package/packages/idb/package.json +19 -0
- package/{ext → packages}/idb/src/index.ts +2 -2
- package/{ext → packages}/idb/src/lib/$IDBRequest.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDB.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDBCursor.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDBIndex.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDBStore.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDBStoreBase.ts +1 -1
- package/{ext → packages}/idb/src/structure/$IDBTransaction.ts +1 -1
- package/{ext → packages}/idb/src/structure/builder/$IDBBuilder.ts +9 -10
- package/{ext → packages}/idb/src/structure/builder/$IDBStoreBuilder.ts +1 -1
- package/packages/markdown/README.md +53 -0
- package/packages/markdown/package.json +19 -0
- package/packages/markdown/src/index.ts +3 -0
- package/packages/markdown/src/lib/type.ts +26 -0
- package/packages/markdown/src/lib/util.ts +21 -0
- package/packages/markdown/src/structure/Markdown.ts +54 -0
- package/packages/markdown/src/structure/MarkdownLexer.ts +111 -0
- package/packages/markdown/src/structure/MarkdownParser.ts +34 -0
- package/packages/markdown/src/syntax/alert.ts +46 -0
- package/packages/markdown/src/syntax/blockquote.ts +35 -0
- package/packages/markdown/src/syntax/bold.ts +11 -0
- package/packages/markdown/src/syntax/code.ts +11 -0
- package/packages/markdown/src/syntax/codeblock.ts +44 -0
- package/packages/markdown/src/syntax/heading.ts +14 -0
- package/packages/markdown/src/syntax/horizontalRule.ts +11 -0
- package/packages/markdown/src/syntax/image.ts +23 -0
- package/packages/markdown/src/syntax/italic.ts +11 -0
- package/packages/markdown/src/syntax/link.ts +46 -0
- package/packages/markdown/src/syntax/list.ts +121 -0
- package/packages/markdown/src/syntax/table.ts +67 -0
- package/packages/markdown/src/syntax/text.ts +19 -0
- package/packages/router/README.md +175 -0
- package/packages/router/package.json +19 -0
- package/packages/router/src/index.ts +68 -0
- package/packages/router/src/node/Page.ts +38 -0
- package/packages/router/src/node/Router.ts +212 -0
- package/{ext/router → packages/router/src}/node/RouterAnchor.ts +13 -2
- package/packages/router/src/structure/PageBuilder.ts +24 -0
- package/packages/router/src/structure/Route.ts +105 -0
- package/packages/signal/README.md +93 -0
- package/packages/signal/package.json +18 -0
- package/packages/signal/src/index.ts +221 -0
- package/{src → packages/signal/src}/structure/Signal.ts +6 -10
- package/packages/ssr/package.json +19 -0
- package/packages/ssr/src/index.ts +38 -0
- package/packages/ui/lib/VirtualScroll.ts +25 -0
- package/packages/ui/node/Accordian.ts +97 -0
- package/packages/ui/node/Carousel.ts +20 -0
- package/packages/ui/node/Form.ts +54 -0
- package/packages/ui/node/Grid.ts +0 -0
- package/packages/ui/node/Modal.ts +45 -0
- package/packages/ui/node/Table.ts +43 -0
- package/packages/ui/node/Tabs.ts +129 -0
- package/packages/ui/node/Toast.ts +16 -0
- package/packages/ui/node/Waterfall.ts +94 -0
- package/packages/ui/package.json +21 -0
- package/packages/utils/package.json +17 -0
- package/{src → packages/utils/src}/global.ts +9 -15
- package/packages/utils/src/index.ts +90 -0
- package/tsconfig.json +1 -1
- package/ext/css/package.json +0 -9
- package/ext/css/src/structure/$CSSVariable.ts +0 -12
- package/ext/html/node/$Canvas.ts +0 -16
- package/ext/i18n/package.json +0 -10
- package/ext/i18n/src/index.ts +0 -54
- package/ext/i18n/src/node/I18nText.ts +0 -35
- package/ext/idb/package.json +0 -13
- package/ext/markdown/index.ts +0 -121
- package/ext/markdown/package.json +0 -8
- package/ext/router/README.md +0 -81
- package/ext/router/index.ts +0 -73
- package/ext/router/node/Page.ts +0 -27
- package/ext/router/node/Route.ts +0 -54
- package/ext/router/node/Router.ts +0 -149
- package/ext/ssr/env.ts +0 -61
- package/ext/ssr/index.ts +0 -49
- package/ext/ssr/package.json +0 -10
- package/src/core.ts +0 -114
- package/src/index.ts +0 -3
- package/src/lib/assign.ts +0 -38
- package/src/lib/assignHelper.ts +0 -18
- package/src/lib/chain.ts +0 -13
- package/src/lib/debounce.ts +0 -7
- package/src/lib/env.ts +0 -2
- package/src/lib/native.ts +0 -40
- package/src/lib/randomId.ts +0 -9
- package/src/lib/sleep.ts +0 -3
- package/src/lib/toArray.ts +0 -9
- package/src/lib/trycatch.ts +0 -17
- package/src/node.ts +0 -10
- /package/{ext → packages}/css/README.md +0 -0
- /package/{ext/css/src/lib → packages/css/src/ext}/colors.ts +0 -0
- /package/{ext → packages}/css/src/structure/$CSSDeclaration.ts +0 -0
- /package/{ext → packages}/idb/README.md +0 -0
- /package/{ext → packages}/idb/src/core.ts +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HORIZONTAL_RULE } from "#lib/type";
|
|
2
|
+
import { setBlockTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownLexer } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
|
|
6
|
+
export const horizontalRuleProcessor = (parser: MarkdownParser) => setProcessor(parser, HORIZONTAL_RULE, _ => `<hr>`)
|
|
7
|
+
|
|
8
|
+
export const horizontalRuleTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, HORIZONTAL_RULE, {
|
|
9
|
+
regex: /^---/,
|
|
10
|
+
handle: _ => ({ content: [] })
|
|
11
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IMAGE } from "#lib/type";
|
|
2
|
+
import { setInlineTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownLexer } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
|
|
6
|
+
export const imageProcessor = (parser: MarkdownParser) => setProcessor(parser, IMAGE, token => {
|
|
7
|
+
const { url, title } = token.data!;
|
|
8
|
+
return `<img alt="${parser.parse(token.content!)}" src="${url}"${title ? ` title="${title}"` : ''}>`
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
export const imageTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, IMAGE, {
|
|
12
|
+
regex: /^!\[(.+?)\]\((.+?)\)/,
|
|
13
|
+
handle: matches => {
|
|
14
|
+
const [_, alt, detail] = matches as [string, string, string];
|
|
15
|
+
const [__, url, title] = detail.match(/(\w\w+?:\/\/[^\s]+)(?: "(.+?)")?/) as [string, string, string];
|
|
16
|
+
return {
|
|
17
|
+
content: lexer.inlineTokenize(alt),
|
|
18
|
+
data: {
|
|
19
|
+
url, title
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ITALIC } from "#lib/type";
|
|
2
|
+
import { setInlineTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownLexer } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
|
|
6
|
+
export const italicProcessor = (parser: MarkdownParser) => setProcessor(parser, ITALIC, token => `<i>${parser.parse(token.content!)}</i>`)
|
|
7
|
+
|
|
8
|
+
export const italicTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, ITALIC, {
|
|
9
|
+
regex: /\*(.+?)\*/,
|
|
10
|
+
handle: matches => ({ content: lexer.inlineTokenize(matches[1]!) })
|
|
11
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LINK, QUICK_LINK } from "#lib/type";
|
|
2
|
+
import { setInlineTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownLexer, Token } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
import { isUndefined } from "@amateras/utils";
|
|
6
|
+
|
|
7
|
+
export const linkProcessor = (parser: MarkdownParser) => {
|
|
8
|
+
const linkProcessor = (token: Token) => {
|
|
9
|
+
const {href, email, title} = token.data!;
|
|
10
|
+
return `<a href="${isUndefined(href) ? `mailto:${email}` : href}"${title ? ` title="${title}"` : ''}>${token.text ?? parser.parse(token.content!)}</a>`
|
|
11
|
+
}
|
|
12
|
+
setProcessor(parser, QUICK_LINK, linkProcessor)
|
|
13
|
+
setProcessor(parser, LINK, linkProcessor)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const linkTokenizer = (lexer: MarkdownLexer) => {
|
|
17
|
+
|
|
18
|
+
setInlineTokenizer(lexer, LINK, {
|
|
19
|
+
regex: /\[(.+?)\]\(((?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:[^\s)]+))(?: "(.+)?")?\)/,
|
|
20
|
+
handle: matches => {
|
|
21
|
+
const [_, alt, detail, title] = matches as [string, string, string, string];
|
|
22
|
+
const match = detail.match(/(?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:\/\/[^\s]+)/);
|
|
23
|
+
const [resolver] = match!;
|
|
24
|
+
const email_or_href = resolver.includes('@') ? { email: resolver }: { href: resolver };
|
|
25
|
+
return {
|
|
26
|
+
content: lexer.inlineTokenize(alt),
|
|
27
|
+
data: {
|
|
28
|
+
title, ...email_or_href
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
setInlineTokenizer(lexer, QUICK_LINK, {
|
|
34
|
+
regex: /<((?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:[^\s>]+))>/,
|
|
35
|
+
handle: matches => {
|
|
36
|
+
const [_, detail] = matches as [string, string];
|
|
37
|
+
const match = detail.match(/(?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:\/\/[^\s]+)/);
|
|
38
|
+
const [resolver] = match!;
|
|
39
|
+
const email_or_href = resolver.includes('@') ? { email: resolver }: { href: resolver };
|
|
40
|
+
return {
|
|
41
|
+
content: resolver,
|
|
42
|
+
data: email_or_href
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { EMPTY_LINE, ORDERED_LIST_ITEM, TEXT_LINE, UNORDERED_LIST_ITEM } from "#lib/type";
|
|
2
|
+
import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownLexer, Token } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
import { equal, isString } from "@amateras/utils";
|
|
6
|
+
|
|
7
|
+
export const listProcessor = (parser: MarkdownParser) => {
|
|
8
|
+
const listType = (type: string) => type === ORDERED_LIST_ITEM ? 'ol' : 'ul'
|
|
9
|
+
const listProcessor = (token: Token, tokens: Token[]) => {
|
|
10
|
+
let i = 0;
|
|
11
|
+
// cache the list by deep number
|
|
12
|
+
const deepListMap = new Map<number, List>();
|
|
13
|
+
|
|
14
|
+
const listGenerator = (type: string, deep: number) => {
|
|
15
|
+
const getList = deepListMap.get(deep)
|
|
16
|
+
const list = getList && listType(type) === getList.tagname ? getList : List(listType(type), []);
|
|
17
|
+
deepListMap.set(deep, list);
|
|
18
|
+
|
|
19
|
+
while (i < tokens.length) {
|
|
20
|
+
const token = tokens[i]!;
|
|
21
|
+
const tokenType = token.type;
|
|
22
|
+
// if token type not equal list item / empty line / text line, then finish loop
|
|
23
|
+
if (!equal(tokenType, ORDERED_LIST_ITEM, UNORDERED_LIST_ITEM, EMPTY_LINE, TEXT_LINE)) { i--; break};
|
|
24
|
+
// if token type equal text line
|
|
25
|
+
if (tokenType === TEXT_LINE) {
|
|
26
|
+
const text = token.content![0]?.text;
|
|
27
|
+
// if text start with double space
|
|
28
|
+
if (text?.match(/^\s\s/)) {
|
|
29
|
+
const match = text.match(/^(\s+)(.+)?/)!;
|
|
30
|
+
// if no content, then next token
|
|
31
|
+
if (!match[2]) { i++; continue }
|
|
32
|
+
token.data = { deep: Math.trunc(match[1]!.length / 2) - 1 }
|
|
33
|
+
}
|
|
34
|
+
// if text start with tab
|
|
35
|
+
else if (text?.match(/^\t/)) {
|
|
36
|
+
const match = text.match(/^(\t+)(.+)?/)!;
|
|
37
|
+
// if no content, then next token
|
|
38
|
+
if (!match[2]) { i++; continue }
|
|
39
|
+
token.data = { deep: match[1]!.length - 1 }
|
|
40
|
+
}
|
|
41
|
+
// else break
|
|
42
|
+
else {i--; break};
|
|
43
|
+
}
|
|
44
|
+
// if token type equal empty line, jump to next token
|
|
45
|
+
if (tokenType === EMPTY_LINE) i++;
|
|
46
|
+
// if token deep number not equal latest deep of list
|
|
47
|
+
else if (token.data!.deep !== deep) {
|
|
48
|
+
// if bigger, push deeper list into current list item
|
|
49
|
+
if (token.data!.deep > deep) deepListMap.get(deep)?.items.at(-1)?.content.push(listGenerator(tokenType, token.data!.deep))
|
|
50
|
+
// else delete current deep cache and return to upper list
|
|
51
|
+
else { deepListMap.delete(deep); break; }
|
|
52
|
+
}
|
|
53
|
+
// if token type equal text line, convert this list to paragraph mode
|
|
54
|
+
else if (tokenType === TEXT_LINE) {
|
|
55
|
+
list.paragraph = true;
|
|
56
|
+
list.items.at(-1)?.content.push(parser.parse(token.content!))
|
|
57
|
+
i++
|
|
58
|
+
}
|
|
59
|
+
// if list type not equal, then finish loop
|
|
60
|
+
else if (tokenType !== type) {
|
|
61
|
+
deepListMap.delete(deep);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
// push list item
|
|
65
|
+
else {
|
|
66
|
+
list.items.push(ListItem([parser.parse(token.content!)]));
|
|
67
|
+
i++
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return list;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
html: `${listGenerator(token.type, token.data!.deep)}`,
|
|
75
|
+
skipTokens: i
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface ListItem { content: (string | List)[], toString(): string }
|
|
80
|
+
const ListItem = (content: (string | List)[]): ListItem => ({
|
|
81
|
+
content: content,
|
|
82
|
+
toString() { return htmltag('li', this.content.join('')) }
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
interface List { tagname: string, items: ListItem[], paragraph: boolean, toString(): string }
|
|
86
|
+
const List = (tagname: 'ul' | 'ol', items: ListItem[]): List => ({
|
|
87
|
+
tagname: tagname,
|
|
88
|
+
items: items,
|
|
89
|
+
paragraph: false,
|
|
90
|
+
toString() {
|
|
91
|
+
if (this.paragraph) this.items.forEach(item => item.content.forEach((text, i) => isString(text) && (item.content[i] = htmltag('p', text))))
|
|
92
|
+
return htmltag(this.tagname, this.items.join(''))
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
setProcessor(parser, UNORDERED_LIST_ITEM, listProcessor);
|
|
97
|
+
setProcessor(parser, ORDERED_LIST_ITEM, listProcessor);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const listTokenizer = (lexer: MarkdownLexer) => {
|
|
101
|
+
const listHandle = (matches: RegExpMatchArray) => {
|
|
102
|
+
const prefix = matches[0].split(/[-*]/)[0]!;
|
|
103
|
+
const spaces = prefix.match(/\s/)?.length ?? 0;
|
|
104
|
+
const tabs = prefix.match(/\t/)?.length ?? 0;
|
|
105
|
+
return ({
|
|
106
|
+
content: lexer.inlineTokenize(matches[1]!),
|
|
107
|
+
data: {
|
|
108
|
+
deep: Math.trunc(tabs + spaces / 2)
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
setBlockTokenizer(lexer, UNORDERED_LIST_ITEM, {
|
|
113
|
+
regex: /^(?:[\s\t]+)?[-*] (.+)/,
|
|
114
|
+
handle: listHandle
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
setBlockTokenizer(lexer, ORDERED_LIST_ITEM, {
|
|
118
|
+
regex: /^(?:[\s\t]+)?\d+\. (.+)/,
|
|
119
|
+
handle: listHandle
|
|
120
|
+
})
|
|
121
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { BLOCK, TABLE, TABLE_COLUMN, TABLE_ROW } from "#lib/type";
|
|
2
|
+
import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
|
|
3
|
+
import type { BlockToken, MarkdownLexer } from "#structure/MarkdownLexer";
|
|
4
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
5
|
+
import { _Array_from } from "@amateras/utils";
|
|
6
|
+
|
|
7
|
+
export const tableProcessor = (parser: MarkdownParser) => setProcessor(parser, TABLE, (token) => {
|
|
8
|
+
let thead = '';
|
|
9
|
+
let tbody = '';
|
|
10
|
+
let rowIndex = 0;
|
|
11
|
+
for (const row of token.content!) {
|
|
12
|
+
let rowHTML = '';
|
|
13
|
+
for (let i = 0; i < row.content!.length; i++) {
|
|
14
|
+
const col = row.content![i]!;
|
|
15
|
+
const align = token.data!.align[i];
|
|
16
|
+
const tagname = rowIndex === 0 ? 'th' : 'td';
|
|
17
|
+
rowHTML += `<${tagname} align="${align ?? 'left'}">${parser.parse(col.content!)}</${tagname}>`
|
|
18
|
+
}
|
|
19
|
+
if (rowIndex === 0) thead += htmltag('thead', htmltag('tr', rowHTML));
|
|
20
|
+
else tbody += htmltag('tr', rowHTML);
|
|
21
|
+
rowIndex++
|
|
22
|
+
}
|
|
23
|
+
tbody = htmltag('tbody', tbody);
|
|
24
|
+
return htmltag('table', thead + tbody)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const tableTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, TABLE, {
|
|
28
|
+
regex: /\|(?:.+\|)+/,
|
|
29
|
+
handle(_, position, lines) {
|
|
30
|
+
const tokens: BlockToken[] = [];
|
|
31
|
+
const align = []
|
|
32
|
+
while (position < lines.length) {
|
|
33
|
+
const row: BlockToken = {
|
|
34
|
+
type: TABLE_ROW,
|
|
35
|
+
layout: BLOCK,
|
|
36
|
+
content: []
|
|
37
|
+
}
|
|
38
|
+
const line = lines[position]!;
|
|
39
|
+
const matches = _Array_from(line.matchAll(/\| ([^|]+)/g));
|
|
40
|
+
if (!matches.length) break;
|
|
41
|
+
for (const match of matches) {
|
|
42
|
+
const text = match[1]!;
|
|
43
|
+
const separator = text.match(/(:)?---+(:)?/);
|
|
44
|
+
if (separator) {
|
|
45
|
+
const [_, LEFT, RIGHT] = separator;
|
|
46
|
+
align.push(RIGHT ? LEFT ? 'center' : 'right' : 'left');
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
row.content.push({
|
|
50
|
+
type: TABLE_COLUMN,
|
|
51
|
+
content: lexer.inlineTokenize(text.trim()),
|
|
52
|
+
layout: BLOCK
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
if (row.content.length) tokens.push(row);
|
|
56
|
+
position++
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
content: tokens,
|
|
60
|
+
data: { align },
|
|
61
|
+
multiLine: {
|
|
62
|
+
skip: position,
|
|
63
|
+
tokens: []
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { EMPTY_LINE, TEXT, TEXT_LINE } from "#lib/type";
|
|
2
|
+
import { htmltag, setProcessor } from "#lib/util";
|
|
3
|
+
import type { MarkdownParser } from "#structure/MarkdownParser";
|
|
4
|
+
|
|
5
|
+
export const textProcessor = (parser: MarkdownParser) => setProcessor(parser, TEXT, token => token.text!);
|
|
6
|
+
|
|
7
|
+
export const textLineProcessor = (parser: MarkdownParser) => setProcessor(parser, TEXT_LINE, (_, tokens) => {
|
|
8
|
+
let html = '';
|
|
9
|
+
let i = 0;
|
|
10
|
+
for (const token of tokens) {
|
|
11
|
+
if (token.type === EMPTY_LINE) break;
|
|
12
|
+
html += parser.parse(token.content!);
|
|
13
|
+
i++;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
html: htmltag('p', html),
|
|
17
|
+
skipTokens: i
|
|
18
|
+
};
|
|
19
|
+
})
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# amateras/router
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```ts
|
|
5
|
+
import 'amateras';
|
|
6
|
+
import 'amateras/router';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Create Route Map
|
|
10
|
+
```ts
|
|
11
|
+
// create home page route
|
|
12
|
+
const HomePage = $.route(page => page
|
|
13
|
+
.pageTitle('Home | My Site') // set window title
|
|
14
|
+
.content([
|
|
15
|
+
$('h1').content('Home')
|
|
16
|
+
])
|
|
17
|
+
)
|
|
18
|
+
// append router and mapping home page route into router
|
|
19
|
+
$(document.body).content([
|
|
20
|
+
$('router')
|
|
21
|
+
.route('/', HomePage)
|
|
22
|
+
.route('/hello', page => 'Hello!')
|
|
23
|
+
.listen() // start to listen path change
|
|
24
|
+
])
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> [!NOTE]
|
|
28
|
+
> Don't forget to `.listen()` the path change!
|
|
29
|
+
|
|
30
|
+
## Router Anchor
|
|
31
|
+
Use `RouterAnchor` to prevent load page when open link by default `HTMLAnchorElement` element.
|
|
32
|
+
```ts
|
|
33
|
+
$('ra').content('Contact').href('/contact');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Common Methods
|
|
37
|
+
- `$.open(url)`: Open page without load page.
|
|
38
|
+
- `$.replace(url)`: Replace history state with url and open page.
|
|
39
|
+
- `$.forward()`: Forward page.
|
|
40
|
+
- `$.back()`: Back page.
|
|
41
|
+
|
|
42
|
+
## Async Route
|
|
43
|
+
```ts
|
|
44
|
+
// ./page/home_page.ts
|
|
45
|
+
export default $.route(page => {
|
|
46
|
+
return page
|
|
47
|
+
.content([
|
|
48
|
+
$('h1').content('Home Page')
|
|
49
|
+
])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// ./router.ts
|
|
53
|
+
$('router')
|
|
54
|
+
.route('/about', () => import('./page/home_page'))
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Path Parameter
|
|
58
|
+
TypeScript will parse the parameter in the path, parameter always start with `:`, after the colon comes the name of the parameter. You can access theses parameter using `Page.params`.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
$('router')
|
|
62
|
+
.route('/user/@:username', page => {
|
|
63
|
+
console.log(page.params.username);
|
|
64
|
+
return page;
|
|
65
|
+
})
|
|
66
|
+
.listen()
|
|
67
|
+
// simulate page open
|
|
68
|
+
.resolve('/user/@amateras') // 'amateras'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If you want separate router and route builder to different file, use generic parameter to define parameter name on `$.route` method.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// greating_page.ts
|
|
75
|
+
export default $.route<['name']>(page => {
|
|
76
|
+
return page
|
|
77
|
+
.content(`Hello, ${name}`)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
// router.ts
|
|
81
|
+
$('router')
|
|
82
|
+
.route('/greating', () => import('./greating_page'))
|
|
83
|
+
// ^ typescript wiil report an error, the route builder required 'name' parameter
|
|
84
|
+
|
|
85
|
+
.route('/greating/:name', () => import('./greating_page'))
|
|
86
|
+
// ^ pass
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Optional Parameter
|
|
90
|
+
Sometime we parameter can be optional, you can define the optional parameter by add `?` sign after the name of the parameter.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const userPage = $.route<'photoId', 'postId?'>(page => {
|
|
94
|
+
return page
|
|
95
|
+
.content([
|
|
96
|
+
`Photo ID: ${page.params.photoId}`, // photoId: string
|
|
97
|
+
`Post ID: ${page.params.postId}` // postId: string | undefined
|
|
98
|
+
])
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
$('router')
|
|
102
|
+
.route('/photos/:photoId', userPage)
|
|
103
|
+
// ^ pass
|
|
104
|
+
.route('/posts/:postId/photos/:photoId', userPage)
|
|
105
|
+
// ^ pass
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Nesting Route
|
|
109
|
+
`Router` element is the container of `Page` element, we can archieve nesting route by create `Router` and append it inside `Page`.
|
|
110
|
+
```ts
|
|
111
|
+
const ContactPage = $.route(page => page
|
|
112
|
+
.pageTitle('Home')
|
|
113
|
+
.content([
|
|
114
|
+
$('h1').content('Contact'),
|
|
115
|
+
$('router', page)
|
|
116
|
+
// here is the magic happened,
|
|
117
|
+
// pass the Page into router arguments
|
|
118
|
+
])
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Then, we need to declare the router map like this:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
$('router')
|
|
126
|
+
.route('/', HomePage)
|
|
127
|
+
.route('/contact', ContactPage, route => route
|
|
128
|
+
// we can define more child routes inside this '/contact' route!
|
|
129
|
+
.route('/', () => 'My name is Amateras.')
|
|
130
|
+
.route('/phone', () => '0123456789')
|
|
131
|
+
)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Alias Path
|
|
135
|
+
|
|
136
|
+
Sometime, the page doesn't have just one path. We can declare the alias paths to one route!
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
$('router')
|
|
140
|
+
.route('/', HomePage, route => route
|
|
141
|
+
.alias('/home')
|
|
142
|
+
.alias('/the/another/way/to/home')
|
|
143
|
+
// ... more alias path
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
What if the main path included parameters? Here is how to deal with it:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
$('router')
|
|
151
|
+
.route('/users/:username', UserPage, route = route
|
|
152
|
+
.alias('/u/:username')
|
|
153
|
+
.alias('/profile')
|
|
154
|
+
// ^ typescript will report an error
|
|
155
|
+
|
|
156
|
+
.alias('/profile', { username: 'amateras' })
|
|
157
|
+
// ^ pass, the params required is fulfilled
|
|
158
|
+
|
|
159
|
+
.alias('/profile', () => { return { username: getUsername() } })
|
|
160
|
+
// ^ even you can pass an arrow function!
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Group Path
|
|
165
|
+
|
|
166
|
+
There have a lot of paths got same prefix? We provide the solution:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
$('router')
|
|
170
|
+
.route('/', HomePage)
|
|
171
|
+
.group('/search', route => route
|
|
172
|
+
.route('/', SearchPage)
|
|
173
|
+
.route('/users', SearchUserPage)
|
|
174
|
+
)
|
|
175
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amateras/router",
|
|
3
|
+
"peerDependencies": {
|
|
4
|
+
"@amateras/core": "workspace:*",
|
|
5
|
+
"@amateras/html": "workspace:*",
|
|
6
|
+
"@amateras/utils": "workspace:*"
|
|
7
|
+
},
|
|
8
|
+
"imports": {
|
|
9
|
+
"#structure/*": "./src/structure/*.ts",
|
|
10
|
+
"#lib/*": "./src/lib/*.ts",
|
|
11
|
+
"#node/*": "./src/node/*.ts"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./src/index.ts",
|
|
15
|
+
"./structure/*": "./src/structure/*.ts",
|
|
16
|
+
"./lib/*": "./src/lib/*.ts",
|
|
17
|
+
"./node/*": "./src/node/*.ts"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Page } from "#node/Page";
|
|
2
|
+
import { Router } from "#node/Router";
|
|
3
|
+
import { PageBuilder } from "#structure/PageBuilder";
|
|
4
|
+
import { Route, type RouteBuilder, type RouteParams } from "#structure/Route";
|
|
5
|
+
import { _Object_assign, _bind, forEach } from "@amateras/utils";
|
|
6
|
+
import type { AnchorTarget } from "../../html/src/node/$Anchor";
|
|
7
|
+
|
|
8
|
+
declare module '@amateras/core' {
|
|
9
|
+
export namespace $ {
|
|
10
|
+
export function route<Params extends RouteParams = []>(builder: (page: Page<Params>) => OrPromise<Page<Params>>): PageBuilder<Params>;
|
|
11
|
+
export function open(url: string | URL | Nullish, target?: AnchorTarget): typeof Router;
|
|
12
|
+
export function replace(url: string | URL | Nullish): typeof Router;
|
|
13
|
+
export function back(): typeof Router;
|
|
14
|
+
export function forward(): typeof Router;
|
|
15
|
+
export interface $NodeMap {
|
|
16
|
+
'router': typeof Router;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare global {
|
|
22
|
+
interface GlobalEventHandlersEventMap {
|
|
23
|
+
'routeopen': Event;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let prototype = {
|
|
28
|
+
route(this: { routes: Map<string, Route> }, path: string, builder: RouteBuilder, handle?: (route: Route) => Route) {
|
|
29
|
+
const route = new Route<any>(path, builder);
|
|
30
|
+
handle?.(route);
|
|
31
|
+
this.routes.set(path, route);
|
|
32
|
+
return this;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
group(this: { routes: Map<string, Route> }, path: string, handle: (route: Route) => Route) {
|
|
36
|
+
this.routes.set(path, handle(new Route<any>(path)))
|
|
37
|
+
return this;
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
notFound(this: { routes: Map<string, Route> }, builder: RouteBuilder) {
|
|
41
|
+
this.routes.set('notfound', new Route('notfound', builder));
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// assign methods
|
|
47
|
+
_Object_assign(Router.prototype, prototype)
|
|
48
|
+
_Object_assign(Route.prototype, prototype)
|
|
49
|
+
_Object_assign($, {
|
|
50
|
+
route: (builder: (page: Page) => Page) => new PageBuilder(builder),
|
|
51
|
+
open: _bind(Router.open, Router),
|
|
52
|
+
replace: _bind(Router.replace, Router),
|
|
53
|
+
back: _bind(Router.back, Router),
|
|
54
|
+
forward: _bind(Router.forward, Router)
|
|
55
|
+
})
|
|
56
|
+
// assign node
|
|
57
|
+
$.assign(['router', Router])
|
|
58
|
+
// use style
|
|
59
|
+
forEach([
|
|
60
|
+
`router{display:block}`,
|
|
61
|
+
`page{display:block}`
|
|
62
|
+
], $.style);
|
|
63
|
+
|
|
64
|
+
export * from '#node/Page';
|
|
65
|
+
export * from '#node/Router';
|
|
66
|
+
export * from '#node/RouterAnchor';
|
|
67
|
+
export * from '#structure/PageBuilder';
|
|
68
|
+
export * from '#structure/Route';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RouteParams } from "#structure/Route";
|
|
2
|
+
import { chain } from "@amateras/core/lib/chain";
|
|
3
|
+
import { $HTMLElement } from "@amateras/core/node/$HTMLElement";
|
|
4
|
+
import { _null } from "@amateras/utils";
|
|
5
|
+
import type { Router } from "./Router";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class Page<Params extends RouteParams = []> extends $HTMLElement {
|
|
9
|
+
params: PageParamsResolver<Params>;
|
|
10
|
+
router: null | Router = _null
|
|
11
|
+
#pageTitle: string | null = _null;
|
|
12
|
+
built = false;
|
|
13
|
+
pathId: string;
|
|
14
|
+
constructor(pathId: string, params: PageParamsResolver<Params>) {
|
|
15
|
+
super('page');
|
|
16
|
+
this.params = params;
|
|
17
|
+
this.pathId = pathId;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pageTitle(): string | null;
|
|
21
|
+
pageTitle(title: string | null): this;
|
|
22
|
+
pageTitle(title?: string | null) {
|
|
23
|
+
return chain(this, arguments, () => this.#pageTitle, title, title => this.#pageTitle = title)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type PageParams = { [key: string]: string }
|
|
29
|
+
export type PageParamsResolver<Params extends string[]> =
|
|
30
|
+
Prettify<
|
|
31
|
+
Params extends [`${infer String}`, ...infer Rest]
|
|
32
|
+
? Rest extends string[]
|
|
33
|
+
? String extends `${infer Key}?`
|
|
34
|
+
? { [key in Key]?: string } & PageParamsResolver<Rest>
|
|
35
|
+
: { [key in String]: string } & PageParamsResolver<Rest>
|
|
36
|
+
: never
|
|
37
|
+
: {}
|
|
38
|
+
>
|