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

wip(app): nvue styler

上级 062fdc23
...@@ -14,17 +14,16 @@ async function objectifierRule(input: string) { ...@@ -14,17 +14,16 @@ async function objectifierRule(input: string) {
describe('nvue-styler: combinators', () => { describe('nvue-styler: combinators', () => {
test('descendant', async () => { test('descendant', async () => {
const { json, messages } = await objectifierRule( 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({ expect(json).toEqual({
bar: { bar: {
left: 5, left: 5,
}, },
'.bar': { '.bar': {
'.foo': { '.foo': {
left: 5, '!left': 0,
right: 10, '!right': 10,
}, },
'.bar': { '.bar': {
left: 2, left: 2,
...@@ -34,4 +33,28 @@ describe('nvue-styler: combinators', () => { ...@@ -34,4 +33,28 @@ describe('nvue-styler: combinators', () => {
}) })
expect(messages.length).toBe(0) 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 @@ ...@@ -17,6 +17,7 @@
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@vue/shared": "3.2.30",
"parse-css-font": "^4.0.0", "parse-css-font": "^4.0.0",
"postcss": "^8.4.5" "postcss": "^8.4.5"
} }
......
import { Container, Root, Document } from 'postcss' import { Container, Root, Document } from 'postcss'
import { extend } from '@vue/shared' import { extend, hasOwn } from '@vue/shared'
interface ObjectifierContext { interface ObjectifierContext {
'FONT-FACE': Record<string, unknown>[] 'FONT-FACE': Record<string, unknown>[]
...@@ -43,7 +43,15 @@ function transform( ...@@ -43,7 +43,15 @@ function transform(
transformSelector(selector, body, result, context) transformSelector(selector, body, result, context)
}) })
} else if (child.type === 'decl') { } 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 return result
...@@ -56,10 +64,8 @@ function transformSelector( ...@@ -56,10 +64,8 @@ function transformSelector(
context: ObjectifierContext context: ObjectifierContext
) { ) {
let className = selector.slice(1) let className = selector.slice(1)
let isCombinators = false
const lastDotIndex = className.lastIndexOf('.') const lastDotIndex = className.lastIndexOf('.')
if (lastDotIndex > 0) { if (lastDotIndex > 0) {
isCombinators = true
className = className.substring(lastDotIndex + 1) className = className.substring(lastDotIndex + 1)
} }
const pseudoIndex = className.indexOf(':') const pseudoIndex = className.indexOf(':')
...@@ -72,22 +78,35 @@ function transformSelector( ...@@ -72,22 +78,35 @@ function transformSelector(
}) })
} }
transition(className, body, context) transition(className, body, context)
if (isCombinators) { if (lastDotIndex > 0) {
className = '.' + className className = '.' + className
result = (result[className] || (result[className] = {})) as Record< result = (result[className] || (result[className] = {})) as Record<
string, string,
unknown unknown
> >
className = selector.replace(className, '').trim() className = selector.substring(0, lastDotIndex + 1).trim()
} }
if (result[className]) { if (result[className]) {
// clone // clone
result[className] = extend({}, result[className], body) result[className] = processImportant(extend({}, result[className], body))
} else { } else {
result[className] = body 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( function transition(
className: string, className: string,
body: Record<string, unknown>, body: Record<string, unknown>,
......
...@@ -660,9 +660,11 @@ importers: ...@@ -660,9 +660,11 @@ importers:
packages/uni-nvue-styler: packages/uni-nvue-styler:
specifiers: specifiers:
'@vue/shared': 3.2.30
parse-css-font: ^4.0.0 parse-css-font: ^4.0.0
postcss: ^8.4.5 postcss: ^8.4.5
dependencies: dependencies:
'@vue/shared': 3.2.30
parse-css-font: 4.0.0 parse-css-font: 4.0.0
postcss: 8.4.6 postcss: 8.4.6
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册