fdsfd
This commit is contained in:
parent
628618df89
commit
e031240dff
3749 changed files with 1120848 additions and 1 deletions
429
node_modules/autoprefixer/lib/hacks/gradient.js
generated
vendored
Normal file
429
node_modules/autoprefixer/lib/hacks/gradient.js
generated
vendored
Normal file
|
@ -0,0 +1,429 @@
|
|||
let parser = require('postcss-value-parser')
|
||||
let range = require('normalize-range')
|
||||
|
||||
let OldValue = require('../old-value')
|
||||
let Value = require('../value')
|
||||
let utils = require('../utils')
|
||||
|
||||
let IS_DIRECTION = /top|left|right|bottom/gi
|
||||
|
||||
class Gradient extends Value {
|
||||
/**
|
||||
* Change degrees for webkit prefix
|
||||
*/
|
||||
replace(string, prefix) {
|
||||
let ast = parser(string)
|
||||
for (let node of ast.nodes) {
|
||||
if (node.type === 'function' && node.value === this.name) {
|
||||
node.nodes = this.newDirection(node.nodes)
|
||||
node.nodes = this.normalize(node.nodes)
|
||||
if (prefix === '-webkit- old') {
|
||||
let changes = this.oldWebkit(node)
|
||||
if (!changes) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
node.nodes = this.convertDirection(node.nodes)
|
||||
node.value = prefix + node.value
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace first token
|
||||
*/
|
||||
replaceFirst(params, ...words) {
|
||||
let prefix = words.map(i => {
|
||||
if (i === ' ') {
|
||||
return { type: 'space', value: i }
|
||||
}
|
||||
return { type: 'word', value: i }
|
||||
})
|
||||
return prefix.concat(params.slice(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert angle unit to deg
|
||||
*/
|
||||
normalizeUnit(str, full) {
|
||||
let num = parseFloat(str)
|
||||
let deg = (num / full) * 360
|
||||
return `${deg}deg`
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize angle
|
||||
*/
|
||||
normalize(nodes) {
|
||||
if (!nodes[0]) return nodes
|
||||
|
||||
if (/-?\d+(.\d+)?grad/.test(nodes[0].value)) {
|
||||
nodes[0].value = this.normalizeUnit(nodes[0].value, 400)
|
||||
} else if (/-?\d+(.\d+)?rad/.test(nodes[0].value)) {
|
||||
nodes[0].value = this.normalizeUnit(nodes[0].value, 2 * Math.PI)
|
||||
} else if (/-?\d+(.\d+)?turn/.test(nodes[0].value)) {
|
||||
nodes[0].value = this.normalizeUnit(nodes[0].value, 1)
|
||||
} else if (nodes[0].value.includes('deg')) {
|
||||
let num = parseFloat(nodes[0].value)
|
||||
num = range.wrap(0, 360, num)
|
||||
nodes[0].value = `${num}deg`
|
||||
}
|
||||
|
||||
if (nodes[0].value === '0deg') {
|
||||
nodes = this.replaceFirst(nodes, 'to', ' ', 'top')
|
||||
} else if (nodes[0].value === '90deg') {
|
||||
nodes = this.replaceFirst(nodes, 'to', ' ', 'right')
|
||||
} else if (nodes[0].value === '180deg') {
|
||||
nodes = this.replaceFirst(nodes, 'to', ' ', 'bottom')
|
||||
} else if (nodes[0].value === '270deg') {
|
||||
nodes = this.replaceFirst(nodes, 'to', ' ', 'left')
|
||||
}
|
||||
|
||||
return nodes
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace old direction to new
|
||||
*/
|
||||
newDirection(params) {
|
||||
if (params[0].value === 'to') {
|
||||
return params
|
||||
}
|
||||
IS_DIRECTION.lastIndex = 0 // reset search index of global regexp
|
||||
if (!IS_DIRECTION.test(params[0].value)) {
|
||||
return params
|
||||
}
|
||||
|
||||
params.unshift(
|
||||
{
|
||||
type: 'word',
|
||||
value: 'to'
|
||||
},
|
||||
{
|
||||
type: 'space',
|
||||
value: ' '
|
||||
}
|
||||
)
|
||||
|
||||
for (let i = 2; i < params.length; i++) {
|
||||
if (params[i].type === 'div') {
|
||||
break
|
||||
}
|
||||
if (params[i].type === 'word') {
|
||||
params[i].value = this.revertDirection(params[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for at word
|
||||
*/
|
||||
isRadial(params) {
|
||||
let state = 'before'
|
||||
for (let param of params) {
|
||||
if (state === 'before' && param.type === 'space') {
|
||||
state = 'at'
|
||||
} else if (state === 'at' && param.value === 'at') {
|
||||
state = 'after'
|
||||
} else if (state === 'after' && param.type === 'space') {
|
||||
return true
|
||||
} else if (param.type === 'div') {
|
||||
break
|
||||
} else {
|
||||
state = 'before'
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Change new direction to old
|
||||
*/
|
||||
convertDirection(params) {
|
||||
if (params.length > 0) {
|
||||
if (params[0].value === 'to') {
|
||||
this.fixDirection(params)
|
||||
} else if (params[0].value.includes('deg')) {
|
||||
this.fixAngle(params)
|
||||
} else if (this.isRadial(params)) {
|
||||
this.fixRadial(params)
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace `to top left` to `bottom right`
|
||||
*/
|
||||
fixDirection(params) {
|
||||
params.splice(0, 2)
|
||||
|
||||
for (let param of params) {
|
||||
if (param.type === 'div') {
|
||||
break
|
||||
}
|
||||
if (param.type === 'word') {
|
||||
param.value = this.revertDirection(param.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 90 degrees
|
||||
*/
|
||||
fixAngle(params) {
|
||||
let first = params[0].value
|
||||
first = parseFloat(first)
|
||||
first = Math.abs(450 - first) % 360
|
||||
first = this.roundFloat(first, 3)
|
||||
params[0].value = `${first}deg`
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix radial direction syntax
|
||||
*/
|
||||
fixRadial(params) {
|
||||
let first = []
|
||||
let second = []
|
||||
let a, b, c, i, next
|
||||
|
||||
for (i = 0; i < params.length - 2; i++) {
|
||||
a = params[i]
|
||||
b = params[i + 1]
|
||||
c = params[i + 2]
|
||||
if (a.type === 'space' && b.value === 'at' && c.type === 'space') {
|
||||
next = i + 3
|
||||
break
|
||||
} else {
|
||||
first.push(a)
|
||||
}
|
||||
}
|
||||
|
||||
let div
|
||||
for (i = next; i < params.length; i++) {
|
||||
if (params[i].type === 'div') {
|
||||
div = params[i]
|
||||
break
|
||||
} else {
|
||||
second.push(params[i])
|
||||
}
|
||||
}
|
||||
|
||||
params.splice(0, i, ...second, div, ...first)
|
||||
}
|
||||
|
||||
revertDirection(word) {
|
||||
return Gradient.directions[word.toLowerCase()] || word
|
||||
}
|
||||
|
||||
/**
|
||||
* Round float and save digits under dot
|
||||
*/
|
||||
roundFloat(float, digits) {
|
||||
return parseFloat(float.toFixed(digits))
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to old webkit syntax
|
||||
*/
|
||||
oldWebkit(node) {
|
||||
let { nodes } = node
|
||||
let string = parser.stringify(node.nodes)
|
||||
|
||||
if (this.name !== 'linear-gradient') {
|
||||
return false
|
||||
}
|
||||
if (nodes[0] && nodes[0].value.includes('deg')) {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
string.includes('px') ||
|
||||
string.includes('-corner') ||
|
||||
string.includes('-side')
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
let params = [[]]
|
||||
for (let i of nodes) {
|
||||
params[params.length - 1].push(i)
|
||||
if (i.type === 'div' && i.value === ',') {
|
||||
params.push([])
|
||||
}
|
||||
}
|
||||
|
||||
this.oldDirection(params)
|
||||
this.colorStops(params)
|
||||
|
||||
node.nodes = []
|
||||
for (let param of params) {
|
||||
node.nodes = node.nodes.concat(param)
|
||||
}
|
||||
|
||||
node.nodes.unshift(
|
||||
{ type: 'word', value: 'linear' },
|
||||
this.cloneDiv(node.nodes)
|
||||
)
|
||||
node.value = '-webkit-gradient'
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Change direction syntax to old webkit
|
||||
*/
|
||||
oldDirection(params) {
|
||||
let div = this.cloneDiv(params[0])
|
||||
|
||||
if (params[0][0].value !== 'to') {
|
||||
return params.unshift([
|
||||
{ type: 'word', value: Gradient.oldDirections.bottom },
|
||||
div
|
||||
])
|
||||
} else {
|
||||
let words = []
|
||||
for (let node of params[0].slice(2)) {
|
||||
if (node.type === 'word') {
|
||||
words.push(node.value.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
words = words.join(' ')
|
||||
let old = Gradient.oldDirections[words] || words
|
||||
|
||||
params[0] = [{ type: 'word', value: old }, div]
|
||||
return params[0]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get div token from exists parameters
|
||||
*/
|
||||
cloneDiv(params) {
|
||||
for (let i of params) {
|
||||
if (i.type === 'div' && i.value === ',') {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return { type: 'div', value: ',', after: ' ' }
|
||||
}
|
||||
|
||||
/**
|
||||
* Change colors syntax to old webkit
|
||||
*/
|
||||
colorStops(params) {
|
||||
let result = []
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
let pos
|
||||
let param = params[i]
|
||||
let item
|
||||
if (i === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
let color = parser.stringify(param[0])
|
||||
if (param[1] && param[1].type === 'word') {
|
||||
pos = param[1].value
|
||||
} else if (param[2] && param[2].type === 'word') {
|
||||
pos = param[2].value
|
||||
}
|
||||
|
||||
let stop
|
||||
if (i === 1 && (!pos || pos === '0%')) {
|
||||
stop = `from(${color})`
|
||||
} else if (i === params.length - 1 && (!pos || pos === '100%')) {
|
||||
stop = `to(${color})`
|
||||
} else if (pos) {
|
||||
stop = `color-stop(${pos}, ${color})`
|
||||
} else {
|
||||
stop = `color-stop(${color})`
|
||||
}
|
||||
|
||||
let div = param[param.length - 1]
|
||||
params[i] = [{ type: 'word', value: stop }]
|
||||
if (div.type === 'div' && div.value === ',') {
|
||||
item = params[i].push(div)
|
||||
}
|
||||
result.push(item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old WebKit gradient too
|
||||
*/
|
||||
old(prefix) {
|
||||
if (prefix === '-webkit-') {
|
||||
let type = this.name === 'linear-gradient' ? 'linear' : 'radial'
|
||||
let string = '-gradient'
|
||||
let regexp = utils.regexp(
|
||||
`-webkit-(${type}-gradient|gradient\\(\\s*${type})`,
|
||||
false
|
||||
)
|
||||
|
||||
return new OldValue(this.name, prefix + this.name, string, regexp)
|
||||
} else {
|
||||
return super.old(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not add non-webkit prefixes for list-style and object
|
||||
*/
|
||||
add(decl, prefix) {
|
||||
let p = decl.prop
|
||||
if (p.includes('mask')) {
|
||||
if (prefix === '-webkit-' || prefix === '-webkit- old') {
|
||||
return super.add(decl, prefix)
|
||||
}
|
||||
} else if (
|
||||
p === 'list-style' ||
|
||||
p === 'list-style-image' ||
|
||||
p === 'content'
|
||||
) {
|
||||
if (prefix === '-webkit-' || prefix === '-webkit- old') {
|
||||
return super.add(decl, prefix)
|
||||
}
|
||||
} else {
|
||||
return super.add(decl, prefix)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
Gradient.names = [
|
||||
'linear-gradient',
|
||||
'repeating-linear-gradient',
|
||||
'radial-gradient',
|
||||
'repeating-radial-gradient'
|
||||
]
|
||||
|
||||
Gradient.directions = {
|
||||
top: 'bottom',
|
||||
left: 'right',
|
||||
bottom: 'top',
|
||||
right: 'left'
|
||||
}
|
||||
|
||||
// Direction to replace
|
||||
Gradient.oldDirections = {
|
||||
'top': 'left bottom, left top',
|
||||
'left': 'right top, left top',
|
||||
'bottom': 'left top, left bottom',
|
||||
'right': 'left top, right top',
|
||||
|
||||
'top right': 'left bottom, right top',
|
||||
'top left': 'right bottom, left top',
|
||||
'right top': 'left bottom, right top',
|
||||
'right bottom': 'left top, right bottom',
|
||||
'bottom right': 'left top, right bottom',
|
||||
'bottom left': 'right top, left bottom',
|
||||
'left top': 'right bottom, left top',
|
||||
'left bottom': 'right top, left bottom'
|
||||
}
|
||||
|
||||
module.exports = Gradient
|
Loading…
Add table
Add a link
Reference in a new issue