Skip to content

Commit

Permalink
feat: split match info and context interface
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Mar 15, 2022
1 parent 8b5012b commit 4b0f3b1
Show file tree
Hide file tree
Showing 45 changed files with 466 additions and 475 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -144,9 +144,9 @@ import type { CSSMap } from "https://deno.land/x/mapcss@$VERSION/mod.ts";
const rePositiveNumber = /^(\d+)$/;
const cssMap: CSSMap = {
z: {
"*": (match) => {
"*": ({ id }) => {
// It actually checks the validity of the numbers
const regExpExecResult = rePositiveNumber.exec(match);
const regExpExecResult = rePositiveNumber.exec(id);
if (regExpExecResult) {
return { zIndex: Number(regExpExecResult[1]) };
}
Expand Down
2 changes: 0 additions & 2 deletions core/generate.ts
Expand Up @@ -131,7 +131,6 @@ export function generate(
{
...staticContext,
...runtimeContext,
identifier,
},
);

Expand All @@ -142,7 +141,6 @@ export function generate(
return resolveModifierMap(cur, modifierMaps, acc, {
...staticContext,
...runtimeContext,
modifier: cur,
});
}, identifierRoot as Root | undefined);

Expand Down
158 changes: 77 additions & 81 deletions core/resolve.ts
Expand Up @@ -8,7 +8,6 @@ import {
isString,
isUndefined,
last,
PartialByKeys,
prop,
propPath,
Root,
Expand All @@ -19,13 +18,13 @@ import {
import { isBlockDefinition, isCSSDefinition, isRoot } from "./utils/assert.ts";
import type {
CSSMap,
IdentifierContext,
IdentifierDefinition,
ModifierContext,
MatchInfo,
ModifierDefinition,
ModifierMap,
PreProcessor,
Preset,
RuntimeContext,
StaticConfig,
StaticContext,
Syntax,
Expand Down Expand Up @@ -60,62 +59,58 @@ function leftSplit(
}

export function resolveCSSMap(
value: Arrayable<string>,
value: string,
cssMap: Arrayable<Readonly<CSSMap>>,
context: Readonly<Omit<IdentifierContext, "parentKey" | "path">>,
context: Readonly<StaticContext & RuntimeContext>,
): Root | undefined {
for (const map of wrap(cssMap)) {
const paths = leftSplit(value, context.separator);
for (const path of paths) {
const first = head(path);
const cssMapContext = makeCSSContext(context, { key: first, path });
const _resolve = (
path: Arrayable<string>,
cssMap: Arrayable<Readonly<CSSMap>>,
): Root | undefined => {
for (const map of wrap(cssMap)) {
const paths = leftSplit(path, context.separator);
for (const path of paths) {
const first = head(path);
const matchInfo: MatchInfo = {
fullPath: value,
path,
id: first ?? "",
parentId: first,
};

const maybeDefinition = prop(first ?? "", map) as
| IdentifierDefinition
| undefined ?? prop("*", map);
const maybeDefinition = prop(first ?? "", map) as
| IdentifierDefinition
| undefined ?? prop("*", map);

const resolve = (
value: IdentifierDefinition | undefined,
): Root | undefined => {
if (isUndefined(value)) return;
const resolve = (
value: IdentifierDefinition | undefined,
): Root | undefined => {
if (isUndefined(value)) return;

if (isFunction(value)) {
return resolve(value(first ?? "", cssMapContext));
} else if (isCSSDefinition(value)) {
return toAST(value.value);
} else if (isRoot(value)) {
return value;
} else if (isBlockDefinition(value)) {
return toAST({
[context.className]: value,
});
} else {
const rest = tail(path);
return resolveCSSMap(rest, value, cssMapContext);
}
};
if (isFunction(value)) {
return resolve(value(matchInfo, context));
} else if (isCSSDefinition(value)) {
return toAST(value.value);
} else if (isRoot(value)) {
return value;
} else if (isBlockDefinition(value)) {
return toAST({
[context.className]: value,
});
} else {
const rest = tail(path);
return _resolve(rest, value);
}
};

const result = resolve(maybeDefinition);
if (isUndefined(result)) continue;
return result;
const result = resolve(maybeDefinition);
if (isUndefined(result)) continue;
return result;
}
}
}
}

function makeCSSContext(
baseContext: Readonly<
(
& Omit<IdentifierContext, "parentKey" | "path">
& { parentKey?: string; path?: string[] }
)
>,
{ key, path }: Readonly<{ key?: string; path: string[] }>,
): IdentifierContext {
return {
...baseContext,
parentKey: baseContext.parentKey ?? key,
path: baseContext.path?.length ? baseContext.path : path,
};

return _resolve(value, cssMap);
}

/** resolve theme via propPath safety */
Expand Down Expand Up @@ -263,44 +258,45 @@ export function resolveConfig(
}

export function resolveModifierMap(
modifier: Arrayable<string>,
fullPath: string,
modifierMap: Arrayable<Readonly<ModifierMap>>,
parentNode: Readonly<Root>,
context: Readonly<PartialByKeys<ModifierContext, "path">>,
context: Readonly<StaticContext & RuntimeContext>,
): Root | undefined {
for (const map of wrap(modifierMap)) {
const paths = leftSplit(modifier, context.separator);
const _resolve = (
path: Arrayable<string>,
modifierMap: Arrayable<Readonly<ModifierMap>>,
): Root | undefined => {
for (const map of wrap(modifierMap)) {
const paths = leftSplit(path, context.separator);

for (const path of paths) {
const _head = head(path);
const ctx = makeModifierContext(context, { path });
for (const path of paths) {
const _head = head(path);
const matchInfo: MatchInfo = {
id: _head ?? "",
parentId: _head,
fullPath,
path,
};

const modifier = prop(_head ?? "", map) as
| ModifierDefinition
| undefined;
if (isUndefined(modifier)) continue;
const modifier = prop(_head ?? "", map) as
| ModifierDefinition
| undefined;
if (isUndefined(modifier)) continue;

if (isFunction(modifier)) {
const maybeRoot = modifier(parentNode, _head ?? "", ctx);
if (isUndefined(maybeRoot)) continue;
return maybeRoot;
}
const rest = tail(path);
if (isFunction(modifier)) {
const maybeRoot = modifier(parentNode, matchInfo, context);
if (isUndefined(maybeRoot)) continue;
return maybeRoot;
}
const rest = tail(path);

const result = resolveModifierMap(rest, modifier, parentNode, ctx);
if (result) {
return result;
const result = _resolve(rest, modifier);
if (result) {
return result;
}
}
}
}
}

function makeModifierContext(
baseContext: Readonly<PartialByKeys<ModifierContext, "path">>,
{ path }: Readonly<{ key?: string; path: string[] }>,
): ModifierContext {
return {
...baseContext,
path: baseContext.path?.length ? baseContext.path : path,
};
return _resolve(fullPath, modifierMap);
}
49 changes: 19 additions & 30 deletions core/resolve_test.ts
@@ -1,47 +1,36 @@
import { expect, test } from "../dev_deps.ts";
import { resolveCSSMap } from "./resolve.ts";
import { Root } from "../deps.ts";
import type { BinaryTree, CSSMap, IdentifierContext } from "./types.ts";
import { createContext } from "../utils/context.ts";
import type {
BinaryTree,
CSSMap,
RuntimeContext,
StaticContext,
} from "./types.ts";

const block = { display: "block" };
const inlineBlock = { display: "inline-block" };

function createCSSMapContext(
context: Partial<IdentifierContext> = {},
): IdentifierContext {
return {
separator: "-",
charMap: {},
token: "class-name",
className: ".class-name",
identifier: "class-name",
mappedToken: "class-name",
theme: {},
variablePrefix: "map-",
parentKey: "",
path: [],
...context,
};
}
test("resolveCSSMap", () => {
const table: [
string,
CSSMap,
IdentifierContext,
StaticContext & RuntimeContext,
BinaryTree<string | number> | undefined,
][] = [
[
"block",
{ block: block },
createCSSMapContext({ className: ".block" }),
createContext({ className: ".block" }),
{
".block": block,
},
],
[
"block",
{ block: { "": block } },
createCSSMapContext({ className: ".block" }),
createContext({ className: ".block" }),
{
".block": block,
},
Expand All @@ -51,7 +40,7 @@ test("resolveCSSMap", () => {
{
inline: { block: { display: "inline-block" } },
},
createCSSMapContext({ className: ".inline-block" }),
createContext({ className: ".inline-block" }),
{
".inline-block": { display: "inline-block" },
},
Expand All @@ -61,7 +50,7 @@ test("resolveCSSMap", () => {
{
inline: { block: { "": inlineBlock } },
},
createCSSMapContext({ className: ".inline-block" }),
createContext({ className: ".inline-block" }),
{
".inline-block": inlineBlock,
},
Expand All @@ -71,13 +60,13 @@ test("resolveCSSMap", () => {
{
inline: { block: inlineBlock },
},
createCSSMapContext({ className: ".inline-block" }),
createContext({ className: ".inline-block" }),
undefined,
],
[
"block",
{ block: { type: "css", value: { ".block": block } } },
createCSSMapContext(),
createContext(),
{ ".block": block },
],
[
Expand All @@ -87,20 +76,20 @@ test("resolveCSSMap", () => {
"": { type: "css", value: { ".block": block } },
},
},
createCSSMapContext(),
createContext(),
{ ".block": block },
],
["block", { block: new Root({ nodes: [] }) }, createCSSMapContext(), {}],
["block", { block: new Root({ nodes: [] }) }, createContext(), {}],
[
"block",
{ block: () => block },
createCSSMapContext({ className: ".test" }),
createContext({ className: ".test" }),
{ ".test": block },
],
[
"block",
{ block: { "": () => block } },
createCSSMapContext({ className: ".test" }),
createContext({ className: ".test" }),
{ ".test": block },
],
[
Expand All @@ -112,7 +101,7 @@ test("resolveCSSMap", () => {
}),
},
},
createCSSMapContext({ className: ".test" }),
createContext({ className: ".test" }),
{ ".test": { "--map-test": "test" } },
],
];
Expand Down

0 comments on commit 4b0f3b1

Please sign in to comment.