first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+284
View File
@@ -0,0 +1,284 @@
if (process.env.UNI_USING_V3) {
module.exports = require('./index.v3.js')
} else {
const postcss = require('postcss')
const selectorParser = require('postcss-selector-parser')
const valueParser = require('postcss-value-parser')
const {
getPlatformCssVars
} = require('@dcloudio/uni-cli-shared')
const CSS_TAGS = require('./tags')
const {
unit,
walk
} = valueParser
const defaultOpts = {
px: false
}
const cssVars = getPlatformCssVars()
const transformSelector = (complexSelector, transformer) => {
return selectorParser(transformer).processSync(complexSelector)
}
const parseWord = function (node, opts) {
const pair = unit(node.value)
if (pair) {
const num = Number(pair.number)
let u = pair.unit.toLowerCase()
if (u === 'px' && process.UNI_TRANSFORM_PX) { // TODO px 转换为 upx
u = 'upx'
}
if (process.env.UNI_PLATFORM === 'h5') {
if (u === 'upx' || u === 'rpx') {
node.value = `%?${num}?%`
}
} else {
if (u === 'upx') {
node.value = num + 'rpx'
}
// fixed 百度目前1rpx会转换成小数点 vw,导致边框之类的显示有问题
if (process.env.UNI_PLATFORM === 'mp-baidu') {
if (num === 1 && (u === 'upx' || u === 'rpx')) {
node.value = '1px'
}
}
}
}
}
const isInsideKeyframes = function (rule) {
return (
rule.parent && rule.parent.type === 'atrule' && /^(-\w+-)?keyframes$/.test(rule.parent.name)
)
}
const tranformValue = function (value, opts) {
return valueParser(value)
.walk(node => {
if (node.type === 'word') {
parseWord(node, opts)
} else if (node.type === 'function') {
if (node.value === 'url') {
return false
}
if (node.value === 'var') {
let cssVarValue = false
walk(node.nodes, n => {
if (n.type === 'word') {
if (Object.prototype.hasOwnProperty.call(cssVars, n.value)) { // 目前仅考虑 nodes 长度为0
cssVarValue = cssVars[n.value]
}
}
})
if (cssVarValue !== false) {
node.type = 'word'
node.value = cssVarValue
delete node.before
delete node.after
delete node.nodes
}
return false
} else {
walk(node.nodes, n => {
if (n.type === 'word') {
parseWord(n, opts)
}
})
}
}
})
.toString()
}
const TAGS = [
'ad',
'audio',
'button',
'camera',
'canvas',
'checkbox',
'checkbox-group',
'cover-image',
'cover-view',
'editor',
'form',
'functional-page-navigator',
'icon',
'image',
'input',
'label',
'live-player',
'live-pusher',
'map',
'movable-area',
'movable-view',
'navigator',
'official-account',
'open-data',
'picker',
'picker-view',
'picker-view-column',
'progress',
'radio',
'radio-group',
'rich-text',
'scroll-view',
'slider',
'swiper',
'swiper-item',
'switch',
'text',
'textarea',
'video',
'view',
'web-view'
]
const BG_PROPS = [
'background',
'background-clip',
'background-color',
'background-image',
'background-origin',
'background-position',
'background-repeat',
'background-size',
'background-attachment'
]
let rewriteUrl
/**
* 转换 upx
* 转换 px
*/
const fn = function (opts) {
opts = {
...defaultOpts,
...opts
}
return function (root, result) {
if (!rewriteUrl) {
rewriteUrl = require('@dcloudio/uni-cli-shared/lib/url-loader').rewriteUrl
}
rewriteUrl(root)
if (process.env.UNI_PLATFORM === 'h5') {
// Transform CSS AST here
root.walkRules(rule => {
let hasPage = false
// Transform each rule here
if (!isInsideKeyframes(rule)) {
// rule.selectors == comma seperated selectors
// a, b.c {} => ["a", "b.c"]
rule.selectors = rule.selectors.map(complexSelector => {
// complexSelector => simpleSelectors
// "a.b#c" => ["a", ".b", "#c"]
if (complexSelector === 'page') {
hasPage = true
}
return transformSelector(complexSelector, simpleSelectors =>
// only process type selector, leave alone class & id selectors
simpleSelectors.walkTags(tag => {
if (tag.value === 'page') {
tag.value = 'uni-page-body'
} else if (~TAGS.indexOf(tag.value) && tag.value.substring(
0, 4) !== 'uni-') {
tag.value = 'uni-' + tag.value
}
})
)
})
}
const bgDecls = []
// handle upx unit
rule.walkDecls(decl => {
if (hasPage) {
if (BG_PROPS.indexOf(decl.prop) !== -1) {
bgDecls.push(decl.clone())
}
}
// Transform each property declaration here
decl.value = tranformValue(decl.value, opts)
})
// handle body background rule
if (bgDecls.length) {
const bodyRule = postcss.rule({
selector: 'body.?%PAGE?%'
})
bgDecls.forEach(decl => bodyRule.append(decl))
rule.after(bodyRule)
}
})
root.walkAtRules(rule => {
if (rule.name === 'media') {
rule.params = tranformValue(rule.params, opts)
}
})
} else {
root.walkRules(rule => {
const selectors = transformSelector(rule.selectors.join(','), function (selectors) {
selectors.walkUniversals(node => {
node.parent.remove()
})
})
if (!selectors) {
return rule.remove()
}
rule.selectors = selectors.split(',')
// handle upx unit
rule.walkDecls(decl => {
const raws = decl.raws
if (raws) {
if (raws.before && raws.before.indexOf(';') !== -1) {
raws.before = raws.before.replace(/;/g, '')
}
if (raws.after && raws.after.indexOf(';') !== -1) {
raws.after = raws.after.replace(/;/g, '')
}
}
// Transform each property declaration here
decl.value = tranformValue(decl.value, opts)
})
if (process.env.UNI_PLATFORM !== 'quickapp-native') {
rule.selectors = rule.selectors.map(complexSelector => {
return transformSelector(complexSelector, simpleSelectors => {
return simpleSelectors.walkTags(tag => {
const k = tag.value
const v = CSS_TAGS[k]
if (v) {
tag.value = v === 'r'
? `._${k}` : v
}
})
})
})
}
})
}
}
}
const version = Number(require('postcss/package.json').version.split('.')[0])
if (version < 8) {
module.exports = postcss.plugin('postcss-uniapp-plugin', fn)
} else {
module.exports = function (opts) {
return {
postcssPlugin: 'postcss-uniapp-plugin',
Once: fn(opts)
}
}
module.exports.postcss = true
}
}
+66
View File
@@ -0,0 +1,66 @@
const selectorParser = require('postcss-selector-parser')
const {
tags
} = require('@dcloudio/uni-cli-shared')
const TAGS = Object.keys(tags)
const transformSelector = (complexSelector, transformer) => {
return selectorParser(transformer).processSync(complexSelector)
}
const isInsideKeyframes = function (rule) {
return (
rule.parent && rule.parent.type === 'atrule' && /^(-\w+-)?keyframes$/.test(rule.parent.name)
)
}
let rewriteUrl
function once (root) {
if (!rewriteUrl) {
rewriteUrl = require('@dcloudio/uni-cli-shared/lib/url-loader').rewriteUrl
}
rewriteUrl(root)
root.walkRules(rule => {
// Transform each rule here
if (!isInsideKeyframes(rule)) {
// rule.selectors == comma seperated selectors
// a, b.c {} => ["a", "b.c"]
rule.selectors = rule.selectors.map(complexSelector =>
// complexSelector => simpleSelectors
// "a.b#c" => ["a", ".b", "#c"]
transformSelector(complexSelector, simpleSelectors => {
// only process type selector, leave alone class & id selectors
return simpleSelectors.walkTags(tag => {
if (tag.value === 'page') {
tag.value = 'body'
} else if (~TAGS.indexOf(tag.value) && tag.value.substring(
0, 4) !== 'uni-') {
tag.value = 'uni-' + tag.value
}
})
})
)
}
})
}
const version = Number(require('postcss/package.json').version.split('.')[0])
if (version < 8) {
const postcss = require('postcss')
module.exports = postcss.plugin('postcss-uniapp-plugin', function (opts) {
return once
})
} else {
module.exports = function (opts) {
return {
postcssPlugin: 'postcss-uniapp-plugin',
Once: once
}
}
module.exports.postcss = true
}
+123
View File
@@ -0,0 +1,123 @@
module.exports = {
br: 'r',
hr: 'r',
p: 'r',
h1: 'r',
h2: 'r',
h3: 'r',
h4: 'r',
h5: 'r',
h6: 'r',
abbr: 'r',
address: 'r',
b: 'r',
bdi: 'r',
bdo: 'r',
blockquote: 'r',
cite: 'r',
code: 'r',
del: 'r',
ins: 'r',
dfn: 'r',
em: 'r',
strong: 'r',
samp: 'r',
kbd: 'r',
var: 'r',
i: 'r',
mark: 'r',
pre: 'r',
q: 'r',
ruby: 'r',
rp: 'r',
rt: 'r',
s: 'r',
small: 'r',
sub: 'r',
sup: 'r',
time: 'r',
u: 'r',
wbr: 'r',
// 表单元素
// 'form': 'r',
// 'input': 'r',
// 'textarea': 'r',
// 'button': 'r',
select: 'r',
option: 'r',
optgroup: 'r',
// 'label': 'r',
fieldset: 'r',
datalist: 'r',
legend: 'r',
output: 'r',
// 框架
iframe: 'r',
// 图像
img: 'r',
// 'canvas': 'r',
figure: 'r',
figcaption: 'r',
// 音视频
// 'audio': 'r',
source: 'r',
// 'video': 'r',
track: 'r',
// 链接
a: 'r',
nav: 'r',
link: 'r',
// 列表
ul: 'r',
ol: 'r',
li: 'r',
dl: 'r',
dt: 'r',
dd: 'r',
menu: 'r',
command: 'r',
// 表格table
table: 'r',
caption: 'r',
th: 'r',
td: 'r',
tr: 'r',
thead: 'r',
tbody: 'r',
tfoot: 'r',
col: 'r',
colgroup: 'r',
// 样式 节
div: 'r',
main: 'r',
span: 'r',
header: 'r',
footer: 'r',
section: 'r',
article: 'r',
aside: 'r',
details: 'r',
dialog: 'r',
summary: 'r',
// 'progress': 'r',
meter: 'r', // todo
head: 'r', // todo
meta: 'r', // todo
base: 'r', // todo
// 'map': 'r', // TODO不是很恰当
area: 'r', // j结合map使用
script: 'r',
noscript: 'r',
embed: 'r',
object: 'r',
param: 'r',
body: 'page',
html: 'page'
}