Skip to content

Commit a7cbcb9

Browse files
committed
fix(transformCss): calculate css weight
1 parent 6771343 commit a7cbcb9

File tree

1 file changed

+57
-6
lines changed

1 file changed

+57
-6
lines changed

src/transformCss.ts

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ interface AllChange {
4040
tag: string
4141
prefix: string
4242
attr: string[]
43+
class: string
4344
media: string
4445
start: Position
4546
end: Position
@@ -285,11 +286,12 @@ export async function transformCss(
285286
props,
286287
} = r
287288

289+
let _class = ''
288290
const attr = props.reduce((result: string[], cur: any) => {
289291
let item
290292

291293
if (cur.name === 'class' && (item = cur.value?.content))
292-
result.push(item)
294+
_class = item
293295
else if (!cur.value)
294296
result.push(cur.name)
295297

@@ -310,6 +312,7 @@ export async function transformCss(
310312
source: newSource,
311313
tag,
312314
attr,
315+
class: _class,
313316
prefix,
314317
media,
315318
start,
@@ -636,6 +639,42 @@ function calculateWeight(c: string) {
636639
return num
637640
}
638641

642+
function getMatchingWeight(name: string, currentClass: string): number {
643+
// 如果name包含逗号,说明是多个选择器,需要找到匹配当前class的选择器
644+
if (name.includes(',')) {
645+
const selectors = name.split(',').map(s => s.trim())
646+
const currentClasses = currentClass.split(' ').filter(Boolean)
647+
648+
// 找到最匹配的选择器
649+
let bestMatch = ''
650+
let maxMatchCount = 0
651+
652+
for (const selector of selectors) {
653+
let matchCount = 0
654+
// 提取选择器中的类名
655+
const selectorClasses = selector.match(/\.[A-Z][\w-]*/gi) || []
656+
657+
for (const selectorClass of selectorClasses) {
658+
const className = selectorClass.substring(1) // 去掉点号
659+
if (currentClasses.includes(className)) {
660+
matchCount++
661+
}
662+
}
663+
664+
if (matchCount > maxMatchCount) {
665+
maxMatchCount = matchCount
666+
bestMatch = selector
667+
}
668+
}
669+
670+
// 如果找到匹配的选择器,使用它计算权重,否则使用第一个
671+
return calculateWeight(bestMatch || selectors[0])
672+
}
673+
674+
// 如果没有逗号,直接计算权重
675+
return calculateWeight(name)
676+
}
677+
639678
function findSameSource(allChange: AllChange[]) {
640679
const result: any = {}
641680
allChange.forEach((item) => {
@@ -674,27 +713,39 @@ async function getConflictClass(
674713
let map: Record<string, Array<number | string | symbol>> = {}
675714
let transform = (code: string) => code
676715
for await (const item of allChange) {
677-
const { before, name, source, attr, after, prefix, media } = item
716+
const {
717+
before,
718+
name,
719+
source,
720+
attr,
721+
after,
722+
prefix,
723+
media,
724+
class: _class,
725+
} = item
678726
const pre = prefix ? `${prefix}|` : ''
679727
const beforeArr = before.split(';').filter(Boolean)
680728
const data = beforeArr.map((item) => {
681729
const [key, value] = item.trim().split(':')
682730
return [`${pre}${key}`, value]
683731
})
732+
733+
// 计算当前选择器的权重
734+
const currentWeight = getMatchingWeight(name, _class)
735+
684736
data.forEach((item) => {
685737
const [key, value] = item
686738
if (value === undefined)
687739
return
688740
if (!map[key]) {
689-
map[key] = [calculateWeight(name), value]
741+
map[key] = [currentWeight, value]
690742
}
691743
else {
692744
const [preWeight] = map[key] as any
693745
if (preWeight === skipTransformFlag)
694746
return
695-
const curWeight = calculateWeight(name)
696-
if (+curWeight >= +preWeight)
697-
map[key] = [+curWeight, value]
747+
if (+currentWeight >= +preWeight)
748+
map[key] = [+currentWeight, value]
698749
}
699750
})
700751

0 commit comments

Comments
 (0)