提交 4cf23077 编写于 作者: fxy060608's avatar fxy060608

wip(app): nvue styler

上级 2c277aaf
......@@ -106,8 +106,8 @@ export function uniAppNVuePlugin({
}
const { code, messages } = await parse(source, {
filename,
descendant: false,
logLevel: 'WARNING',
combinators: false,
})
messages.forEach((message) => {
if (message.type === 'warning') {
......
import { parse } from '../src'
async function objectifierRule(input: string) {
const { code, messages } = await parse(input, {
combinators: true,
logLevel: 'NOTE',
})
return {
json: JSON.parse(code),
messages,
}
}
describe('nvue-styler: combinators', () => {
test('descendant', async () => {
const { json, messages } = await objectifierRule(
` .bar {left:5;}.foo .bar {left: 0;}.foo .bar{left:5;right:10;}.bar .bar{left:2}.foo .bar .foobar{left:1}`
)
console.log(json, messages)
expect(json).toEqual({
bar: {
left: 5,
},
'.bar': {
'.foo': {
left: 5,
right: 10,
},
'.bar': {
left: 2,
},
},
'.foobar': { '.foo .bar': { left: 1 } },
})
expect(messages.length).toBe(0)
})
})
......@@ -11,13 +11,13 @@ import { normalizeMap } from './map'
const normalized = Symbol('normalized')
export interface NormalizeOptions {
descendant?: boolean
combinators?: boolean
logLevel?: 'NOTE' | 'WARNING' | 'ERROR'
}
export function normalize(opts: NormalizeOptions = {}): Plugin {
if (!hasOwn(opts, 'descendant')) {
opts.descendant = false
if (!hasOwn(opts, 'combinators')) {
opts.combinators = false
}
if (!hasOwn(opts, 'logLevel')) {
opts.logLevel = 'WARNING'
......@@ -32,19 +32,22 @@ export function normalize(opts: NormalizeOptions = {}): Plugin {
return plugin
}
function createRuleProcessor({ descendant }: NormalizeOptions) {
function createRuleProcessor({ combinators }: NormalizeOptions) {
return (rule: Rule, helper: Helpers) => {
if ((rule as any)[normalized]) {
return
}
const regx = descendant
const regx = combinators
? /^((?:(?:\.[A-Za-z0-9_\-]+)+[\+\~\> ])*)((?:\.[A-Za-z0-9_\-\:]+)+)$/
: /^(\.)([A-Za-z0-9_\-:]+)$/
rule.selector = rule.selectors
.filter((selector) => {
.map((selector) => {
selector = selector
.replace(/\s*([\+\~\>])\s*/g, '$1')
.replace(/\s+/, ' ')
if (regx.test(selector)) {
return true
return selector
}
rule.warn(
helper.result,
......@@ -52,8 +55,9 @@ function createRuleProcessor({ descendant }: NormalizeOptions) {
selector +
'` is not supported. nvue only support classname selector'
)
return false
return ''
})
.filter(Boolean)
.join(', ')
if (!rule.selector) {
rule.remove()
......
......@@ -10,7 +10,10 @@ export function objectifier(node: Root | Document | Container | null) {
if (!node) {
return {}
}
const context: ObjectifierContext = { 'FONT-FACE': [], TRANSITION: {} }
const context: ObjectifierContext = {
'FONT-FACE': [],
TRANSITION: {},
}
const result = transform(node, context)
if (context['FONT-FACE'].length) {
result['@FONT-FACE'] = context['FONT-FACE']
......@@ -37,23 +40,7 @@ function transform(
} else if (child.type === 'rule') {
const body = transform(child, context)
child.selectors.forEach((selector) => {
let className = selector.slice(1)
const pseudoIndex = className.indexOf(':')
if (pseudoIndex > -1) {
const pseudoClass = className.slice(pseudoIndex)
className = className.slice(0, pseudoIndex)
Object.keys(body).forEach(function (name) {
body[name + pseudoClass] = body[name]
delete body[name]
})
}
transition(className, body, context)
if (result[className]) {
// clone
result[className] = extend({}, result[className], body)
} else {
result[className] = body
}
transformSelector(selector, body, result, context)
})
} else if (child.type === 'decl') {
result[child.prop] = child.value
......@@ -62,6 +49,45 @@ function transform(
return result
}
function transformSelector(
selector: string,
body: Record<string, unknown>,
result: Record<string, unknown | Record<string, unknown>>,
context: ObjectifierContext
) {
let className = selector.slice(1)
let isCombinators = false
const lastDotIndex = className.lastIndexOf('.')
if (lastDotIndex > 0) {
isCombinators = true
className = className.substring(lastDotIndex + 1)
}
const pseudoIndex = className.indexOf(':')
if (pseudoIndex > -1) {
const pseudoClass = className.slice(pseudoIndex)
className = className.slice(0, pseudoIndex)
Object.keys(body).forEach(function (name) {
body[name + pseudoClass] = body[name]
delete body[name]
})
}
transition(className, body, context)
if (isCombinators) {
className = '.' + className
result = (result[className] || (result[className] = {})) as Record<
string,
unknown
>
className = selector.replace(className, '').trim()
}
if (result[className]) {
// clone
result[className] = extend({}, result[className], body)
} else {
result[className] = body
}
}
function transition(
className: string,
body: Record<string, unknown>,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册