@unocss/core
Advanced tools
Comparing version 0.4.16 to 0.5.0
@@ -10,3 +10,3 @@ declare class UnoGenerator { | ||
applyExtractors(code: string, id?: string, set?: Set<string>): Promise<Set<string>>; | ||
generate(input: string | Set<string>, id?: string, scope?: string): Promise<GenerateResult>; | ||
generate(input: string | Set<string>, { id, scope, preflights, layerComments, }?: GenerateOptions): Promise<GenerateResult>; | ||
matchVariants(raw: string): VariantMatchedResult; | ||
@@ -17,4 +17,4 @@ applyVariants(parsed: ParsedUtil, variantHandlers?: VariantHandler[], raw?: string): readonly [string, CSSEntries, string | undefined]; | ||
stringifyUtil(parsed?: ParsedUtil | RawUtil): StringifiedUtil | undefined; | ||
expandShortcut(processed: string, depth?: number): string[] | undefined; | ||
stringifyShortcuts(parent: VariantMatchedResult, expanded: string[]): Promise<StringifiedUtil[]>; | ||
expandShortcut(processed: string, depth?: number): [string[], RuleMeta | undefined] | undefined; | ||
stringifyShortcuts(parent: VariantMatchedResult, expanded: string[], meta: RuleMeta | undefined): Promise<StringifiedUtil[] | undefined>; | ||
isExcluded(raw: string): boolean; | ||
@@ -63,10 +63,19 @@ } | ||
declare type Extractor = (code: string, id?: string) => Awaitable<Set<string> | undefined>; | ||
declare type DynamicRule<Theme extends {} = {}> = [RegExp, ((match: string[], context: Readonly<RuleContext<Theme>>) => Awaitable<CSSObject | CSSEntries | string | undefined>)]; | ||
declare type StaticRule = [string, CSSObject | CSSEntries]; | ||
interface RuleMeta { | ||
layer?: string; | ||
} | ||
declare type DynamicMatcher<Theme extends {} = {}> = ((match: string[], context: Readonly<RuleContext<Theme>>) => Awaitable<CSSObject | CSSEntries | string | undefined>); | ||
declare type DynamicRule<Theme extends {} = {}> = [RegExp, DynamicMatcher<Theme>] | [RegExp, DynamicMatcher<Theme>, RuleMeta]; | ||
declare type StaticRule = [string, CSSObject | CSSEntries] | [string, CSSObject | CSSEntries, RuleMeta]; | ||
declare type Rule<Theme extends {} = {}> = DynamicRule<Theme> | StaticRule; | ||
declare type DynamicShortcut = [RegExp, ((match: string[]) => (string | string[] | undefined))]; | ||
declare type StaticShortcut = [string, string | string[]]; | ||
declare type DynamicShortcutMatcher = ((match: string[]) => (string | string[] | undefined)); | ||
declare type DynamicShortcut = [RegExp, DynamicShortcutMatcher] | [RegExp, DynamicShortcutMatcher, RuleMeta]; | ||
declare type StaticShortcut = [string, string | string[]] | [string, string | string[], RuleMeta]; | ||
declare type StaticShortcutMap = Record<string, string | string[]>; | ||
declare type UserShortcuts = StaticShortcutMap | (StaticShortcut | DynamicShortcut | StaticShortcutMap)[]; | ||
declare type Shortcut = StaticShortcut | DynamicShortcut; | ||
interface Preflight { | ||
getCSS: () => string | undefined; | ||
layer?: string; | ||
} | ||
declare type ExcludeRule = string | RegExp; | ||
@@ -131,5 +140,17 @@ interface VariantHandler { | ||
/** | ||
* Raw CSS injections. | ||
*/ | ||
preflights?: Preflight[]; | ||
/** | ||
* Theme object for shared configuration between rules | ||
*/ | ||
theme?: Theme; | ||
/** | ||
* Layer orders. Default to 0. | ||
*/ | ||
layers?: Record<string, number>; | ||
/** | ||
* Custom function to sort layers. | ||
*/ | ||
sortLayers?: (layers: string[]) => string[]; | ||
} | ||
@@ -166,29 +187,57 @@ interface Preset extends ConfigBase { | ||
rulesDynamic: (DynamicRule | undefined)[]; | ||
rulesStaticMap: Record<string, [number, CSSObject | CSSEntries] | undefined>; | ||
rulesStaticMap: Record<string, [number, CSSObject | CSSEntries, RuleMeta | undefined] | undefined>; | ||
} | ||
interface GenerateResult { | ||
css: string; | ||
layers: string[]; | ||
getLayer(name?: string): string | undefined; | ||
getLayers(excludes?: string[]): string; | ||
matched: Set<string>; | ||
} | ||
declare type VariantMatchedResult = readonly [ | ||
string, | ||
string, | ||
VariantHandler[] | ||
raw: string, | ||
current: string, | ||
variants: VariantHandler[] | ||
]; | ||
declare type ParsedUtil = readonly [ | ||
number, | ||
string, | ||
CSSEntries, | ||
VariantHandler[] | ||
index: number, | ||
raw: string, | ||
entries: CSSEntries, | ||
meta: RuleMeta | undefined, | ||
variants: VariantHandler[] | ||
]; | ||
declare type RawUtil = readonly [ | ||
number, | ||
string | ||
index: number, | ||
rawCSS: string, | ||
meta: RuleMeta | undefined | ||
]; | ||
declare type StringifiedUtil = readonly [ | ||
number, | ||
string | undefined, | ||
string, | ||
string | undefined | ||
index: number, | ||
selector: string | undefined, | ||
body: string, | ||
mediaQuery: string | undefined, | ||
meta: RuleMeta | undefined | ||
]; | ||
interface GenerateOptions { | ||
/** | ||
* Filepath of the file being processed. | ||
*/ | ||
id?: string; | ||
/** | ||
* Generate preflights (if defined) | ||
* | ||
* @default true | ||
*/ | ||
preflights?: boolean; | ||
/** | ||
* @expiremental | ||
*/ | ||
scope?: string; | ||
/** | ||
* Show layer seperator in comments | ||
* | ||
* @default true | ||
*/ | ||
layerComments?: boolean; | ||
} | ||
@@ -235,4 +284,6 @@ declare function escapeRegExp(string: string): string; | ||
declare function withLayer<T>(layer: string, rules: Rule<T>[]): Rule<T>[]; | ||
declare const extractorSplit: Extractor; | ||
export { ArgumentType, Awaitable, BetterMap, CSSEntries, CSSObject, ConfigBase, DeepPartial, DynamicRule, DynamicShortcut, ExcludeRule, Extractor, GenerateResult, GeneratorOptions, ParsedUtil, Preset, RawUtil, ResolvedConfig, RestArgs, Rule, RuleContext, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserShortcuts, Variant, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, createGenerator, e, entriesToCss, escapeRegExp, escapeSelector, extractorSplit, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeVariant, toArray, uniq, validateFilterRE }; | ||
export { ArgumentType, Awaitable, BetterMap, CSSEntries, CSSObject, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, ExcludeRule, Extractor, GenerateOptions, GenerateResult, GeneratorOptions, ParsedUtil, Preflight, Preset, RawUtil, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserShortcuts, Variant, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, createGenerator, e, entriesToCss, escapeRegExp, escapeSelector, extractorSplit, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeVariant, toArray, uniq, validateFilterRE, withLayer }; |
@@ -34,3 +34,4 @@ var __defProp = Object.defineProperty; | ||
uniq: () => uniq, | ||
validateFilterRE: () => validateFilterRE | ||
validateFilterRE: () => validateFilterRE, | ||
withLayer: () => withLayer | ||
}); | ||
@@ -151,3 +152,3 @@ | ||
var attributifyRE = /^\[(.+?)~?="(.*)"\]$/; | ||
var validateFilterRE = /[a-z]/; | ||
var validateFilterRE = /[a-z?]/; | ||
function isAttributifySelector(selector) { | ||
@@ -163,3 +164,3 @@ return selector.match(attributifyRE); | ||
function isRawUtil(util) { | ||
return util.length === 2; | ||
return util.length === 3; | ||
} | ||
@@ -223,2 +224,13 @@ | ||
// src/utils/layer.ts | ||
function withLayer(layer, rules) { | ||
rules.forEach((r) => { | ||
if (!r[2]) | ||
r[2] = { layer }; | ||
else | ||
r[2].layer = layer; | ||
}); | ||
return rules; | ||
} | ||
// src/extractors/split.ts | ||
@@ -243,2 +255,3 @@ var extractorSplit = (code) => new Set(code.split(/[\s'"`;>=]+/g).filter(isValidSelector)); | ||
]; | ||
const layers = Object.assign({}, ...rawPresets.map((i) => i.layers), userConfig.layers); | ||
function mergePresets(key) { | ||
@@ -258,3 +271,3 @@ return uniq([ | ||
if (isStaticRule(rule)) { | ||
rulesStaticMap[rule[0]] = [i, rule[1]]; | ||
rulesStaticMap[rule[0]] = [i, rule[1], rule[2]]; | ||
delete rules[i]; | ||
@@ -271,3 +284,5 @@ } | ||
excluded: [], | ||
sortLayers: (layers2) => layers2, | ||
...config, | ||
layers, | ||
theme, | ||
@@ -277,2 +292,3 @@ rulesSize, | ||
rulesStaticMap, | ||
preflights: mergePresets("preflights"), | ||
variants: mergePresets("variants").map(normalizeVariant), | ||
@@ -310,7 +326,14 @@ shortcuts: resolveShortcuts(mergePresets("shortcuts")), | ||
} | ||
async generate(input, id, scope) { | ||
async generate(input, { | ||
id, | ||
scope, | ||
preflights = true, | ||
layerComments = true | ||
} = {}) { | ||
const tokens = typeof input === "string" ? await this.applyExtractors(input, id) : input; | ||
const layerSet = new Set(["default"]); | ||
const matched = new Set(); | ||
const sheet = new Map(); | ||
const hit = (raw, payload) => { | ||
var _a; | ||
this._cache.set(raw, payload); | ||
@@ -323,2 +346,4 @@ matched.add(raw); | ||
sheet.get(query).push(item); | ||
if ((_a = item[4]) == null ? void 0 : _a.layer) | ||
layerSet.add(item[4].layer); | ||
} | ||
@@ -347,5 +372,5 @@ }; | ||
const expanded = this.expandShortcut(applied[1]); | ||
if (expanded == null ? void 0 : expanded.length) { | ||
const utils = await this.stringifyShortcuts(applied, expanded); | ||
if (utils.length) { | ||
if (expanded) { | ||
const utils = await this.stringifyShortcuts(applied, expanded[0], expanded[1]); | ||
if (utils == null ? void 0 : utils.length) { | ||
hit(raw, utils); | ||
@@ -363,26 +388,62 @@ return; | ||
})); | ||
const css = Array.from(sheet).map(([query, items]) => { | ||
const size = items.length; | ||
const sorted = items.sort((a, b) => { | ||
var _a; | ||
return a[0] - b[0] || ((_a = a[1]) == null ? void 0 : _a.localeCompare(b[1] || "")) || 0; | ||
}).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]); | ||
const rules = sorted.map(([selector, body], idx) => { | ||
if (selector && this.config.mergeSelectors) { | ||
for (let i = size - 1; i > idx; i--) { | ||
const current = sorted[i]; | ||
if (current[0] && current[1] === body) { | ||
current[0] = `${selector},${current[0]}`; | ||
return null; | ||
if (preflights) { | ||
this.config.preflights.forEach((i) => { | ||
if (i.layer) | ||
layerSet.add(i.layer); | ||
}); | ||
} | ||
const layerCache = {}; | ||
const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => { | ||
var _a, _b; | ||
return ((_a = this.config.layers[a]) != null ? _a : 0) - ((_b = this.config.layers[b]) != null ? _b : 0) || a.localeCompare(b); | ||
})); | ||
const getLayer = (layer) => { | ||
if (layerCache[layer]) | ||
return layerCache[layer]; | ||
let css = Array.from(sheet).map(([query, items]) => { | ||
const size = items.length; | ||
const sorted = items.filter((i) => { | ||
var _a; | ||
return (((_a = i[4]) == null ? void 0 : _a.layer) || "default") === layer; | ||
}).sort((a, b) => { | ||
var _a; | ||
return a[0] - b[0] || ((_a = a[1]) == null ? void 0 : _a.localeCompare(b[1] || "")) || 0; | ||
}).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]); | ||
if (!sorted.length) | ||
return void 0; | ||
const rules = sorted.map(([selector, body], idx) => { | ||
if (selector && this.config.mergeSelectors) { | ||
for (let i = size - 1; i > idx; i--) { | ||
const current = sorted[i]; | ||
if (current && current[0] && current[1] === body) { | ||
current[0] = `${selector},${current[0]}`; | ||
return null; | ||
} | ||
} | ||
} | ||
} | ||
return selector ? `${selector}{${body}}` : body; | ||
}).filter(Boolean).join("\n"); | ||
return query ? `${query}{ | ||
return selector ? `${selector}{${body}}` : body; | ||
}).filter(Boolean).join("\n"); | ||
return query ? `${query}{ | ||
${rules} | ||
}` : rules; | ||
}).join("\n"); | ||
}).filter(Boolean).join("\n"); | ||
if (preflights) { | ||
css = [ | ||
...this.config.preflights.filter((i) => (i.layer || "default") === layer).map((i) => i.getCSS()).filter(Boolean), | ||
css | ||
].join("\n"); | ||
} | ||
return layerCache[layer] = layerComments ? `/* layer: ${layer} */ | ||
${css}` : css; | ||
}; | ||
const getLayers = (excludes) => { | ||
return layers.filter((i) => !(excludes == null ? void 0 : excludes.includes(i))).map((i) => getLayer(i) || "").join("\n"); | ||
}; | ||
return { | ||
css, | ||
get css() { | ||
return getLayers(); | ||
}, | ||
layers, | ||
getLayers, | ||
getLayer, | ||
matched | ||
@@ -421,3 +482,3 @@ }; | ||
} | ||
applyVariants(parsed, variantHandlers = parsed[3], raw = parsed[1]) { | ||
applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) { | ||
const selector = variantHandlers.reduce((p, v) => { | ||
@@ -440,3 +501,3 @@ var _a; | ||
body = normalizeEntries(body); | ||
const [selector, entries, mediaQuery] = this.applyVariants([0, overrideSelector || context.rawSelector, body, context.variantHandlers]); | ||
const [selector, entries, mediaQuery] = this.applyVariants([0, overrideSelector || context.rawSelector, body, void 0, context.variantHandlers]); | ||
const cssBody = `${selector}{${entriesToCss(entries)}}`; | ||
@@ -452,3 +513,3 @@ if (mediaQuery) | ||
if (staticMatch == null ? void 0 : staticMatch[1]) | ||
return [staticMatch[0], raw, normalizeEntries(staticMatch[1]), variantHandlers]; | ||
return [staticMatch[0], raw, normalizeEntries(staticMatch[1]), staticMatch[2], variantHandlers]; | ||
const context = { | ||
@@ -466,3 +527,3 @@ rawSelector: raw, | ||
continue; | ||
const [matcher, handler] = rule; | ||
const [matcher, handler, meta] = rule; | ||
const match = processed.match(matcher); | ||
@@ -473,5 +534,5 @@ if (!match) | ||
if (typeof result === "string") | ||
return [i, result]; | ||
return [i, result, meta]; | ||
if (result) | ||
return [i, raw, normalizeEntries(result), variantHandlers]; | ||
return [i, raw, normalizeEntries(result), meta, variantHandlers]; | ||
} | ||
@@ -483,3 +544,3 @@ } | ||
if (isRawUtil(parsed)) | ||
return [parsed[0], void 0, parsed[1], void 0]; | ||
return [parsed[0], void 0, parsed[1], void 0, parsed[2]]; | ||
const [selector, entries, mediaQuery] = this.applyVariants(parsed); | ||
@@ -489,3 +550,3 @@ const body = entriesToCss(entries); | ||
return; | ||
return [parsed[0], selector, body, mediaQuery]; | ||
return [parsed[0], selector, body, mediaQuery, parsed[3]]; | ||
} | ||
@@ -495,2 +556,3 @@ expandShortcut(processed, depth = 3) { | ||
return; | ||
let meta; | ||
let result; | ||
@@ -500,2 +562,3 @@ for (const s of this.config.shortcuts) { | ||
if (s[0] === processed) { | ||
meta = meta || s[2]; | ||
result = s[1]; | ||
@@ -508,4 +571,6 @@ break; | ||
result = s[1](match); | ||
if (result) | ||
if (result) { | ||
meta = meta || s[2]; | ||
break; | ||
} | ||
} | ||
@@ -517,5 +582,11 @@ } | ||
result = result.split(/ /g); | ||
return result.flatMap((r) => this.expandShortcut(r, depth - 1) || [r]); | ||
return [ | ||
result.flatMap((r) => { | ||
var _a; | ||
return ((_a = this.expandShortcut(r, depth - 1)) == null ? void 0 : _a[0]) || [r]; | ||
}), | ||
meta | ||
]; | ||
} | ||
async stringifyShortcuts(parent, expanded) { | ||
async stringifyShortcuts(parent, expanded, meta) { | ||
const selectorMap = new TwoKeyMap(); | ||
@@ -525,3 +596,5 @@ const parsed = (await Promise.all(uniq(expanded).map((i) => this.parseUtil(i)))).filter(Boolean).sort((a, b) => a[0] - b[0]); | ||
for (const item of parsed) { | ||
const [selector, entries, mediaQuery] = this.applyVariants(item, [...item[3], ...parentVariants], raw); | ||
if (isRawUtil(item)) | ||
continue; | ||
const [selector, entries, mediaQuery] = this.applyVariants(item, [...item[4], ...parentVariants], raw); | ||
const mapItem = selectorMap.getFallback(selector, mediaQuery, [[], item[0]]); | ||
@@ -534,5 +607,5 @@ mapItem[0].push(...entries); | ||
const body = entriesToCss(entries); | ||
if (!body) | ||
return void 0; | ||
return [index, selector, body, mediaQuery]; | ||
if (body) | ||
return [index, selector, body, mediaQuery, meta]; | ||
return void 0; | ||
}).filter(Boolean); | ||
@@ -589,3 +662,4 @@ } | ||
uniq, | ||
validateFilterRE | ||
validateFilterRE, | ||
withLayer | ||
}); |
{ | ||
"name": "@unocss/core", | ||
"version": "0.4.16", | ||
"version": "0.5.0", | ||
"description": "The instant on-demand Atomic CSS engine.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50190
1496