vasille-web 7.0.0-rc.2 → 7.0.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 +35 -16
- package/build/dev/communication.d.ts +9 -0
- package/build/dev/css-injector.d.ts +14 -0
- package/build/dev/css-injector.js +37 -0
- package/build/dev/css.d.ts +3 -0
- package/build/dev/css.js +32 -0
- package/build/dev/index.d.ts +55 -0
- package/build/dev/index.js +64 -0
- package/build/dev/inspector.d.ts +18 -0
- package/build/dev/inspector.js +226 -0
- package/build/dev/mount.d.ts +11 -0
- package/build/dev/mount.js +91 -0
- package/build/dev/router.d.ts +23 -0
- package/build/dev/router.js +67 -0
- package/build/dev/runner.d.ts +34 -0
- package/build/dev/runner.js +128 -0
- package/build/shadow/css.d.ts +23 -0
- package/build/shadow/css.js +77 -0
- package/build/shadow/index.d.ts +3 -0
- package/build/shadow/index.js +3 -0
- package/build/shadow/lib.d.ts +11 -0
- package/build/shadow/lib.js +145 -0
- package/build/shadow/types.d.ts +31 -0
- package/build/ssg/awaited.d.ts +3 -0
- package/build/ssg/awaited.js +24 -0
- package/build/ssg/css.d.ts +8 -0
- package/build/ssg/css.js +36 -0
- package/build/ssg/index.d.ts +21 -0
- package/build/ssg/index.js +37 -0
- package/build/ssg/router.d.ts +17 -0
- package/build/ssg/router.js +59 -0
- package/build/ssg/runner.d.ts +56 -0
- package/build/ssg/runner.js +337 -0
- package/build/types/index.d.ts +9 -0
- package/build/types/index.js +1 -0
- package/build/web/css/index.d.ts +21 -0
- package/build/web/css/index.js +53 -0
- package/build/web/css/lib.d.ts +10 -0
- package/build/web/css/lib.js +75 -0
- package/build/web/index.d.ts +6 -0
- package/build/web/index.js +6 -0
- package/{types → build/web/jsx}/jsx-runtime.d.ts +8 -7
- package/build/web/jsx/spec/css.d.ts +7 -0
- package/build/web/jsx/spec/css.js +1 -0
- package/{types → build/web/jsx}/spec/html.d.ts +2 -0
- package/build/web/jsx/spec/html.js +1 -0
- package/build/web/mount.d.ts +19 -0
- package/{lib/index.js → build/web/mount.js} +26 -21
- package/build/web/router/router.d.ts +45 -0
- package/build/web/router/router.js +131 -0
- package/build/web/runner/binding/attribute.d.ts +16 -0
- package/build/web/runner/binding/attribute.js +30 -0
- package/build/web/runner/binding/binding.d.ts +20 -0
- package/build/web/runner/binding/binding.js +28 -0
- package/build/web/runner/binding/class.d.ts +9 -0
- package/build/web/runner/binding/class.js +32 -0
- package/build/web/runner/binding/property.d.ts +16 -0
- package/build/web/runner/binding/property.js +20 -0
- package/build/web/runner/binding/style.d.ts +17 -0
- package/build/web/runner/binding/style.js +32 -0
- package/build/web/runner/runner.d.ts +45 -0
- package/build/web/runner/runner.js +176 -0
- package/coverage/clover.xml +754 -0
- package/coverage/coverage-final.json +20 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/dev/css-injector.ts.html +250 -0
- package/coverage/lcov-report/dev/css.ts.html +220 -0
- package/coverage/lcov-report/dev/index.html +131 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +221 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/shadow/css.ts.html +382 -0
- package/coverage/lcov-report/shadow/index.html +131 -0
- package/coverage/lcov-report/shadow/lib.ts.html +670 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/ssg/awaited.ts.html +169 -0
- package/coverage/lcov-report/ssg/css.ts.html +223 -0
- package/coverage/lcov-report/ssg/index.html +176 -0
- package/coverage/lcov-report/ssg/index.ts.html +370 -0
- package/coverage/lcov-report/ssg/router.ts.html +388 -0
- package/coverage/lcov-report/ssg/runner.ts.html +1405 -0
- package/coverage/lcov-report/web/css/index.html +131 -0
- package/coverage/lcov-report/web/css/index.ts.html +313 -0
- package/coverage/lcov-report/web/css/lib.ts.html +352 -0
- package/coverage/lcov-report/web/index.html +116 -0
- package/coverage/lcov-report/web/index.ts.html +574 -0
- package/coverage/lcov-report/web/mount.ts.html +454 -0
- package/coverage/lcov-report/web/router/index.html +116 -0
- package/coverage/lcov-report/web/router/router.ts.html +784 -0
- package/coverage/lcov-report/web/runner/binding/attribute.ts.html +190 -0
- package/coverage/lcov-report/web/runner/binding/binding.ts.html +193 -0
- package/coverage/lcov-report/web/runner/binding/class.ts.html +199 -0
- package/coverage/lcov-report/web/runner/binding/index.html +176 -0
- package/coverage/lcov-report/web/runner/binding/property.ts.html +154 -0
- package/coverage/lcov-report/web/runner/binding/style.ts.html +205 -0
- package/coverage/lcov-report/web/runner/index.html +116 -0
- package/coverage/lcov-report/web/runner/runner.ts.html +835 -0
- package/coverage/lcov.info +1554 -0
- package/jest.config.cjs +37 -0
- package/package.json +91 -60
- package/test/api/dev.test.ts +5 -0
- package/test/api/import-list.ts +106 -0
- package/test/api/shadow.test.ts +5 -0
- package/test/api/ssg.test.ts +5 -0
- package/test/api/web.test.ts +5 -0
- package/test/css/css-dev.test.ts +103 -0
- package/test/css/css.test.ts +27 -0
- package/test/mount/exported-web-router.test.ts +63 -0
- package/test/mount/modal-no-ctx.test.ts +14 -0
- package/test/mount/modal-which-throws.test.ts +33 -0
- package/test/mount/modal-with-slot.test.ts +39 -0
- package/test/mount/modal.test.ts +34 -0
- package/test/mount/prompt-error.test.ts +44 -0
- package/test/mount/prompt-timeout.test.ts +53 -0
- package/test/mount/prompt-which-trows.test.ts +33 -0
- package/test/mount/prompt.test.ts +44 -0
- package/test/page.ts +16 -0
- package/test/router/empty-router.test.ts +21 -0
- package/test/router/page.ts +19 -0
- package/test/router/router.test.ts +774 -0
- package/test/router/v7.test.ts +129 -0
- package/test/runner/destruction.test.ts +113 -0
- package/test/runner/runner.test.ts +403 -0
- package/test/shadow/components/Component.ts +72 -0
- package/test/shadow/css.test.ts +68 -0
- package/test/shadow/page.ts +21 -0
- package/test/shadow/shadow.test.ts +71 -0
- package/test/ssg/awaited/awaited.test.ts +11 -0
- package/test/ssg/awaited/element.test.ts +6 -0
- package/test/ssg/awaited/element.tsx +10 -0
- package/test/ssg/awaited/element.tsx.html +12 -0
- package/test/ssg/awaited/embed.test.ts +6 -0
- package/test/ssg/awaited/embed.tsx +14 -0
- package/test/ssg/awaited/embed.tsx.html +16 -0
- package/test/ssg/awaited/text.test.ts +6 -0
- package/test/ssg/awaited/text.tsx +8 -0
- package/test/ssg/awaited/text.tsx.html +7 -0
- package/test/ssg/awaited/throw-sync.tsx +10 -0
- package/test/ssg/awaited/throw-sync.tsx.html +7 -0
- package/test/ssg/awaited/throw.tsx +13 -0
- package/test/ssg/awaited/throw.tsx.html +7 -0
- package/test/ssg/compose/compose.test.ts +25 -0
- package/test/ssg/compose/modal.tsx +29 -0
- package/test/ssg/compose/modal.tsx.html +16 -0
- package/test/ssg/compose/view.tsx +35 -0
- package/test/ssg/compose/view.tsx.html +12 -0
- package/test/ssg/core/core.test.ts +31 -0
- package/test/ssg/core/div-embed.tsx +7 -0
- package/test/ssg/core/div-embed.tsx.html +9 -0
- package/test/ssg/core/div-with-class.tsx +5 -0
- package/test/ssg/core/div-with-class.tsx.html +9 -0
- package/test/ssg/core/div-with-text.tsx +5 -0
- package/test/ssg/core/div-with-text.tsx.html +9 -0
- package/test/ssg/core/div.tsx +5 -0
- package/test/ssg/core/div.tsx.html +7 -0
- package/test/ssg/core/text-join.tsx +9 -0
- package/test/ssg/core/text-join.tsx.html +10 -0
- package/test/ssg/core/text.tsx +5 -0
- package/test/ssg/core/text.tsx.html +7 -0
- package/test/ssg/css/css.test.ts +6 -0
- package/test/ssg/css/css.tsx +34 -0
- package/test/ssg/css/css.tsx.html +28 -0
- package/test/ssg/extra-tags/body.tsx +6 -0
- package/test/ssg/extra-tags/body.tsx.html +7 -0
- package/test/ssg/extra-tags/extra-tags.test.ts +11 -0
- package/test/ssg/extra-tags/head.tsx +9 -0
- package/test/ssg/extra-tags/head.tsx.html +12 -0
- package/test/ssg/markdown/blocks.tsx +12 -0
- package/test/ssg/markdown/blocks.tsx.md +12 -0
- package/test/ssg/markdown/css.tsx +11 -0
- package/test/ssg/markdown/css.tsx.md +1 -0
- package/test/ssg/markdown/external.tsx +7 -0
- package/test/ssg/markdown/external.tsx.md +3 -0
- package/test/ssg/markdown/heading.tsx +12 -0
- package/test/ssg/markdown/heading.tsx.md +13 -0
- package/test/ssg/markdown/hybrid.tsx +15 -0
- package/test/ssg/markdown/hybrid.tsx.md +11 -0
- package/test/ssg/markdown/lists.tsx +26 -0
- package/test/ssg/markdown/lists.tsx.md +16 -0
- package/test/ssg/markdown/markdown.test.ts +41 -0
- package/test/ssg/markdown/stylish.tsx +19 -0
- package/test/ssg/markdown/stylish.tsx.md +15 -0
- package/test/ssg/markdown/table.tsx +32 -0
- package/test/ssg/markdown/table.tsx.md +11 -0
- package/test/ssg/router/embed.html +7 -0
- package/test/ssg/router/embed.tsx +5 -0
- package/test/ssg/router/file-html.tsx +5 -0
- package/test/ssg/router/file.html +7 -0
- package/test/ssg/router/index.html +7 -0
- package/test/ssg/router/index.tsx +5 -0
- package/test/ssg/router/router.test.ts +26 -0
- package/test/ssg/run-test.ts +33 -0
- package/test/ssg/runner/attr.tsx +7 -0
- package/test/ssg/runner/attr.tsx.html +7 -0
- package/test/ssg/runner/class.tsx +8 -0
- package/test/ssg/runner/class.tsx.html +7 -0
- package/test/ssg/runner/runner.test.ts +16 -0
- package/test/ssg/runner/style.tsx +19 -0
- package/test/ssg/runner/style.tsx.html +7 -0
- package/test/tsconfig.json +20 -0
- package/lib/dev.js +0 -109
- package/types/dev.d.ts +0 -10
- package/types/index.d.ts +0 -21
- package/types/spec/css.d.ts +0 -7
- /package/{lib/spec/css.js → build/dev/communication.js} +0 -0
- /package/{lib/spec/html.js → build/shadow/types.js} +0 -0
- /package/{lib → build/web/jsx}/jsx-runtime.js +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Element } from "./runner.js";
|
|
2
|
+
import { CssStyleInjector } from "../web/css/index.js";
|
|
3
|
+
export declare function styleSheet(styles: {
|
|
4
|
+
[k: string]: (string | [number, string])[];
|
|
5
|
+
}): {
|
|
6
|
+
[k: string]: CssStyleInjector;
|
|
7
|
+
};
|
|
8
|
+
export declare function mountStyles(head: Element): void;
|
package/build/ssg/css.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Element, RawContentNode } from "./runner.js";
|
|
2
|
+
import { CssStyleInjector, laptopMaxWidth, mobileMaxWidth, tabletMaxWidth } from "../web/css/index.js";
|
|
3
|
+
const styles = [
|
|
4
|
+
{ rules: [], media: () => "" },
|
|
5
|
+
{ rules: [], media: () => `(max-width:${mobileMaxWidth}px)` },
|
|
6
|
+
{ rules: [], media: () => `(min-width:${mobileMaxWidth}px) and (max-width:${tabletMaxWidth}px)` },
|
|
7
|
+
{ rules: [], media: () => `(min-width:${tabletMaxWidth}px) and (max-width:${laptopMaxWidth}px)` },
|
|
8
|
+
{ rules: [], media: () => "(prefers-color-scheme:dark)" },
|
|
9
|
+
{ rules: [], media: () => "(prefers-color-scheme:light)" },
|
|
10
|
+
];
|
|
11
|
+
class StaticCssStyleInjector extends CssStyleInjector {
|
|
12
|
+
generateClassName() {
|
|
13
|
+
return `${super.generateClassName()}-ssg`;
|
|
14
|
+
}
|
|
15
|
+
insertRule(rule, className) {
|
|
16
|
+
styles[typeof rule === "string" ? 0 : rule[0]].rules.push((typeof rule === "string" ? rule : rule[1]).replace("{}", className));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function styleSheet(styles) {
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const key in styles) {
|
|
22
|
+
result[key] = new StaticCssStyleInjector(styles[key]);
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
export function mountStyles(head) {
|
|
27
|
+
for (const item of styles) {
|
|
28
|
+
if (item.rules.length > 0) {
|
|
29
|
+
const media = item.media();
|
|
30
|
+
const style = new Element("style", { a: { media: media ? media : undefined } });
|
|
31
|
+
style.appendChild(new RawContentNode(item.rules));
|
|
32
|
+
head.appendChild(style);
|
|
33
|
+
item.rules = [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Fragment, view } from "vasille";
|
|
2
|
+
import { SsgRunner, Node, Element, type SsgTagOptions } from "./runner.js";
|
|
3
|
+
export { safe } from "vasille";
|
|
4
|
+
export { ensure, ref, ref as state, expr, expr as bind, expr as calculate, expr as watch, expr as live, set, Delay, For, Slot, Watch, store, model, setModel, mapModel, arrayModel, Switch, setErrorHandler, match, view, debounceRef as debounced, toDeepFieldRef, toFieldRef, safeRef as safeState, safeExpr as safeLive, safeInit, abortSignal, Slot as Zombie, ArrayModelView, expr as effect, ArrayView, MapModelView, SetModelView, QueuedRender, receiveOptional, SteelContext, Model, } from "vasille";
|
|
5
|
+
export { styleSheet } from "./css.js";
|
|
6
|
+
export { setMobileMaxWidth, setTabletMaxWidth, setLaptopMaxWidth } from "../web/index.js";
|
|
7
|
+
export { context, impute, receive, share } from "vasille";
|
|
8
|
+
export { screen, screen as page } from "vasille";
|
|
9
|
+
export { awaited } from "./awaited.js";
|
|
10
|
+
export { routerApp } from "./router.js";
|
|
11
|
+
interface CompositionProps {
|
|
12
|
+
slot?: (...args: any[]) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const component: typeof view;
|
|
15
|
+
export declare const compose: typeof view;
|
|
16
|
+
export declare function modal<T extends CompositionProps>(modal: (node: Fragment<Node, Element, SsgTagOptions, SsgRunner>, input: T) => void): (input: T, node: Fragment<Node, Element, SsgTagOptions, SsgRunner>) => void;
|
|
17
|
+
export declare class Prompt {
|
|
18
|
+
}
|
|
19
|
+
export declare function prompt(): void;
|
|
20
|
+
export declare function showPrompt(): void;
|
|
21
|
+
export declare function mount(): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PortalNode, view } from "vasille";
|
|
2
|
+
export { safe } from "vasille";
|
|
3
|
+
export { ensure, ref, ref as state, expr, expr as bind, expr as calculate, expr as watch, expr as live, set, Delay, For, Slot, Watch, store, model, setModel, mapModel, arrayModel, Switch, setErrorHandler, match, view, debounceRef as debounced, toDeepFieldRef, toFieldRef, safeRef as safeState, safeExpr as safeLive, safeInit, abortSignal,
|
|
4
|
+
// no zombies in SSG
|
|
5
|
+
Slot as Zombie, ArrayModelView, expr as effect, ArrayView, MapModelView, SetModelView, QueuedRender, receiveOptional, SteelContext, Model, } from "vasille";
|
|
6
|
+
export { styleSheet } from "./css.js";
|
|
7
|
+
export { setMobileMaxWidth, setTabletMaxWidth, setLaptopMaxWidth } from "../web/index.js";
|
|
8
|
+
export { context, impute, receive, share } from "vasille";
|
|
9
|
+
export { screen, screen as page } from "vasille";
|
|
10
|
+
export { awaited } from "./awaited.js";
|
|
11
|
+
export { routerApp } from "./router.js";
|
|
12
|
+
export const component = view;
|
|
13
|
+
export const compose = view;
|
|
14
|
+
export function modal(modal) {
|
|
15
|
+
return function (props, node) {
|
|
16
|
+
if (!node) {
|
|
17
|
+
throw new Error("Vasille: Modal context is missing");
|
|
18
|
+
}
|
|
19
|
+
const runner = node.runner;
|
|
20
|
+
const portal = new PortalNode(runner.body, runner, node.sDeep + 1);
|
|
21
|
+
node.child(portal);
|
|
22
|
+
modal(portal, props);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// no prompts support in SSG
|
|
26
|
+
export class Prompt {
|
|
27
|
+
}
|
|
28
|
+
export function prompt() {
|
|
29
|
+
new Prompt();
|
|
30
|
+
}
|
|
31
|
+
export function showPrompt() {
|
|
32
|
+
throw new Error("User input is not supported in SSG");
|
|
33
|
+
}
|
|
34
|
+
// SSG works only with file-based router
|
|
35
|
+
export function mount() {
|
|
36
|
+
throw new Error("SSG app can not be mounted");
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Element, Node, SsgRunner, SsgTagOptions } from "./runner.js";
|
|
2
|
+
import { Fragment, ScreenProps, Answer, QueryParams, Router, RouterInitialization, Routing } from "vasille";
|
|
3
|
+
export type Mode = "html" | "markdown" | "git-doc";
|
|
4
|
+
export declare class SsgRouter extends Router<Node, Element, SsgTagOptions, string, {}, []> {
|
|
5
|
+
protected readonly runner: SsgRunner;
|
|
6
|
+
protected readonly node: Fragment<Node, Element, SsgTagOptions>;
|
|
7
|
+
readonly html: boolean;
|
|
8
|
+
readonly markdown: boolean;
|
|
9
|
+
constructor(runner: SsgRunner, node: Fragment<Node, Element, SsgTagOptions>, init: RouterInitialization<Node, Element, SsgTagOptions, string, {}>, mode: Mode);
|
|
10
|
+
render(): Promise<Record<string, string>>;
|
|
11
|
+
renderStatic(routing: Routing<Node, Element, SsgTagOptions, string, {}>, prefix: string, routes: Record<string, string>): Promise<Record<string, string>>;
|
|
12
|
+
protected doNavigate(url: string): Promise<string>;
|
|
13
|
+
protected parseUrl(url: string): [string, QueryParams, string];
|
|
14
|
+
protected loadTarget<Route extends string>(target: Answer<Node, Element, SsgTagOptions, Route, {}>, props: ScreenProps<Route>): Promise<void>;
|
|
15
|
+
protected renderScreen<Props>(screen: (props: Props, ctx: Fragment<Node, Element, SsgTagOptions>) => void | Promise<void>, props: Props): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function routerApp(init: RouterInitialization<Node, Element, SsgTagOptions, string, {}>, mode?: Mode): SsgRouter;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Element, SsgRunner } from "./runner.js";
|
|
2
|
+
import { waitForAsyncData } from "./awaited.js";
|
|
3
|
+
import { mountStyles } from "./css.js";
|
|
4
|
+
import { Fragment, Router, AppNode } from "vasille";
|
|
5
|
+
export class SsgRouter extends Router {
|
|
6
|
+
constructor(runner, node, init, mode) {
|
|
7
|
+
super(init);
|
|
8
|
+
this.runner = runner;
|
|
9
|
+
this.node = node;
|
|
10
|
+
this.html = mode === "html" || mode === "git-doc";
|
|
11
|
+
this.markdown = mode === "markdown" || mode === "git-doc";
|
|
12
|
+
}
|
|
13
|
+
async render() {
|
|
14
|
+
return await this.renderStatic(this.root, "/", {});
|
|
15
|
+
}
|
|
16
|
+
async renderStatic(routing, prefix, routes) {
|
|
17
|
+
if (routing.self) {
|
|
18
|
+
const forceFile = prefix.endsWith(".html");
|
|
19
|
+
const dirPath = prefix.slice(1);
|
|
20
|
+
const filePath = forceFile ? dirPath : dirPath + "/index.html";
|
|
21
|
+
routes[filePath] = await this.doNavigate(prefix);
|
|
22
|
+
}
|
|
23
|
+
for (const key in routing.static) {
|
|
24
|
+
await this.renderStatic(routing.static[key], `${prefix !== "/" ? prefix + "/" : "/"}${key}`, routes);
|
|
25
|
+
}
|
|
26
|
+
return routes;
|
|
27
|
+
}
|
|
28
|
+
async doNavigate(url) {
|
|
29
|
+
console.log(`Rendering ${url}...`);
|
|
30
|
+
await this.prepareNavigation(url, true, true);
|
|
31
|
+
if (this.markdown) {
|
|
32
|
+
return this.runner.body.toMarkDown(this.html);
|
|
33
|
+
}
|
|
34
|
+
return (["<!doctype html>", "<html>", this.runner.head.toHTML(1), this.runner.body.toHTML(1), "</html>"].join("\n") + "\n");
|
|
35
|
+
}
|
|
36
|
+
parseUrl(url) {
|
|
37
|
+
return [url, {}, ""];
|
|
38
|
+
}
|
|
39
|
+
async loadTarget(target, props) {
|
|
40
|
+
this.runner.head.children.splice(0);
|
|
41
|
+
this.runner.body.children.splice(0);
|
|
42
|
+
this.node.children.splice(0);
|
|
43
|
+
await this.renderScreen(target.screen, props);
|
|
44
|
+
}
|
|
45
|
+
async renderScreen(screen, props) {
|
|
46
|
+
await screen(props, this.node);
|
|
47
|
+
await waitForAsyncData();
|
|
48
|
+
mountStyles(this.runner.head);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function routerApp(init, mode = "html") {
|
|
52
|
+
const head = new Element("head", {});
|
|
53
|
+
const body = new Element("body", {});
|
|
54
|
+
const runner = new SsgRunner(head, body);
|
|
55
|
+
const app = new AppNode(body, runner);
|
|
56
|
+
const fragment = new Fragment(runner, 1);
|
|
57
|
+
app.child(fragment);
|
|
58
|
+
return new SsgRouter(runner, fragment, init, mode);
|
|
59
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { WebTagOptions } from "../web/runner/runner.js";
|
|
2
|
+
import { IRunner, IValue, Tag, TextNode } from "vasille";
|
|
3
|
+
export type SsgTagOptions = Omit<WebTagOptions, "slot" | "events" | "callback"> & {
|
|
4
|
+
slot?(ctx: SsgTag): void;
|
|
5
|
+
};
|
|
6
|
+
export declare abstract class Node {
|
|
7
|
+
readonly children: Node[];
|
|
8
|
+
parent: Node | null;
|
|
9
|
+
insertBefore(node: Node, before: Node): void;
|
|
10
|
+
appendChild(node: Node): void;
|
|
11
|
+
abstract toHTML(level: number): string;
|
|
12
|
+
abstract toMarkDown(supportHtml: boolean): string;
|
|
13
|
+
protected level(level: number): string;
|
|
14
|
+
}
|
|
15
|
+
export declare class RawContentNode extends Node {
|
|
16
|
+
readonly lines: string[];
|
|
17
|
+
constructor(lines: string[]);
|
|
18
|
+
toHTML(level: number): string;
|
|
19
|
+
}
|
|
20
|
+
export declare class Text extends Node {
|
|
21
|
+
readonly text: unknown | IValue<unknown, unknown>;
|
|
22
|
+
constructor(text: unknown | IValue<unknown, unknown>);
|
|
23
|
+
isEmpty(): boolean;
|
|
24
|
+
toText(): any;
|
|
25
|
+
toHTML(level: number): string;
|
|
26
|
+
toMarkDown(supportHtml: boolean): string;
|
|
27
|
+
}
|
|
28
|
+
export declare class Element extends Node {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly options: SsgTagOptions;
|
|
31
|
+
constructor(name: string, options: SsgTagOptions);
|
|
32
|
+
processAttrs(): Record<string, string | number>;
|
|
33
|
+
processStyles(): string;
|
|
34
|
+
toHTML(level: number): string;
|
|
35
|
+
toMarkDown(supportHtml: boolean): string;
|
|
36
|
+
protected attrString(attrs: Record<string, string | number>): string;
|
|
37
|
+
}
|
|
38
|
+
export declare class SsgTextNode extends TextNode<Node, Element, SsgTagOptions> {
|
|
39
|
+
protected node: Text;
|
|
40
|
+
compose(): void;
|
|
41
|
+
protected findFirstChild(): Node;
|
|
42
|
+
}
|
|
43
|
+
export declare class SsgTag extends Tag<Node, Element, SsgTagOptions, SsgRunner> {
|
|
44
|
+
node: Element;
|
|
45
|
+
compose(): void;
|
|
46
|
+
protected applyOptions(options: SsgTagOptions): void;
|
|
47
|
+
}
|
|
48
|
+
export declare class SsgRunner implements IRunner<Node, Element, SsgTagOptions> {
|
|
49
|
+
head: Element;
|
|
50
|
+
body: Element;
|
|
51
|
+
constructor(head: Element, body: Element);
|
|
52
|
+
insertBefore(node: Node, before: Node | Element): void;
|
|
53
|
+
appendChild(node: Element, child: Node | Element): void;
|
|
54
|
+
textNode(deep: number, text: unknown): TextNode<Node, Element, SsgTagOptions>;
|
|
55
|
+
tag(deep: number, tagName: string, input: SsgTagOptions, cb?: ((ctx: Tag<Node, Element, SsgTagOptions>) => void) | undefined): Tag<Node, Element, SsgTagOptions>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import escapeHTML from "escape-html";
|
|
2
|
+
import { IValue, Tag, TextNode } from "vasille";
|
|
3
|
+
import { CssStyleInjector } from "../web/css/index.js";
|
|
4
|
+
export class Node {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.children = [];
|
|
7
|
+
this.parent = null;
|
|
8
|
+
}
|
|
9
|
+
insertBefore(node, before) {
|
|
10
|
+
const index = this.children.indexOf(before);
|
|
11
|
+
/* istanbul ignore else */
|
|
12
|
+
if (index >= 0) {
|
|
13
|
+
this.children.splice(index, 0, node);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
appendChild(node) {
|
|
17
|
+
node.parent = this;
|
|
18
|
+
this.children.push(node);
|
|
19
|
+
}
|
|
20
|
+
level(level) {
|
|
21
|
+
return "\t".repeat(level);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// @ts-expect-error
|
|
25
|
+
export class RawContentNode extends Node {
|
|
26
|
+
constructor(lines) {
|
|
27
|
+
super();
|
|
28
|
+
this.lines = lines;
|
|
29
|
+
}
|
|
30
|
+
toHTML(level) {
|
|
31
|
+
const prefix = this.level(level);
|
|
32
|
+
return this.lines.map(line => prefix + line).join("\n");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class Text extends Node {
|
|
36
|
+
constructor(text) {
|
|
37
|
+
super();
|
|
38
|
+
this.text = text;
|
|
39
|
+
}
|
|
40
|
+
isEmpty() {
|
|
41
|
+
return !this.text || (this.text instanceof IValue && !this.text.V);
|
|
42
|
+
}
|
|
43
|
+
toText() {
|
|
44
|
+
return (this.text instanceof IValue ? this.text.V : this.text) ?? "";
|
|
45
|
+
}
|
|
46
|
+
toHTML(level) {
|
|
47
|
+
const text = this.toText();
|
|
48
|
+
return escapeHTML(`${this.level(level)}${text}`);
|
|
49
|
+
}
|
|
50
|
+
toMarkDown(supportHtml) {
|
|
51
|
+
return this.toText();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function addClass(classes, item) {
|
|
55
|
+
if (item instanceof IValue) {
|
|
56
|
+
addClass(classes, item.V);
|
|
57
|
+
}
|
|
58
|
+
else if (typeof item === "string") {
|
|
59
|
+
classes.push(item);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
/* istanbul ignore else */
|
|
63
|
+
if (item instanceof CssStyleInjector) {
|
|
64
|
+
classes.push(item.inject());
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class Element extends Node {
|
|
69
|
+
constructor(name, options) {
|
|
70
|
+
super();
|
|
71
|
+
this.name = name;
|
|
72
|
+
this.options = options;
|
|
73
|
+
if (options.c) {
|
|
74
|
+
for (const item of options.c) {
|
|
75
|
+
if (item instanceof CssStyleInjector) {
|
|
76
|
+
item.inject();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
processAttrs() {
|
|
82
|
+
const attrs = {};
|
|
83
|
+
if (this.options.a) {
|
|
84
|
+
for (const [name, value] of Object.entries(this.options.a)) {
|
|
85
|
+
const extracted = value instanceof IValue ? value.V : value;
|
|
86
|
+
if (typeof extracted === "string" || typeof extracted === "number") {
|
|
87
|
+
attrs[name] = extracted;
|
|
88
|
+
}
|
|
89
|
+
else if (extracted) {
|
|
90
|
+
attrs[name] = "";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return attrs;
|
|
95
|
+
}
|
|
96
|
+
processStyles() {
|
|
97
|
+
const styles = [];
|
|
98
|
+
const attrValue = this.options.a?.style;
|
|
99
|
+
/* istanbul ignore else */
|
|
100
|
+
if (typeof attrValue === "string") {
|
|
101
|
+
styles.push(attrValue);
|
|
102
|
+
}
|
|
103
|
+
if (this.options.s) {
|
|
104
|
+
for (const [name, value] of Object.entries(this.options.s)) {
|
|
105
|
+
const extracted = value instanceof IValue ? value.V : value;
|
|
106
|
+
if (extracted instanceof Array) {
|
|
107
|
+
styles.push(`${name}: ${extracted.map(n => `${n}px`).join(" ")}`);
|
|
108
|
+
}
|
|
109
|
+
else if (typeof extracted === "number") {
|
|
110
|
+
styles.push(`${name}: ${extracted}px`);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
styles.push(`${name}: ${extracted}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return styles.join("; ");
|
|
118
|
+
}
|
|
119
|
+
toHTML(level) {
|
|
120
|
+
const attrs = this.processAttrs();
|
|
121
|
+
if (this.options.c) {
|
|
122
|
+
const classes = [];
|
|
123
|
+
for (const item of this.options.c) {
|
|
124
|
+
addClass(classes, item);
|
|
125
|
+
}
|
|
126
|
+
attrs.class = classes.join(" ");
|
|
127
|
+
}
|
|
128
|
+
if (this.options.s) {
|
|
129
|
+
attrs.style = this.processStyles();
|
|
130
|
+
}
|
|
131
|
+
const attrStr = this.attrString(attrs);
|
|
132
|
+
if (this.children.length === 0) {
|
|
133
|
+
return `${this.level(level)}<${this.name}${attrStr}/>`;
|
|
134
|
+
}
|
|
135
|
+
let prevWasText = false;
|
|
136
|
+
let result = [`${this.level(level)}<${this.name}${attrStr}>\n`];
|
|
137
|
+
this.children.forEach(item => {
|
|
138
|
+
const currentIsText = item instanceof Text;
|
|
139
|
+
const content = currentIsText
|
|
140
|
+
? item.toHTML(!prevWasText ? level + 1 : 0)
|
|
141
|
+
: (prevWasText ? "\n" : "") + item.toHTML(level + 1) + "\n";
|
|
142
|
+
if (!(item instanceof Text && item.isEmpty())) {
|
|
143
|
+
prevWasText = currentIsText;
|
|
144
|
+
result.push(content);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
if (prevWasText) {
|
|
148
|
+
result.push("\n");
|
|
149
|
+
}
|
|
150
|
+
result.push(`${this.level(level)}</${this.name}>`);
|
|
151
|
+
return result.join("");
|
|
152
|
+
}
|
|
153
|
+
toMarkDown(supportHtml) {
|
|
154
|
+
const children = (fn = (v, _index) => v) => {
|
|
155
|
+
return this.children.map((item, index) => fn(item.toMarkDown(supportHtml), index)).join("");
|
|
156
|
+
};
|
|
157
|
+
const attrs = this.options.a ?? {};
|
|
158
|
+
const headingId = () => {
|
|
159
|
+
if (attrs.id) {
|
|
160
|
+
return ` {#${attrs.id}}`;
|
|
161
|
+
}
|
|
162
|
+
return "";
|
|
163
|
+
};
|
|
164
|
+
switch (this.name.toLowerCase()) {
|
|
165
|
+
case "h1":
|
|
166
|
+
console.log(children(), headingId());
|
|
167
|
+
return `\n# ${children()}${headingId()}\n`;
|
|
168
|
+
case "h2":
|
|
169
|
+
return `\n## ${children()}${headingId()}\n`;
|
|
170
|
+
case "h3":
|
|
171
|
+
return `\n### ${children()}${headingId()}\n`;
|
|
172
|
+
case "b":
|
|
173
|
+
return `**${children()}**`;
|
|
174
|
+
case "i":
|
|
175
|
+
return `*${children()}*`;
|
|
176
|
+
case "blockquote":
|
|
177
|
+
return `\n> ${children().replace("\n", "\n> ")}\n`;
|
|
178
|
+
case "pre":
|
|
179
|
+
return `\n\`\`\`\n${children()}\n\`\`\``;
|
|
180
|
+
case "code":
|
|
181
|
+
return `\`${children()}\``;
|
|
182
|
+
case "ol":
|
|
183
|
+
return `\n${children((v, index) => `\n${index + 1}. ${v}`)}`;
|
|
184
|
+
case "ul":
|
|
185
|
+
return `\n${children((v, index) => `\n- ${v}`)}`;
|
|
186
|
+
case "hr":
|
|
187
|
+
return `\n---\n`;
|
|
188
|
+
case "a":
|
|
189
|
+
return `[${children()}](${attrs.href})`;
|
|
190
|
+
case "img":
|
|
191
|
+
return ``;
|
|
192
|
+
case "dt":
|
|
193
|
+
return `\n\n${children()}`;
|
|
194
|
+
case "dd":
|
|
195
|
+
return `\n: ${children()}`;
|
|
196
|
+
case "del":
|
|
197
|
+
return `~~${children()}~~`;
|
|
198
|
+
case "mark":
|
|
199
|
+
return `==${children()}==`;
|
|
200
|
+
case "sub":
|
|
201
|
+
return `~${children()}~`;
|
|
202
|
+
case "sup":
|
|
203
|
+
return `^${children()}^`;
|
|
204
|
+
case "input":
|
|
205
|
+
if (attrs.type === "checkbox") {
|
|
206
|
+
return `[${attrs.checked ? "x" : " "}] `;
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
case "p":
|
|
210
|
+
case "article":
|
|
211
|
+
case "aside":
|
|
212
|
+
case "details":
|
|
213
|
+
case "header":
|
|
214
|
+
case "footer":
|
|
215
|
+
case "main":
|
|
216
|
+
case "nav":
|
|
217
|
+
case "section":
|
|
218
|
+
case "summary":
|
|
219
|
+
return `\n\n${children()}\n\n`;
|
|
220
|
+
case "table": {
|
|
221
|
+
let head = this.children.find(child => {
|
|
222
|
+
return child instanceof Element && child.name.toLowerCase() === "thead";
|
|
223
|
+
});
|
|
224
|
+
let body = this.children.find(child => {
|
|
225
|
+
return child instanceof Element && child.name.toLowerCase() === "tbody";
|
|
226
|
+
});
|
|
227
|
+
let firstChild = head?.children[0] ?? this.children[0];
|
|
228
|
+
const firstChildIsTr = firstChild instanceof Element && firstChild.name.toLowerCase() === "tr";
|
|
229
|
+
if (firstChildIsTr) {
|
|
230
|
+
const number = firstChild.children.length;
|
|
231
|
+
const headRows = head?.toMarkDown(supportHtml);
|
|
232
|
+
const bodyRows = body
|
|
233
|
+
? body.toMarkDown(supportHtml)
|
|
234
|
+
: this.children
|
|
235
|
+
.slice(1)
|
|
236
|
+
.map(item => item.toMarkDown(supportHtml))
|
|
237
|
+
.join("");
|
|
238
|
+
const separator = "\n" + "| - ".repeat(number) + "|";
|
|
239
|
+
return `\n${headRows ?? separator}${separator}${bodyRows}`;
|
|
240
|
+
}
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
case "thead":
|
|
244
|
+
case "tbody":
|
|
245
|
+
return children();
|
|
246
|
+
case "tr":
|
|
247
|
+
return `\n| ${children().trim()}`;
|
|
248
|
+
case "th":
|
|
249
|
+
case "td":
|
|
250
|
+
return `${children()} | `;
|
|
251
|
+
case "br":
|
|
252
|
+
return "\n\n";
|
|
253
|
+
case "body":
|
|
254
|
+
return children();
|
|
255
|
+
}
|
|
256
|
+
if (supportHtml) {
|
|
257
|
+
const attrs = this.processAttrs();
|
|
258
|
+
const styles = this.processStyles();
|
|
259
|
+
if (styles) {
|
|
260
|
+
attrs.style = styles;
|
|
261
|
+
}
|
|
262
|
+
return `<${this.name}${this.attrString(attrs)}>${children()}</${this.name}>`;
|
|
263
|
+
}
|
|
264
|
+
return children();
|
|
265
|
+
}
|
|
266
|
+
attrString(attrs) {
|
|
267
|
+
const string = Object.entries(attrs)
|
|
268
|
+
.map(([name, attr]) => {
|
|
269
|
+
return attr === "" ? name : `${name}="${escapeHTML(`${attr}`).replace(/"/g, """)}"`;
|
|
270
|
+
})
|
|
271
|
+
.join(" ");
|
|
272
|
+
return string ? " " + string : string;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
export class SsgTextNode extends TextNode {
|
|
276
|
+
compose() {
|
|
277
|
+
this.node = new Text(this.data);
|
|
278
|
+
this.parent.appendNode(this.node);
|
|
279
|
+
}
|
|
280
|
+
findFirstChild() {
|
|
281
|
+
return this.node;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
export class SsgTag extends Tag {
|
|
285
|
+
compose() {
|
|
286
|
+
this.node = new Element(this.name, this.options);
|
|
287
|
+
this.parent.appendNode(this.node);
|
|
288
|
+
this.applyOptions(this.options);
|
|
289
|
+
}
|
|
290
|
+
applyOptions(options) {
|
|
291
|
+
options.slot?.(this);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
class HeadTag extends SsgTag {
|
|
295
|
+
compose() {
|
|
296
|
+
this.node = this.runner.head;
|
|
297
|
+
this.applyOptions(this.options);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
class BodyTag extends SsgTag {
|
|
301
|
+
compose() {
|
|
302
|
+
this.node = this.runner.body;
|
|
303
|
+
for (const key in this.options) {
|
|
304
|
+
this.node.options[key] = this.options[key];
|
|
305
|
+
}
|
|
306
|
+
this.applyOptions(this.options);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
export class SsgRunner {
|
|
310
|
+
constructor(head, body) {
|
|
311
|
+
this.head = head;
|
|
312
|
+
this.body = body;
|
|
313
|
+
}
|
|
314
|
+
insertBefore(node, before) {
|
|
315
|
+
const { parent } = before;
|
|
316
|
+
/* istanbul ignore else */
|
|
317
|
+
if (parent) {
|
|
318
|
+
parent.insertBefore(node, before);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
appendChild(node, child) {
|
|
322
|
+
node.appendChild(child);
|
|
323
|
+
}
|
|
324
|
+
textNode(deep, text) {
|
|
325
|
+
return new SsgTextNode({ text }, this, deep);
|
|
326
|
+
}
|
|
327
|
+
tag(deep, tagName, input, cb) {
|
|
328
|
+
if (cb) {
|
|
329
|
+
input.slot = cb;
|
|
330
|
+
}
|
|
331
|
+
return tagName === "head"
|
|
332
|
+
? new HeadTag(input, this, tagName, deep)
|
|
333
|
+
: tagName === "body"
|
|
334
|
+
? new BodyTag(input, this, tagName, deep)
|
|
335
|
+
: new SsgTag(input, this, tagName, deep);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type { WebRouterInitialization, NavigationMode, WebRouter } from "../web/router/router.js";
|
|
2
|
+
export type { WebTagOptions, AttrType, StyleType } from "../web/runner/runner.js";
|
|
3
|
+
export type { ClassItem } from "../web/jsx/jsx-runtime.js";
|
|
4
|
+
export type { ElementStyleProps, StyleSheetProps } from "../web/jsx/spec/css.js";
|
|
5
|
+
export type { WebComponent, WebComponentAdapter, WebComponentAttributes, WebComponentEvents, WebComponentEventHandler, WebComponentProps, } from "../shadow/types.js";
|
|
6
|
+
export type { Mode as SsgRouterMode } from "../ssg/router.js";
|
|
7
|
+
export type { AppSide, IdeSide } from "../dev/communication.js";
|
|
8
|
+
export type { PromptProps } from "../web/mount.js";
|
|
9
|
+
export type { CssStyleInjector } from "../web/css/index.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { setMobileMaxWidth, setTabletMaxWidth, setLaptopMaxWidth, mobileMaxWidth, tabletMaxWidth, laptopMaxWidth, } from "./lib.js";
|
|
2
|
+
export declare class CssStyleInjector {
|
|
3
|
+
protected className: string | null;
|
|
4
|
+
protected styles: (string | [number, string])[];
|
|
5
|
+
constructor(styles: (string | [number, string])[]);
|
|
6
|
+
inject(): string;
|
|
7
|
+
protected generateClassName(): string;
|
|
8
|
+
protected insertRule(rule: string | [number, string], className: string): void;
|
|
9
|
+
}
|
|
10
|
+
export declare class SafeCssStyleInjector extends CssStyleInjector {
|
|
11
|
+
protected insertRule(rule: string | [number, string], className: string): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Inserts stylesheet to document
|
|
15
|
+
* @param styles CSS styles based on classes
|
|
16
|
+
*/
|
|
17
|
+
export declare function styleSheet<T extends {
|
|
18
|
+
[k: string]: (string | [number, string])[];
|
|
19
|
+
}>(styles: T): {
|
|
20
|
+
[K in keyof T]: CssStyleInjector;
|
|
21
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { insertRule } from "./lib.js";
|
|
2
|
+
export { setMobileMaxWidth, setTabletMaxWidth, setLaptopMaxWidth, mobileMaxWidth, tabletMaxWidth, laptopMaxWidth, } from "./lib.js";
|
|
3
|
+
let index = 1;
|
|
4
|
+
export class CssStyleInjector {
|
|
5
|
+
constructor(styles) {
|
|
6
|
+
this.className = null;
|
|
7
|
+
this.styles = styles;
|
|
8
|
+
}
|
|
9
|
+
inject() {
|
|
10
|
+
if (this.className) {
|
|
11
|
+
return this.className;
|
|
12
|
+
}
|
|
13
|
+
const className = this.generateClassName();
|
|
14
|
+
for (const item of this.styles) {
|
|
15
|
+
this.insertRule(item, className);
|
|
16
|
+
}
|
|
17
|
+
this.styles.splice(0);
|
|
18
|
+
return (this.className = className);
|
|
19
|
+
}
|
|
20
|
+
generateClassName() {
|
|
21
|
+
return `vasille-${++index}`;
|
|
22
|
+
}
|
|
23
|
+
insertRule(rule, className) {
|
|
24
|
+
if (rule instanceof Array) {
|
|
25
|
+
insertRule(rule[0], rule[1].replace("{}", className));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
insertRule(0, rule.replace("{}", className));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class SafeCssStyleInjector extends CssStyleInjector {
|
|
33
|
+
insertRule(rule, className) {
|
|
34
|
+
try {
|
|
35
|
+
super.insertRule(rule, className);
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
// ignore any style related errors
|
|
39
|
+
void e;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Inserts stylesheet to document
|
|
45
|
+
* @param styles CSS styles based on classes
|
|
46
|
+
*/
|
|
47
|
+
export function styleSheet(styles) {
|
|
48
|
+
const result = {};
|
|
49
|
+
for (const key in styles) {
|
|
50
|
+
result[key] = new SafeCssStyleInjector(styles[key]);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare let mobile: CSSStyleSheet | undefined;
|
|
2
|
+
export declare let tablet: CSSStyleSheet | undefined;
|
|
3
|
+
export declare let desktop: CSSStyleSheet | undefined;
|
|
4
|
+
export declare let mobileMaxWidth: number;
|
|
5
|
+
export declare let tabletMaxWidth: number;
|
|
6
|
+
export declare let laptopMaxWidth: number;
|
|
7
|
+
export declare function setMobileMaxWidth(value: number): void;
|
|
8
|
+
export declare function setTabletMaxWidth(value: number): void;
|
|
9
|
+
export declare function setLaptopMaxWidth(value: number): void;
|
|
10
|
+
export declare function insertRule(target: number, rule: string): void;
|