提交 8d8f7c7a 编写于 作者: fxy060608's avatar fxy060608

wip(app): nvue styler

上级 062fdc23
......@@ -14,17 +14,16 @@ async function objectifierRule(input: string) {
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}`
` .bar {left:5;}.foo .bar {left: 0!important;}.foo .bar{left:5;right:5;right:10!important}.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,
'!left': 0,
'!right': 10,
},
'.bar': {
left: 2,
......@@ -34,4 +33,28 @@ describe('nvue-styler: combinators', () => {
})
expect(messages.length).toBe(0)
})
test('other', async () => {
const types = ['>', '+', '~']
for (const type of types) {
const { json, messages } = await objectifierRule(
` .bar {left:5;}.foo ${type} .bar {left: 0;}.foo${type} .bar{left:5;right:10;}.bar ${type}.bar{left:2}.foo ${type}.bar ${type}.foobar{left:1}`
)
expect(json).toEqual({
bar: {
left: 5,
},
'.bar': {
[`.foo${type}`]: {
left: 5,
right: 10,
},
[`.bar${type}`]: {
left: 2,
},
},
'.foobar': { [`.foo${type}.bar${type}`]: { left: 1 } },
})
expect(messages.length).toBe(0)
}
})
})
......@@ -17,6 +17,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@vue/shared": "3.2.30",
"parse-css-font": "^4.0.0",
"postcss": "^8.4.5"
}
......
import { Container, Root, Document } from 'postcss'
import { extend } from '@vue/shared'
import { extend, hasOwn } from '@vue/shared'
interface ObjectifierContext {
'FONT-FACE': Record<string, unknown>[]
......@@ -43,7 +43,15 @@ function transform(
transformSelector(selector, body, result, context)
})
} else if (child.type === 'decl') {
result[child.prop] = child.value
if (child.important) {
result['!' + child.prop] = child.value
// !important的值域优先级高,故删除非!important的值域
delete result[child.prop]
} else {
if (!hasOwn(result, '!' + child.prop)) {
result[child.prop] = child.value
}
}
}
})
return result
......@@ -56,10 +64,8 @@ function transformSelector(
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(':')
......@@ -72,22 +78,35 @@ function transformSelector(
})
}
transition(className, body, context)
if (isCombinators) {
if (lastDotIndex > 0) {
className = '.' + className
result = (result[className] || (result[className] = {})) as Record<
string,
unknown
>
className = selector.replace(className, '').trim()
className = selector.substring(0, lastDotIndex + 1).trim()
}
if (result[className]) {
// clone
result[className] = extend({}, result[className], body)
result[className] = processImportant(extend({}, result[className], body))
} else {
result[className] = body
}
}
/**
* 处理 important 属性,如果某个属性是 important,需要将非 important 的该属性移除掉
* @param body
*/
function processImportant(body: Record<string, unknown>) {
Object.keys(body).forEach((name) => {
if (name.startsWith('!')) {
delete body[name.substring(1)]
}
})
return body
}
function transition(
className: string,
body: Record<string, unknown>,
......
......@@ -660,9 +660,11 @@ importers:
packages/uni-nvue-styler:
specifiers:
'@vue/shared': 3.2.30
parse-css-font: ^4.0.0
postcss: ^8.4.5
dependencies:
'@vue/shared': 3.2.30
parse-css-font: 4.0.0
postcss: 8.4.6
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册