Socket
Socket
Sign inDemoInstall

autoprefixer

Package Overview
Dependencies
13
Maintainers
1
Versions
243
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 10.4.14 to 10.4.15

368

data/prefixes.js

@@ -71,5 +71,5 @@ let unpack = require('caniuse-lite/dist/unpacker/feature')

{
mistakes: ['-khtml-', '-ms-', '-o-'],
browsers,
feature: 'border-radius',
browsers
mistakes: ['-khtml-', '-ms-', '-o-']
}

@@ -84,5 +84,5 @@ )

prefix(['box-shadow'], {
mistakes: ['-khtml-'],
browsers,
feature: 'css-boxshadow',
browsers
mistakes: ['-khtml-']
})

@@ -109,5 +109,5 @@ )

{
mistakes: ['-khtml-', '-ms-'],
browsers,
feature: 'css-animation',
browsers
mistakes: ['-khtml-', '-ms-']
}

@@ -130,5 +130,5 @@ )

{
mistakes: ['-khtml-', '-ms-'],
browsers,
feature: 'css-transitions'
feature: 'css-transitions',
mistakes: ['-khtml-', '-ms-']
}

@@ -143,4 +143,4 @@ )

prefix(['transform', 'transform-origin'], {
feature: 'transforms2d',
browsers
browsers,
feature: 'transforms2d'
})

@@ -154,9 +154,9 @@ )

prefix(['perspective', 'perspective-origin'], {
feature: 'transforms3d',
browsers
browsers,
feature: 'transforms3d'
})
return prefix(['transform-style'], {
mistakes: ['-ms-', '-o-'],
browsers,
feature: 'transforms3d'
feature: 'transforms3d',
mistakes: ['-ms-', '-o-']
})

@@ -167,5 +167,5 @@ })

prefix(['backface-visibility'], {
mistakes: ['-ms-', '-o-'],
browsers,
feature: 'transforms3d',
browsers
mistakes: ['-ms-', '-o-']
})

@@ -186,2 +186,5 @@ )

{
browsers,
feature: 'css-gradients',
mistakes: ['-ms-'],
props: [

@@ -196,6 +199,3 @@ 'background',

'mask-image'
],
mistakes: ['-ms-'],
feature: 'css-gradients',
browsers
]
}

@@ -221,4 +221,4 @@ )

{
feature: 'css-gradients',
browsers
browsers,
feature: 'css-gradients'
}

@@ -233,4 +233,4 @@ )

prefix(['box-sizing'], {
feature: 'css3-boxsizing',
browsers
browsers,
feature: 'css3-boxsizing'
})

@@ -244,4 +244,4 @@ )

prefix(['filter'], {
feature: 'css-filters',
browsers
browsers,
feature: 'css-filters'
})

@@ -255,2 +255,4 @@ )

prefix(['filter-function'], {
browsers,
feature: 'css-filter-function',
props: [

@@ -265,5 +267,3 @@ 'background',

'mask-image'
],
feature: 'css-filter-function',
browsers
]
})

@@ -273,8 +273,8 @@ )

// Backdrop-filter
let prefixBackdrop = require('caniuse-lite/data/features/css-backdrop-filter')
let prefixBackdropFilter = require('caniuse-lite/data/features/css-backdrop-filter')
f(prefixBackdrop, { match: /y\sx|y\s#2/ }, browsers =>
f(prefixBackdropFilter, { match: /y\sx|y\s#2/ }, browsers =>
prefix(['backdrop-filter'], {
feature: 'css-backdrop-filter',
browsers
browsers,
feature: 'css-backdrop-filter'
})

@@ -288,2 +288,4 @@ )

prefix(['element'], {
browsers,
feature: 'css-element-function',
props: [

@@ -298,5 +300,3 @@ 'background',

'mask-image'
],
feature: 'css-element-function',
browsers
]
})

@@ -323,4 +323,4 @@ )

{
feature: 'multicolumn',
browsers
browsers,
feature: 'multicolumn'
}

@@ -331,4 +331,4 @@ )

prefix(['break-before', 'break-after', 'break-inside'], {
feature: 'multicolumn',
browsers: noff
browsers: noff,
feature: 'multicolumn'
})

@@ -342,5 +342,5 @@ })

prefix(['user-select'], {
mistakes: ['-khtml-'],
browsers,
feature: 'user-select-none',
browsers
mistakes: ['-khtml-']
})

@@ -361,9 +361,9 @@ )

prefix(['display-flex', 'inline-flex'], {
props: ['display'],
browsers,
feature: 'flexbox',
browsers
props: ['display']
})
prefix(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
})

@@ -382,4 +382,4 @@ prefix(

{
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
}

@@ -391,8 +391,8 @@ )

add(['display-flex', 'inline-flex'], {
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
})
add(['flex', 'flex-grow', 'flex-shrink', 'flex-basis'], {
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
})

@@ -411,4 +411,4 @@ add(

{
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
}

@@ -423,5 +423,5 @@ )

prefix(['calc'], {
props: ['*'],
browsers,
feature: 'calc',
browsers
props: ['*']
})

@@ -435,4 +435,4 @@ )

prefix(['background-origin', 'background-size'], {
feature: 'background-img-opts',
browsers
browsers,
feature: 'background-img-opts'
})

@@ -446,4 +446,4 @@ )

prefix(['background-clip'], {
feature: 'background-clip-text',
browsers
browsers,
feature: 'background-clip-text'
})

@@ -463,4 +463,4 @@ )

{
feature: 'font-feature',
browsers
browsers,
feature: 'font-feature'
}

@@ -475,4 +475,4 @@ )

prefix(['font-kerning'], {
feature: 'font-kerning',
browsers
browsers,
feature: 'font-kerning'
})

@@ -486,4 +486,4 @@ )

prefix(['border-image'], {
feature: 'border-image',
browsers
browsers,
feature: 'border-image'
})

@@ -497,5 +497,5 @@ )

prefix(['::selection'], {
selector: true,
browsers,
feature: 'css-selection',
browsers
selector: true
})

@@ -509,5 +509,5 @@ )

prefix(['::placeholder'], {
selector: true,
browsers: browsers.concat(['ie 10 old', 'ie 11 old', 'firefox 18 old']),
feature: 'css-placeholder',
browsers: browsers.concat(['ie 10 old', 'ie 11 old', 'firefox 18 old'])
selector: true
})

@@ -521,5 +521,5 @@ })

prefix([':placeholder-shown'], {
selector: true,
browsers,
feature: 'css-placeholder-shown',
browsers
selector: true
})

@@ -533,4 +533,4 @@ })

prefix(['hyphens'], {
feature: 'css-hyphens',
browsers
browsers,
feature: 'css-hyphens'
})

@@ -544,13 +544,17 @@ )

prefix([':fullscreen'], {
selector: true,
browsers,
feature: 'fullscreen',
browsers
selector: true
})
)
f(prefixFullscreen, { match: /x(\s#2|$)/ }, browsers =>
// ::backdrop pseudo-element
// https://caniuse.com/mdn-css_selectors_backdrop
let prefixBackdrop = require('caniuse-lite/data/features/mdn-css-backdrop-pseudo-element')
f(prefixBackdrop, browsers =>
prefix(['::backdrop'], {
selector: true,
feature: 'fullscreen',
browsers
browsers,
feature: 'backdrop',
selector: true
})

@@ -564,5 +568,5 @@ )

prefix(['::file-selector-button'], {
selector: true,
browsers,
feature: 'file-selector-button',
browsers
selector: true
})

@@ -576,5 +580,5 @@ )

prefix([':autofill'], {
selector: true,
browsers,
feature: 'css-autofill',
browsers
selector: true
})

@@ -588,4 +592,4 @@ )

prefix(['tab-size'], {
feature: 'css3-tabsize',
browsers
browsers,
feature: 'css3-tabsize'
})

@@ -620,5 +624,5 @@ )

prefix(['max-content', 'min-content'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})

@@ -629,5 +633,5 @@ )

prefix(['fill', 'fill-available'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})

@@ -638,5 +642,5 @@ )

prefix(['fit-content'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})

@@ -651,5 +655,5 @@ )

prefix(['stretch'], {
props: sizeProps,
browsers,
feature: 'css-width-stretch',
browsers
props: sizeProps
})

@@ -663,5 +667,5 @@ )

prefix(['zoom-in', 'zoom-out'], {
props: ['cursor'],
browsers,
feature: 'css3-cursors-newer',
browsers
props: ['cursor']
})

@@ -675,5 +679,5 @@ )

prefix(['grab', 'grabbing'], {
props: ['cursor'],
browsers,
feature: 'css3-cursors-grab',
browsers
props: ['cursor']
})

@@ -687,5 +691,5 @@ )

prefix(['sticky'], {
props: ['position'],
browsers,
feature: 'css-sticky',
browsers
props: ['position']
})

@@ -699,4 +703,4 @@ )

prefix(['touch-action'], {
feature: 'pointer',
browsers
browsers,
feature: 'pointer'
})

@@ -710,4 +714,4 @@ )

prefix(['text-decoration-skip', 'text-decoration-skip-ink'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})

@@ -720,4 +724,4 @@ )

prefix(['text-decoration'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})

@@ -730,4 +734,4 @@ )

prefix(['text-decoration-color'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})

@@ -740,4 +744,4 @@ )

prefix(['text-decoration-line'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})

@@ -750,4 +754,4 @@ )

prefix(['text-decoration-style'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})

@@ -761,4 +765,4 @@ )

prefix(['text-size-adjust'], {
feature: 'text-size-adjust',
browsers
browsers,
feature: 'text-size-adjust'
})

@@ -782,4 +786,4 @@ )

{
feature: 'css-masks',
browsers
browsers,
feature: 'css-masks'
}

@@ -798,4 +802,4 @@ )

{
feature: 'css-masks',
browsers
browsers,
feature: 'css-masks'
}

@@ -810,4 +814,4 @@ )

prefix(['clip-path'], {
feature: 'css-clip-path',
browsers
browsers,
feature: 'css-clip-path'
})

@@ -821,4 +825,4 @@ )

prefix(['box-decoration-break'], {
feature: 'css-boxdecorationbreak',
browsers
browsers,
feature: 'css-boxdecorationbreak'
})

@@ -832,4 +836,4 @@ )

prefix(['object-fit', 'object-position'], {
feature: 'object-fit',
browsers
browsers,
feature: 'object-fit'
})

@@ -843,4 +847,4 @@ )

prefix(['shape-margin', 'shape-outside', 'shape-image-threshold'], {
feature: 'css-shapes',
browsers
browsers,
feature: 'css-shapes'
})

@@ -854,4 +858,4 @@ )

prefix(['text-overflow'], {
feature: 'text-overflow',
browsers
browsers,
feature: 'text-overflow'
})

@@ -865,4 +869,4 @@ )

prefix(['@viewport'], {
feature: 'css-deviceadaptation',
browsers
browsers,
feature: 'css-deviceadaptation'
})

@@ -876,4 +880,4 @@ )

prefix(['@resolution'], {
feature: 'css-media-resolution',
browsers
browsers,
feature: 'css-media-resolution'
})

@@ -887,4 +891,4 @@ )

prefix(['text-align-last'], {
feature: 'css-text-align-last',
browsers
browsers,
feature: 'css-text-align-last'
})

@@ -898,5 +902,5 @@ )

prefix(['pixelated'], {
props: ['image-rendering'],
browsers,
feature: 'css-crisp-edges',
browsers
props: ['image-rendering']
})

@@ -907,4 +911,4 @@ )

prefix(['image-rendering'], {
feature: 'css-crisp-edges',
browsers
browsers,
feature: 'css-crisp-edges'
})

@@ -927,4 +931,4 @@ )

{
feature: 'css-logical-props',
browsers
browsers,
feature: 'css-logical-props'
}

@@ -945,4 +949,4 @@ )

{
feature: 'css-logical-props',
browsers
browsers,
feature: 'css-logical-props'
}

@@ -957,4 +961,4 @@ )

prefix(['appearance'], {
feature: 'css-appearance',
browsers
browsers,
feature: 'css-appearance'
})

@@ -976,4 +980,4 @@ )

{
feature: 'css-snappoints',
browsers
browsers,
feature: 'css-snappoints'
}

@@ -988,4 +992,4 @@ )

prefix(['flow-into', 'flow-from', 'region-fragment'], {
feature: 'css-regions',
browsers
browsers,
feature: 'css-regions'
})

@@ -999,2 +1003,4 @@ )

prefix(['image-set'], {
browsers,
feature: 'css-image-set',
props: [

@@ -1010,5 +1016,3 @@ 'background',

'content'
],
feature: 'css-image-set',
browsers
]
})

@@ -1022,4 +1026,4 @@ )

prefix(['writing-mode'], {
feature: 'css-writing-mode',
browsers
browsers,
feature: 'css-writing-mode'
})

@@ -1033,2 +1037,4 @@ )

prefix(['cross-fade'], {
browsers,
feature: 'css-cross-fade',
props: [

@@ -1043,5 +1049,3 @@ 'background',

'mask-image'
],
feature: 'css-cross-fade',
browsers
]
})

@@ -1055,5 +1059,5 @@ )

prefix([':read-only', ':read-write'], {
selector: true,
browsers,
feature: 'css-read-only-write',
browsers
selector: true
})

@@ -1074,4 +1078,4 @@ )

{
feature: 'text-emphasis',
browsers
browsers,
feature: 'text-emphasis'
}

@@ -1086,5 +1090,5 @@ )

prefix(['display-grid', 'inline-grid'], {
props: ['display'],
browsers,
feature: 'css-grid',
browsers
props: ['display']
})

@@ -1107,4 +1111,4 @@ prefix(

{
feature: 'css-grid',
browsers
browsers,
feature: 'css-grid'
}

@@ -1116,4 +1120,4 @@ )

prefix(['grid-column-align', 'grid-row-align'], {
feature: 'css-grid',
browsers
browsers,
feature: 'css-grid'
})

@@ -1127,4 +1131,4 @@ )

prefix(['text-spacing'], {
feature: 'css-text-spacing',
browsers
browsers,
feature: 'css-text-spacing'
})

@@ -1138,5 +1142,5 @@ )

prefix([':any-link'], {
selector: true,
browsers,
feature: 'css-any-link',
browsers
selector: true
})

@@ -1151,5 +1155,5 @@ )

prefix(['isolate'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})

@@ -1162,5 +1166,5 @@ )

prefix(['plaintext'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})

@@ -1173,5 +1177,5 @@ )

prefix(['isolate-override'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})

@@ -1185,4 +1189,4 @@ )

prefix(['overscroll-behavior'], {
feature: 'css-overscroll-behavior',
browsers
browsers,
feature: 'css-overscroll-behavior'
})

@@ -1196,4 +1200,4 @@ )

prefix(['text-orientation'], {
feature: 'css-text-orientation',
browsers
browsers,
feature: 'css-text-orientation'
})

@@ -1207,5 +1211,5 @@ )

prefix(['print-color-adjust', 'color-adjust'], {
feature: 'css-print-color-adjust',
browsers
browsers,
feature: 'css-print-color-adjust'
})
)

@@ -99,5 +99,5 @@ let browserslist = require('browserslist')

let brwlstOpts = {
env: options.env,
ignoreUnknownVersions: options.ignoreUnknownVersions,
stats: options.stats,
env: options.env
stats: options.stats
}

@@ -118,8 +118,17 @@

return {
browsers: reqs,
info(opts) {
opts = opts || {}
opts.from = opts.from || process.cwd()
return getInfo(loadPrefixes(opts))
},
options,
postcssPlugin: 'autoprefixer',
prepare(result) {
let prefixes = loadPrefixes({
from: result.opts.from,
env: options.env
env: options.env,
from: result.opts.from
})

@@ -138,12 +147,3 @@

}
},
info(opts) {
opts = opts || {}
opts.from = opts.from || process.cwd()
return getInfo(loadPrefixes(opts))
},
options,
browsers: reqs
}
}

@@ -150,0 +150,0 @@ }

@@ -7,2 +7,9 @@ let browserslist = require('browserslist')

class Browsers {
constructor(data, requirements, options, browserslistOpts) {
this.data = data
this.options = options || {}
this.browserslistOpts = browserslistOpts || {}
this.selected = this.parse(requirements)
}
/**

@@ -39,7 +46,7 @@ * Return all prefixes for default browser data

constructor(data, requirements, options, browserslistOpts) {
this.data = data
this.options = options || {}
this.browserslistOpts = browserslistOpts || {}
this.selected = this.parse(requirements)
/**
* Is browser is selected by requirements
*/
isSelected(browser) {
return this.selected.includes(browser)
}

@@ -72,11 +79,4 @@

}
/**
* Is browser is selected by requirements
*/
isSelected(browser) {
return this.selected.includes(browser)
}
}
module.exports = Browsers

@@ -7,54 +7,66 @@ let Prefixer = require('./prefixer')

/**
* Always true, because we already get prefixer by property name
* Clone and add prefixes for declaration
*/
check(/* decl */) {
return true
add(decl, prefix, prefixes, result) {
let prefixed = this.prefixed(decl.prop, prefix)
if (
this.isAlready(decl, prefixed) ||
this.otherPrefixes(decl.value, prefix)
) {
return undefined
}
return this.insert(decl, prefix, prefixes, result)
}
/**
* Return prefixed version of property
* Calculate indentation to create visual cascade
*/
prefixed(prop, prefix) {
return prefix + prop
calcBefore(prefixes, decl, prefix = '') {
let max = this.maxPrefixed(prefixes, decl)
let diff = max - utils.removeNote(prefix).length
let before = decl.raw('before')
if (diff > 0) {
before += Array(diff).fill(' ').join('')
}
return before
}
/**
* Return unprefixed version of property
* Always true, because we already get prefixer by property name
*/
normalize(prop) {
return prop
check(/* decl */) {
return true
}
/**
* Check `value`, that it contain other prefixes, rather than `prefix`
* Clone and insert new declaration
*/
otherPrefixes(value, prefix) {
for (let other of Browsers.prefixes()) {
if (other === prefix) {
continue
}
if (value.includes(other)) {
return value.replace(/var\([^)]+\)/, '').includes(other)
}
insert(decl, prefix, prefixes) {
let cloned = this.set(this.clone(decl), prefix)
if (!cloned) return undefined
let already = decl.parent.some(
i => i.prop === cloned.prop && i.value === cloned.value
)
if (already) {
return undefined
}
return false
}
/**
* Set prefix to declaration
*/
set(decl, prefix) {
decl.prop = this.prefixed(decl.prop, prefix)
return decl
if (this.needCascade(decl)) {
cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
}
return decl.parent.insertBefore(decl, cloned)
}
/**
* Should we use visual cascade for prefixes
* Did this declaration has this prefix above
*/
needCascade(decl) {
if (!decl._autoprefixerCascade) {
decl._autoprefixerCascade =
this.all.options.cascade !== false && decl.raw('before').includes('\n')
isAlready(decl, prefixed) {
let already = this.all.group(decl).up(i => i.prop === prefixed)
if (!already) {
already = this.all.group(decl).down(i => i.prop === prefixed)
}
return decl._autoprefixerCascade
return already
}

@@ -83,78 +95,46 @@

/**
* Calculate indentation to create visual cascade
* Should we use visual cascade for prefixes
*/
calcBefore(prefixes, decl, prefix = '') {
let max = this.maxPrefixed(prefixes, decl)
let diff = max - utils.removeNote(prefix).length
let before = decl.raw('before')
if (diff > 0) {
before += Array(diff).fill(' ').join('')
needCascade(decl) {
if (!decl._autoprefixerCascade) {
decl._autoprefixerCascade =
this.all.options.cascade !== false && decl.raw('before').includes('\n')
}
return before
return decl._autoprefixerCascade
}
/**
* Remove visual cascade
* Return unprefixed version of property
*/
restoreBefore(decl) {
let lines = decl.raw('before').split('\n')
let min = lines[lines.length - 1]
this.all.group(decl).up(prefixed => {
let array = prefixed.raw('before').split('\n')
let last = array[array.length - 1]
if (last.length < min.length) {
min = last
}
})
lines[lines.length - 1] = min
decl.raws.before = lines.join('\n')
normalize(prop) {
return prop
}
/**
* Clone and insert new declaration
* Return list of prefixed properties to clean old prefixes
*/
insert(decl, prefix, prefixes) {
let cloned = this.set(this.clone(decl), prefix)
if (!cloned) return undefined
let already = decl.parent.some(
i => i.prop === cloned.prop && i.value === cloned.value
)
if (already) {
return undefined
}
if (this.needCascade(decl)) {
cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
}
return decl.parent.insertBefore(decl, cloned)
old(prop, prefix) {
return [this.prefixed(prop, prefix)]
}
/**
* Did this declaration has this prefix above
* Check `value`, that it contain other prefixes, rather than `prefix`
*/
isAlready(decl, prefixed) {
let already = this.all.group(decl).up(i => i.prop === prefixed)
if (!already) {
already = this.all.group(decl).down(i => i.prop === prefixed)
otherPrefixes(value, prefix) {
for (let other of Browsers.prefixes()) {
if (other === prefix) {
continue
}
if (value.includes(other)) {
return value.replace(/var\([^)]+\)/, '').includes(other)
}
}
return already
return false
}
/**
* Clone and add prefixes for declaration
* Return prefixed version of property
*/
add(decl, prefix, prefixes, result) {
let prefixed = this.prefixed(decl.prop, prefix)
if (
this.isAlready(decl, prefixed) ||
this.otherPrefixes(decl.value, prefix)
) {
return undefined
}
return this.insert(decl, prefix, prefixes, result)
prefixed(prop, prefix) {
return prefix + prop
}

@@ -182,9 +162,29 @@

/**
* Return list of prefixed properties to clean old prefixes
* Remove visual cascade
*/
old(prop, prefix) {
return [this.prefixed(prop, prefix)]
restoreBefore(decl) {
let lines = decl.raw('before').split('\n')
let min = lines[lines.length - 1]
this.all.group(decl).up(prefixed => {
let array = prefixed.raw('before').split('\n')
let last = array[array.length - 1]
if (last.length < min.length) {
min = last
}
})
lines[lines.length - 1] = min
decl.raws.before = lines.join('\n')
}
/**
* Set prefix to declaration
*/
set(decl, prefix) {
decl.prop = this.prefixed(decl.prop, prefix)
return decl
}
}
module.exports = Declaration

@@ -6,2 +6,9 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'align-content'
}
/**
* Change property name for 2012 spec

@@ -19,9 +26,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'align-content'
}
/**
* Change value for 2012 spec and ignore prefix for 2009

@@ -47,6 +47,6 @@ */

'flex-start': 'start',
'space-between': 'justify',
'space-around': 'distribute'
'space-around': 'distribute',
'space-between': 'justify'
}
module.exports = AlignContent

@@ -6,2 +6,9 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'align-items'
}
/**
* Change property name for 2009 and 2012 specs

@@ -22,9 +29,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'align-items'
}
/**
* Change value for 2009 and 2012 specs

@@ -31,0 +31,0 @@ */

@@ -15,2 +15,9 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'align-self'
}
/**
* Change property name for 2012 specs

@@ -28,9 +35,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'align-self'
}
/**
* Change value for 2012 spec and ignore prefix for 2009

@@ -37,0 +37,0 @@ */

@@ -5,2 +5,12 @@ let Declaration = require('../declaration')

/**
* Return property name by spec
*/
normalize(prop) {
if (prop.includes('-before')) {
return prop.replace('-before', '-block-start')
}
return prop.replace('-after', '-block-end')
}
/**
* Use old syntax for -moz- and -webkit-

@@ -14,12 +24,2 @@ */

}
/**
* Return property name by spec
*/
normalize(prop) {
if (prop.includes('-before')) {
return prop.replace('-before', '-block-start')
}
return prop.replace('-after', '-block-end')
}
}

@@ -26,0 +26,0 @@

@@ -5,2 +5,9 @@ let Declaration = require('../declaration')

/**
* Return unprefixed version of property
*/
normalize(prop) {
return BorderRadius.toNormal[prop] || prop
}
/**
* Change syntax, when add Mozilla prefix

@@ -14,9 +21,2 @@ */

}
/**
* Return unprefixed version of property
*/
normalize(prop) {
return BorderRadius.toNormal[prop] || prop
}
}

@@ -23,0 +23,0 @@

@@ -5,6 +5,12 @@ let Declaration = require('../declaration')

/**
* Change name for -webkit- and -moz- prefix
* Don’t prefix some values
*/
prefixed(prop, prefix) {
return `${prefix}column-${prop}`
insert(decl, prefix, prefixes) {
if (decl.prop !== 'break-inside') {
return super.insert(decl, prefix, prefixes)
}
if (/region/i.test(decl.value) || /page/i.test(decl.value)) {
return undefined
}
return super.insert(decl, prefix, prefixes)
}

@@ -26,2 +32,9 @@

/**
* Change name for -webkit- and -moz- prefix
*/
prefixed(prop, prefix) {
return `${prefix}column-${prop}`
}
/**
* Change prefixed value for avoid-column and avoid-page

@@ -38,15 +51,2 @@ */

}
/**
* Don’t prefix some values
*/
insert(decl, prefix, prefixes) {
if (decl.prop !== 'break-inside') {
return super.insert(decl, prefix, prefixes)
}
if (/region/i.test(decl.value) || /page/i.test(decl.value)) {
return undefined
}
return super.insert(decl, prefix, prefixes)
}
}

@@ -53,0 +53,0 @@

@@ -21,2 +21,11 @@ let flexSpec = require('./flex-spec')

/**
* Change value for old specs
*/
old(prefix) {
let prefixed = this.prefixed(prefix)
if (!prefixed) return undefined
return new OldValue(this.name, prefixed)
}
/**
* Return value by spec

@@ -53,11 +62,2 @@ */

}
/**
* Change value for old specs
*/
old(prefix) {
let prefixed = this.prefixed(prefix)
if (!prefixed) return undefined
return new OldValue(this.name, prefixed)
}
}

@@ -64,0 +64,0 @@

@@ -6,9 +6,2 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'flex-direction'
}
/**
* Use two properties for 2009 spec

@@ -58,2 +51,9 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'flex-direction'
}
/**
* Clean two properties for 2009 spec

@@ -60,0 +60,0 @@ */

@@ -8,2 +8,9 @@ let list = require('postcss').list

/**
* Return property name by final spec
*/
normalize() {
return 'flex'
}
/**
* Change property name for 2009 spec

@@ -21,9 +28,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'flex'
}
/**
* Spec 2009 supports only first argument

@@ -30,0 +30,0 @@ * Spec 2012 disallows unitless basis

@@ -12,141 +12,75 @@ let parser = require('postcss-value-parser')

/**
* Change degrees for webkit prefix
* Do not add non-webkit prefixes for list-style and object
*/
replace(string, prefix) {
let ast = parser(string)
for (let node of ast.nodes) {
let gradientName = this.name // gradient name
if (node.type === 'function' && node.value === gradientName) {
node.nodes = this.newDirection(node.nodes)
node.nodes = this.normalize(node.nodes, gradientName)
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
}
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 ast.toString()
return undefined
}
/**
* Replace first token
* Get div token from exists parameters
*/
replaceFirst(params, ...words) {
let prefix = words.map(i => {
if (i === ' ') {
return { type: 'space', value: i }
cloneDiv(params) {
for (let i of params) {
if (i.type === 'div' && i.value === ',') {
return 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, gradientName) {
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 (
gradientName === 'linear-gradient' ||
gradientName === 'repeating-linear-gradient'
) {
let direction = nodes[0].value
// Unitless zero for `<angle>` values are allowed in CSS gradients and transforms.
// Spec: https://github.com/w3c/csswg-drafts/commit/602789171429b2231223ab1e5acf8f7f11652eb3
if (direction === '0deg' || direction === '0') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'top')
} else if (direction === '90deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'right')
} else if (direction === '180deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'bottom') // default value
} else if (direction === '270deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'left')
}
}
return nodes
return { after: ' ', type: 'div', value: ',' }
}
/**
* Replace old direction to new
* Change colors syntax to old webkit
*/
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: ' '
colorStops(params) {
let result = []
for (let i = 0; i < params.length; i++) {
let pos
let param = params[i]
let item
if (i === 0) {
continue
}
)
for (let i = 2; i < params.length; i++) {
if (params[i].type === 'div') {
break
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
}
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
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 {
state = 'before'
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 false
return result
}

@@ -171,2 +105,13 @@

/**
* 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`
}
/**
* Replace `to top left` to `bottom right`

@@ -188,13 +133,2 @@ */

/**
* 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

@@ -232,57 +166,132 @@ */

revertDirection(word) {
return Gradient.directions[word.toLowerCase()] || word
/**
* 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
}
/**
* Round float and save digits under dot
* Replace old direction to new
*/
roundFloat(float, digits) {
return parseFloat(float.toFixed(digits))
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
}
/**
* Convert to old webkit syntax
* Normalize angle
*/
oldWebkit(node) {
let { nodes } = node
let string = parser.stringify(node.nodes)
normalize(nodes, gradientName) {
if (!nodes[0]) return nodes
if (this.name !== 'linear-gradient') {
return false
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] && nodes[0].value.includes('deg')) {
return false
}
if (
string.includes('px') ||
string.includes('-corner') ||
string.includes('-side')
gradientName === 'linear-gradient' ||
gradientName === 'repeating-linear-gradient'
) {
return false
}
let direction = nodes[0].value
let params = [[]]
for (let i of nodes) {
params[params.length - 1].push(i)
if (i.type === 'div' && i.value === ',') {
params.push([])
// Unitless zero for `<angle>` values are allowed in CSS gradients and transforms.
// Spec: https://github.com/w3c/csswg-drafts/commit/602789171429b2231223ab1e5acf8f7f11652eb3
if (direction === '0deg' || direction === '0') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'top')
} else if (direction === '90deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'right')
} else if (direction === '180deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'bottom') // default value
} else if (direction === '270deg') {
nodes = this.replaceFirst(nodes, 'to', ' ', 'left')
}
}
this.oldDirection(params)
this.colorStops(params)
return nodes
}
node.nodes = []
for (let param of params) {
node.nodes = node.nodes.concat(param)
}
/**
* Convert angle unit to deg
*/
normalizeUnit(str, full) {
let num = parseFloat(str)
let deg = (num / full) * 360
return `${deg}deg`
}
node.nodes.unshift(
{ type: 'word', value: 'linear' },
this.cloneDiv(node.nodes)
)
node.value = '-webkit-gradient'
/**
* Remove old WebKit gradient too
*/
old(prefix) {
if (prefix === '-webkit-') {
let type
if (this.name === 'linear-gradient') {
type = 'linear'
} else if (this.name === 'repeating-linear-gradient') {
type = 'repeating-linear'
} else if (this.name === 'repeating-radial-gradient') {
type = 'repeating-radial'
} else {
type = 'radial'
}
let string = '-gradient'
let regexp = utils.regexp(
`-webkit-(${type}-gradient|gradient\\(\\s*${type})`,
false
)
return true
return new OldValue(this.name, prefix + this.name, string, regexp)
} else {
return super.old(prefix)
}
}

@@ -318,102 +327,93 @@

/**
* Get div token from exists parameters
* Convert to old webkit syntax
*/
cloneDiv(params) {
for (let i of params) {
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 === ',') {
return i
params.push([])
}
}
return { type: 'div', value: ',', after: ' ' }
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 colors syntax to old webkit
* Change degrees for webkit prefix
*/
colorStops(params) {
let result = []
for (let i = 0; i < params.length; i++) {
let pos
let param = params[i]
let item
if (i === 0) {
continue
replace(string, prefix) {
let ast = parser(string)
for (let node of ast.nodes) {
let gradientName = this.name // gradient name
if (node.type === 'function' && node.value === gradientName) {
node.nodes = this.newDirection(node.nodes)
node.nodes = this.normalize(node.nodes, gradientName)
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
}
}
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
return ast.toString()
}
/**
* Remove old WebKit gradient too
* Replace first token
*/
old(prefix) {
if (prefix === '-webkit-') {
let type
if (this.name === 'linear-gradient') {
type = 'linear'
} else if (this.name === 'repeating-linear-gradient') {
type = 'repeating-linear'
} else if (this.name === 'repeating-radial-gradient') {
type = 'repeating-radial'
} else {
type = 'radial'
replaceFirst(params, ...words) {
let prefix = words.map(i => {
if (i === ' ') {
return { type: 'space', value: i }
}
let string = '-gradient'
let regexp = utils.regexp(
`-webkit-(${type}-gradient|gradient\\(\\s*${type})`,
false
)
return { type: 'word', value: i }
})
return prefix.concat(params.slice(1))
}
return new OldValue(this.name, prefix + this.name, string, regexp)
} else {
return super.old(prefix)
}
revertDirection(word) {
return Gradient.directions[word.toLowerCase()] || word
}
/**
* Do not add non-webkit prefixes for list-style and object
* Round float and save digits under dot
*/
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
roundFloat(float, digits) {
return parseFloat(float.toFixed(digits))
}

@@ -430,6 +430,6 @@ }

Gradient.directions = {
top: 'bottom', // default value
bottom: 'top',
left: 'right',
bottom: 'top',
right: 'left'
right: 'left',
top: 'bottom' // default value
}

@@ -439,17 +439,17 @@

Gradient.oldDirections = {
'top': 'left bottom, left top',
'bottom': 'left top, left bottom',
'bottom left': 'right top, left bottom',
'bottom right': 'left top, right bottom',
'left': 'right top, left top',
'bottom': 'left top, left bottom',
'left bottom': 'right top, left bottom',
'left top': 'right bottom, left top',
'right': 'left top, right top',
'top right': 'left bottom, right top',
'right bottom': 'left top, right bottom',
'right top': 'left bottom, right top',
'top': 'left bottom, left 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'
'top right': 'left bottom, right top'
}
module.exports = Gradient

@@ -12,13 +12,13 @@ let Declaration = require('../declaration')

/**
* Change property name for IE
* Change IE property back
*/
prefixed(prop, prefix) {
return prefix + 'grid-column-align'
normalize() {
return 'justify-self'
}
/**
* Change IE property back
* Change property name for IE
*/
normalize() {
return 'justify-self'
prefixed(prop, prefix) {
return prefix + 'grid-column-align'
}

@@ -25,0 +25,0 @@ }

@@ -12,13 +12,13 @@ let Declaration = require('../declaration')

/**
* Change property name for IE
* Change IE property back
*/
prefixed(prop, prefix) {
return prefix + 'grid-row-align'
normalize() {
return 'align-self'
}
/**
* Change IE property back
* Change property name for IE
*/
normalize() {
return 'align-self'
prefixed(prop, prefix) {
return prefix + 'grid-row-align'
}

@@ -25,0 +25,0 @@ }

let Declaration = require('../declaration')
let {
prefixTrackProp,
prefixTrackValue,
autoplaceGridItems,
getGridGap,
inheritGridGap
inheritGridGap,
prefixTrackProp,
prefixTrackValue
} = require('./grid-utils')

@@ -12,19 +12,2 @@ let Processor = require('../processor')

class GridRowsColumns extends Declaration {
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
if (prefix === '-ms-') {
return prefixTrackProp({ prop, prefix })
}
return super.prefixed(prop, prefix)
}
/**
* Change IE property back
*/
normalize(prop) {
return prop.replace(/^grid-(rows|columns)/, 'grid-template-$1')
}
insert(decl, prefix, prefixes, result) {

@@ -60,4 +43,4 @@ if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)

let prefixValue = prefixTrackValue({
value,
gap: gapValue
gap: gapValue,
value
})

@@ -69,3 +52,3 @@

decl.cloneBefore({
prop: prefixTrackProp({ prop, prefix }),
prop: prefixTrackProp({ prefix, prop }),
value: prefixValue

@@ -119,2 +102,19 @@ })

}
/**
* Change IE property back
*/
normalize(prop) {
return prop.replace(/^grid-(rows|columns)/, 'grid-template-$1')
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
if (prefix === '-ms-') {
return prefixTrackProp({ prefix, prop })
}
return super.prefixed(prop, prefix)
}
}

@@ -121,0 +121,0 @@

let Declaration = require('../declaration')
let {
getGridGap,
inheritGridGap,
parseGridAreas,
warnMissedAreas,
prefixTrackProp,
prefixTrackValue,
getGridGap,
warnGridGap,
inheritGridGap
warnMissedAreas
} = require('./grid-utils')

@@ -42,4 +42,4 @@

trackDecl.cloneBefore({
prop: prefixTrackProp({ prop, prefix }),
value: prefixTrackValue({ value, gap: gap.row })
prop: prefixTrackProp({ prefix, prop }),
value: prefixTrackValue({ gap: gap.row, value })
})

@@ -56,7 +56,7 @@ } else {

prop: '-ms-grid-rows',
raws: {},
value: prefixTrackValue({
value: `repeat(${gridRows.length}, auto)`,
gap: gap.row
}),
raws: {}
gap: gap.row,
value: `repeat(${gridRows.length}, auto)`
})
})

@@ -67,5 +67,5 @@ }

warnGridGap({
decl,
gap,
hasColumns,
decl,
result

@@ -75,4 +75,4 @@ })

let areas = parseGridAreas({
rows: gridRows,
gap
gap,
rows: gridRows
})

@@ -79,0 +79,0 @@

let Declaration = require('../declaration')
let {
getGridGap,
inheritGridGap,
parseTemplate,
warnMissedAreas,
getGridGap,
warnGridGap,
inheritGridGap
warnMissedAreas
} = require('./grid-utils')

@@ -29,3 +29,3 @@

let { rows, columns, areas } = parseTemplate({
let { areas, columns, rows } = parseTemplate({
decl,

@@ -40,5 +40,5 @@ gap: inheritedGap || gap

warnGridGap({
decl,
gap,
hasColumns,
decl,
result

@@ -52,4 +52,4 @@ })

prop: '-ms-grid-rows',
value: rows,
raws: {}
raws: {},
value: rows
})

@@ -61,4 +61,4 @@ }

prop: '-ms-grid-columns',
value: columns,
raws: {}
raws: {},
value: columns
})

@@ -65,0 +65,0 @@ }

@@ -93,3 +93,3 @@ let parser = require('postcss-value-parser')

function prefixTrackProp({ prop, prefix }) {
function prefixTrackProp({ prefix, prop }) {
return prefix + prop.replace('template-', '')

@@ -109,5 +109,5 @@ }

{
count: [],
key: 'count',
size: [],
count: []
size: []
}

@@ -137,3 +137,3 @@ )

function prefixTrackValue({ value, gap }) {
function prefixTrackValue({ gap, value }) {
let result = parser(value).nodes.reduce((nodes, node) => {

@@ -170,3 +170,3 @@ if (node.type === 'function' && node.value === 'repeat') {

function track(start, end) {
return { start, end, span: end - start }
return { end, span: end - start, start }
}

@@ -180,3 +180,3 @@

function parseGridAreas({ rows, gap }) {
function parseGridAreas({ gap, rows }) {
return rows.reduce((areas, line, rowIndex) => {

@@ -256,6 +256,6 @@ if (gap.row) rowIndex *= 2

{
areas: [],
columns: [],
key: 'rows',
columns: [],
rows: [],
areas: []
rows: []
}

@@ -266,12 +266,12 @@ )

areas: parseGridAreas({
rows: gridTemplate.areas,
gap
gap,
rows: gridTemplate.areas
}),
columns: prefixTrackValue({
value: gridTemplate.columns.join(' '),
gap: gap.column
gap: gap.column,
value: gridTemplate.columns.join(' ')
}),
rows: prefixTrackValue({
value: gridTemplate.rows.join(' '),
gap: gap.row
gap: gap.row,
value: gridTemplate.rows.join(' ')
})

@@ -439,8 +439,8 @@ }

parsed[index].rules.push({
areas,
duplicateAreaNames,
hasDuplicates: !hasNoDuplicates,
node: rule,
params: media.params,
selectors: rule.selectors,
node: rule,
duplicateAreaNames,
areas
selectors: rule.selectors
})

@@ -454,9 +454,9 @@ } else {

{
areas,
duplicateAreaNames: [],
duplicateRules: [],
hasDuplicates: false,
duplicateRules: [],
node: rule,
params: media.params,
selectors: rule.selectors,
node: rule,
duplicateAreaNames: [],
areas
selectors: rule.selectors
}

@@ -1005,3 +1005,3 @@ ]

function warnGridGap({ gap, hasColumns, decl, result }) {
function warnGridGap({ decl, gap, hasColumns, result }) {
let hasBothGaps = gap.row && gap.column

@@ -1092,3 +1092,3 @@ if (!hasColumns && (hasBothGaps || (gap.column && !gap.row))) {

let areas = parseGridAreas({ rows: filledRows, gap })
let areas = parseGridAreas({ gap, rows: filledRows })
let keys = Object.keys(areas)

@@ -1095,0 +1095,0 @@ let items = keys.map(i => areas[i])

@@ -12,2 +12,9 @@ let Declaration = require('../declaration')

/**
* Return property name by spec
*/
normalize() {
return 'image-rendering'
}
/**
* Change property name for IE

@@ -23,2 +30,9 @@ */

/**
* Warn on old value
*/
process(node, result) {
return super.process(node, result)
}
/**
* Change property and value for IE

@@ -32,16 +46,2 @@ */

}
/**
* Return property name by spec
*/
normalize() {
return 'image-rendering'
}
/**
* Warn on old value
*/
process(node, result) {
return super.process(node, result)
}
}

@@ -48,0 +48,0 @@

@@ -5,13 +5,13 @@ let Declaration = require('../declaration')

/**
* Use old syntax for -moz- and -webkit-
* Return property name by spec
*/
prefixed(prop, prefix) {
return prefix + prop.replace('-inline', '')
normalize(prop) {
return prop.replace(/(margin|padding|border)-(start|end)/, '$1-inline-$2')
}
/**
* Return property name by spec
* Use old syntax for -moz- and -webkit-
*/
normalize(prop) {
return prop.replace(/(margin|padding|border)-(start|end)/, '$1-inline-$2')
prefixed(prop, prefix) {
return prefix + prop.replace('-inline', '')
}

@@ -18,0 +18,0 @@ }

@@ -9,5 +9,7 @@ let OldValue = require('../old-value')

class Intrinsic extends Value {
regexp() {
if (!this.regexpCache) this.regexpCache = regexp(this.name)
return this.regexpCache
add(decl, prefix) {
if (decl.prop.includes('grid') && prefix !== '-webkit-') {
return undefined
}
return super.add(decl, prefix)
}

@@ -23,12 +25,2 @@

replace(string, prefix) {
if (prefix === '-moz-' && this.isStretch()) {
return string.replace(this.regexp(), '$1-moz-available$3')
}
if (prefix === '-webkit-' && this.isStretch()) {
return string.replace(this.regexp(), '$1-webkit-fill-available$3')
}
return super.replace(string, prefix)
}
old(prefix) {

@@ -46,7 +38,15 @@ let prefixed = prefix + this.name

add(decl, prefix) {
if (decl.prop.includes('grid') && prefix !== '-webkit-') {
return undefined
regexp() {
if (!this.regexpCache) this.regexpCache = regexp(this.name)
return this.regexpCache
}
replace(string, prefix) {
if (prefix === '-moz-' && this.isStretch()) {
return string.replace(this.regexp(), '$1-moz-available$3')
}
return super.add(decl, prefix)
if (prefix === '-webkit-' && this.isStretch()) {
return string.replace(this.regexp(), '$1-webkit-fill-available$3')
}
return super.replace(string, prefix)
}

@@ -53,0 +53,0 @@ }

@@ -6,2 +6,9 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'justify-content'
}
/**
* Change property name for 2009 and 2012 specs

@@ -22,9 +29,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'justify-content'
}
/**
* Change value for 2009 and 2012 specs

@@ -52,6 +52,6 @@ */

'flex-start': 'start',
'space-between': 'justify',
'space-around': 'distribute'
'space-around': 'distribute',
'space-between': 'justify'
}
module.exports = JustifyContent

@@ -76,5 +76,5 @@ let Declaration = require('../declaration')

add: 'source-over',
subtract: 'source-out',
exclude: 'xor',
intersect: 'source-in',
exclude: 'xor'
subtract: 'source-out'
}

@@ -81,0 +81,0 @@

@@ -6,2 +6,9 @@ let flexSpec = require('./flex-spec')

/**
* Return property name by final spec
*/
normalize() {
return 'order'
}
/**
* Change property name for 2009 and 2012 specs

@@ -22,9 +29,2 @@ */

/**
* Return property name by final spec
*/
normalize() {
return 'order'
}
/**
* Fix value for 2009 spec

@@ -31,0 +31,0 @@ */

@@ -5,13 +5,13 @@ let Declaration = require('../declaration')

/**
* Change property name for IE
* Return property name by spec
*/
prefixed(prop, prefix) {
return prefix + 'scroll-chaining'
normalize() {
return 'overscroll-behavior'
}
/**
* Return property name by spec
* Change property name for IE
*/
normalize() {
return 'overscroll-behavior'
prefixed(prop, prefix) {
return prefix + 'scroll-chaining'
}

@@ -18,0 +18,0 @@

@@ -6,25 +6,25 @@ let OldValue = require('../old-value')

/**
* Use non-standard name for WebKit and Firefox
* Different name for WebKit and Firefox
*/
replace(string, prefix) {
old(prefix) {
if (prefix === '-webkit-') {
return string.replace(this.regexp(), '$1-webkit-optimize-contrast')
return new OldValue(this.name, '-webkit-optimize-contrast')
}
if (prefix === '-moz-') {
return string.replace(this.regexp(), '$1-moz-crisp-edges')
return new OldValue(this.name, '-moz-crisp-edges')
}
return super.replace(string, prefix)
return super.old(prefix)
}
/**
* Different name for WebKit and Firefox
* Use non-standard name for WebKit and Firefox
*/
old(prefix) {
replace(string, prefix) {
if (prefix === '-webkit-') {
return new OldValue(this.name, '-webkit-optimize-contrast')
return string.replace(this.regexp(), '$1-webkit-optimize-contrast')
}
if (prefix === '-moz-') {
return new OldValue(this.name, '-moz-crisp-edges')
return string.replace(this.regexp(), '$1-moz-crisp-edges')
}
return super.old(prefix)
return super.replace(string, prefix)
}

@@ -31,0 +31,0 @@ }

@@ -5,2 +5,9 @@ let Declaration = require('../declaration')

/**
* Return property name by spec
*/
normalize() {
return 'print-color-adjust'
}
/**
* Change property name for WebKit-based browsers

@@ -15,9 +22,2 @@ */

}
/**
* Return property name by spec
*/
normalize() {
return 'print-color-adjust'
}
}

@@ -24,0 +24,0 @@

@@ -5,16 +5,2 @@ let Declaration = require('../declaration')

/**
* Recursively check all parents for @keyframes
*/
keyframeParents(decl) {
let { parent } = decl
while (parent) {
if (parent.type === 'atrule' && parent.name === 'keyframes') {
return true
}
;({ parent } = parent)
}
return false
}
/**
* Is transform contain 3D commands

@@ -37,13 +23,2 @@ */

/**
* Replace rotateZ to rotate for IE 9
*/
set(decl, prefix) {
decl = super.set(decl, prefix)
if (prefix === '-ms-') {
decl.value = decl.value.replace(/rotatez/gi, 'rotate')
}
return decl
}
/**
* Don't add prefix for IE in keyframes

@@ -65,2 +40,27 @@ */

}
/**
* Recursively check all parents for @keyframes
*/
keyframeParents(decl) {
let { parent } = decl
while (parent) {
if (parent.type === 'atrule' && parent.name === 'keyframes') {
return true
}
;({ parent } = parent)
}
return false
}
/**
* Replace rotateZ to rotate for IE 9
*/
set(decl, prefix) {
decl = super.set(decl, prefix)
if (prefix === '-ms-') {
decl.value = decl.value.replace(/rotatez/gi, 'rotate')
}
return decl
}
}

@@ -67,0 +67,0 @@

@@ -5,12 +5,2 @@ let Declaration = require('../declaration')

/**
* Change prefixed value for IE
*/
set(decl, prefix) {
if (prefix === '-ms-' && decl.value === 'contain') {
decl.value = 'element'
}
return super.set(decl, prefix)
}
/**
* Avoid prefixing all in IE

@@ -25,2 +15,12 @@ */

}
/**
* Change prefixed value for IE
*/
set(decl, prefix) {
if (prefix === '-ms-' && decl.value === 'contain') {
decl.value = 'element'
}
return super.set(decl, prefix)
}
}

@@ -27,0 +27,0 @@

@@ -32,9 +32,9 @@ let Declaration = require('../declaration')

'horizontal-tb': 'lr-tb',
'vertical-rl': 'tb-rl',
'vertical-lr': 'tb-lr'
'vertical-lr': 'tb-lr',
'vertical-rl': 'tb-rl'
},
rtl: {
'horizontal-tb': 'rl-tb',
'vertical-rl': 'bt-rl',
'vertical-lr': 'bt-lr'
'vertical-lr': 'bt-lr',
'vertical-rl': 'bt-rl'
}

@@ -41,0 +41,0 @@ }

@@ -8,13 +8,13 @@ let browserslist = require('browserslist')

const NAMES = {
and_chr: 'Chrome for Android',
and_ff: 'Firefox for Android',
and_qq: 'QQ Browser',
and_uc: 'UC for Android',
baidu: 'Baidu Browser',
ie: 'IE',
ie_mob: 'IE Mobile',
ios_saf: 'iOS Safari',
kaios: 'KaiOS Browser',
op_mini: 'Opera Mini',
op_mob: 'Opera Mobile',
and_chr: 'Chrome for Android',
and_ff: 'Firefox for Android',
and_uc: 'UC for Android',
and_qq: 'QQ Browser',
kaios: 'KaiOS Browser',
baidu: 'Baidu Browser',
samsung: 'Samsung Internet'

@@ -21,0 +21,0 @@ }

@@ -16,2 +16,18 @@ class OldSelector {

/**
* Does rule contain an unnecessary prefixed selector
*/
check(rule) {
if (!rule.selector.includes(this.prefixed)) {
return false
}
if (!rule.selector.match(this.regexp)) {
return false
}
if (this.isHack(rule)) {
return false
}
return true
}
/**
* Is rule a hack without unprefixed version bottom

@@ -50,20 +66,4 @@ */

}
/**
* Does rule contain an unnecessary prefixed selector
*/
check(rule) {
if (!rule.selector.includes(this.prefixed)) {
return false
}
if (!rule.selector.match(this.regexp)) {
return false
}
if (this.isHack(rule)) {
return false
}
return true
}
}
module.exports = OldSelector

@@ -37,3 +37,20 @@ let Browsers = require('./browsers')

class Prefixer {
constructor(name, prefixes, all) {
this.prefixes = prefixes
this.name = name
this.all = all
}
/**
* Clone node and clean autprefixer custom caches
*/
static clone(node, overrides) {
let cloned = clone(node)
for (let name in overrides) {
cloned[name] = overrides[name]
}
return cloned
}
/**
* Add hack to selected names

@@ -64,18 +81,8 @@ */

/**
* Clone node and clean autprefixer custom caches
* Shortcut for Prefixer.clone
*/
static clone(node, overrides) {
let cloned = clone(node)
for (let name in overrides) {
cloned[name] = overrides[name]
}
return cloned
clone(node, overrides) {
return Prefixer.clone(node, overrides)
}
constructor(name, prefixes, all) {
this.prefixes = prefixes
this.name = name
this.all = all
}
/**

@@ -137,11 +144,4 @@ * Find prefix in node parents

}
/**
* Shortcut for Prefixer.clone
*/
clone(node, overrides) {
return Prefixer.clone(node, overrides)
}
}
module.exports = Prefixer

@@ -159,72 +159,73 @@ let vendor = require('./vendor')

/**
* Select prefixes from data, which is necessary for selected browsers
* Declaration loader with caching
*/
select(list) {
let selected = { add: {}, remove: {} }
decl(prop) {
if (!declsCache.has(prop)) {
declsCache.set(prop, Declaration.load(prop))
}
for (let name in list) {
let data = list[name]
let add = data.browsers.map(i => {
let params = i.split(' ')
return {
browser: `${params[0]} ${params[1]}`,
note: params[2]
}
})
return declsCache.get(prop)
}
let notes = add
.filter(i => i.note)
.map(i => `${this.browsers.prefix(i.browser)} ${i.note}`)
notes = utils.uniq(notes)
/**
* Group declaration by unprefixed property to check them
*/
group(decl) {
let rule = decl.parent
let index = rule.index(decl)
let { length } = rule.nodes
let unprefixed = this.unprefixed(decl.prop)
add = add
.filter(i => this.browsers.isSelected(i.browser))
.map(i => {
let prefix = this.browsers.prefix(i.browser)
if (i.note) {
return `${prefix} ${i.note}`
} else {
return prefix
let checker = (step, callback) => {
index += step
while (index >= 0 && index < length) {
let other = rule.nodes[index]
if (other.type === 'decl') {
if (step === -1 && other.prop === unprefixed) {
if (!Browsers.withPrefix(other.value)) {
break
}
}
})
add = this.sort(utils.uniq(add))
if (this.options.flexbox === 'no-2009') {
add = add.filter(i => !i.includes('2009'))
}
if (this.unprefixed(other.prop) !== unprefixed) {
break
} else if (callback(other) === true) {
return true
}
let all = data.browsers.map(i => this.browsers.prefix(i))
if (data.mistakes) {
all = all.concat(data.mistakes)
if (step === +1 && other.prop === unprefixed) {
if (!Browsers.withPrefix(other.value)) {
break
}
}
}
index += step
}
all = all.concat(notes)
all = utils.uniq(all)
return false
}
if (add.length) {
selected.add[name] = add
if (add.length < all.length) {
selected.remove[name] = all.filter(i => !add.includes(i))
}
} else {
selected.remove[name] = all
return {
down(callback) {
return checker(+1, callback)
},
up(callback) {
return checker(-1, callback)
}
}
}
return selected
/**
* Normalize prefix for remover
*/
normalize(prop) {
return this.decl(prop).normalize(prop)
}
/**
* Sort vendor prefixes
* Return prefixed version of property
*/
sort(prefixes) {
return prefixes.sort((a, b) => {
let aLength = utils.removeNote(a).length
let bLength = utils.removeNote(b).length
if (aLength === bLength) {
return b.length - a.length
} else {
return bLength - aLength
}
})
prefixed(prop, prefix) {
prop = vendor.unprefixed(prop)
return this.decl(prop).prefixed(prop, prefix)
}

@@ -237,4 +238,4 @@

let add = {
'selectors': [],
'@supports': new Supports(Prefixes, this)
'@supports': new Supports(Prefixes, this),
'selectors': []
}

@@ -329,13 +330,75 @@ for (let name in selected.add) {

/**
* Declaration loader with caching
* Select prefixes from data, which is necessary for selected browsers
*/
decl(prop) {
if (!declsCache.has(prop)) {
declsCache.set(prop, Declaration.load(prop))
select(list) {
let selected = { add: {}, remove: {} }
for (let name in list) {
let data = list[name]
let add = data.browsers.map(i => {
let params = i.split(' ')
return {
browser: `${params[0]} ${params[1]}`,
note: params[2]
}
})
let notes = add
.filter(i => i.note)
.map(i => `${this.browsers.prefix(i.browser)} ${i.note}`)
notes = utils.uniq(notes)
add = add
.filter(i => this.browsers.isSelected(i.browser))
.map(i => {
let prefix = this.browsers.prefix(i.browser)
if (i.note) {
return `${prefix} ${i.note}`
} else {
return prefix
}
})
add = this.sort(utils.uniq(add))
if (this.options.flexbox === 'no-2009') {
add = add.filter(i => !i.includes('2009'))
}
let all = data.browsers.map(i => this.browsers.prefix(i))
if (data.mistakes) {
all = all.concat(data.mistakes)
}
all = all.concat(notes)
all = utils.uniq(all)
if (add.length) {
selected.add[name] = add
if (add.length < all.length) {
selected.remove[name] = all.filter(i => !add.includes(i))
}
} else {
selected.remove[name] = all
}
}
return declsCache.get(prop)
return selected
}
/**
* Sort vendor prefixes
*/
sort(prefixes) {
return prefixes.sort((a, b) => {
let aLength = utils.removeNote(a).length
let bLength = utils.removeNote(b).length
if (aLength === bLength) {
return b.length - a.length
} else {
return bLength - aLength
}
})
}
/**
* Return unprefixed version of property

@@ -352,17 +415,2 @@ */

/**
* Normalize prefix for remover
*/
normalize(prop) {
return this.decl(prop).normalize(prop)
}
/**
* Return prefixed version of property
*/
prefixed(prop, prefix) {
prop = vendor.unprefixed(prop)
return this.decl(prop).prefixed(prop, prefix)
}
/**
* Return values, which must be prefixed in selected property

@@ -382,52 +430,4 @@ */

}
/**
* Group declaration by unprefixed property to check them
*/
group(decl) {
let rule = decl.parent
let index = rule.index(decl)
let { length } = rule.nodes
let unprefixed = this.unprefixed(decl.prop)
let checker = (step, callback) => {
index += step
while (index >= 0 && index < length) {
let other = rule.nodes[index]
if (other.type === 'decl') {
if (step === -1 && other.prop === unprefixed) {
if (!Browsers.withPrefix(other.value)) {
break
}
}
if (this.unprefixed(other.prop) !== unprefixed) {
break
} else if (callback(other) === true) {
return true
}
if (step === +1 && other.prop === unprefixed) {
if (!Browsers.withPrefix(other.value)) {
break
}
}
}
index += step
}
return false
}
return {
up(callback) {
return checker(-1, callback)
},
down(callback) {
return checker(+1, callback)
}
}
}
}
module.exports = Prefixes

@@ -400,137 +400,2 @@ let parser = require('postcss-value-parser')

/**
* Remove unnecessary pefixes
*/
remove(css, result) {
// At-rules
let resolution = this.prefixes.remove['@resolution']
css.walkAtRules((rule, i) => {
if (this.prefixes.remove[`@${rule.name}`]) {
if (!this.disabled(rule, result)) {
rule.parent.removeChild(i)
}
} else if (
rule.name === 'media' &&
rule.params.includes('-resolution') &&
resolution
) {
resolution.clean(rule)
}
})
// Selectors
for (let checker of this.prefixes.remove.selectors) {
css.walkRules((rule, i) => {
if (checker.check(rule)) {
if (!this.disabled(rule, result)) {
rule.parent.removeChild(i)
}
}
})
}
return css.walkDecls((decl, i) => {
if (this.disabled(decl, result)) return
let rule = decl.parent
let unprefixed = this.prefixes.unprefixed(decl.prop)
// Transition
if (decl.prop === 'transition' || decl.prop === 'transition-property') {
this.prefixes.transition.remove(decl)
}
// Properties
if (
this.prefixes.remove[decl.prop] &&
this.prefixes.remove[decl.prop].remove
) {
let notHack = this.prefixes.group(decl).down(other => {
return this.prefixes.normalize(other.prop) === unprefixed
})
if (unprefixed === 'flex-flow') {
notHack = true
}
if (decl.prop === '-webkit-box-orient') {
let hacks = { 'flex-direction': true, 'flex-flow': true }
if (!decl.parent.some(j => hacks[j.prop])) return
}
if (notHack && !this.withHackValue(decl)) {
if (decl.raw('before').includes('\n')) {
this.reduceSpaces(decl)
}
rule.removeChild(i)
return
}
}
// Values
for (let checker of this.prefixes.values('remove', unprefixed)) {
if (!checker.check) continue
if (!checker.check(decl.value)) continue
unprefixed = checker.unprefixed
let notHack = this.prefixes.group(decl).down(other => {
return other.value.includes(unprefixed)
})
if (notHack) {
rule.removeChild(i)
return
}
}
})
}
/**
* Some rare old values, which is not in standard
*/
withHackValue(decl) {
return decl.prop === '-webkit-background-clip' && decl.value === 'text'
}
/**
* Check for grid/flexbox options.
*/
disabledValue(node, result) {
if (this.gridStatus(node, result) === false && node.type === 'decl') {
if (node.prop === 'display' && node.value.includes('grid')) {
return true
}
}
if (this.prefixes.options.flexbox === false && node.type === 'decl') {
if (node.prop === 'display' && node.value.includes('flex')) {
return true
}
}
if (node.type === 'decl' && node.prop === 'content') {
return true
}
return this.disabled(node, result)
}
/**
* Check for grid/flexbox options.
*/
disabledDecl(node, result) {
if (this.gridStatus(node, result) === false && node.type === 'decl') {
if (node.prop.includes('grid') || node.prop === 'justify-items') {
return true
}
}
if (this.prefixes.options.flexbox === false && node.type === 'decl') {
let other = ['order', 'justify-content', 'align-items', 'align-content']
if (node.prop.includes('flex') || other.includes(node.prop)) {
return true
}
}
return this.disabled(node, result)
}
/**
* Check for control comment and global options

@@ -594,31 +459,39 @@ */

/**
* Normalize spaces in cascade declaration group
* Check for grid/flexbox options.
*/
reduceSpaces(decl) {
let stop = false
this.prefixes.group(decl).up(() => {
stop = true
return true
})
if (stop) {
return
disabledDecl(node, result) {
if (this.gridStatus(node, result) === false && node.type === 'decl') {
if (node.prop.includes('grid') || node.prop === 'justify-items') {
return true
}
}
if (this.prefixes.options.flexbox === false && node.type === 'decl') {
let other = ['order', 'justify-content', 'align-items', 'align-content']
if (node.prop.includes('flex') || other.includes(node.prop)) {
return true
}
}
let parts = decl.raw('before').split('\n')
let prevMin = parts[parts.length - 1].length
let diff = false
return this.disabled(node, result)
}
this.prefixes.group(decl).down(other => {
parts = other.raw('before').split('\n')
let last = parts.length - 1
/**
* Check for grid/flexbox options.
*/
disabledValue(node, result) {
if (this.gridStatus(node, result) === false && node.type === 'decl') {
if (node.prop === 'display' && node.value.includes('grid')) {
return true
}
}
if (this.prefixes.options.flexbox === false && node.type === 'decl') {
if (node.prop === 'display' && node.value.includes('flex')) {
return true
}
}
if (node.type === 'decl' && node.prop === 'content') {
return true
}
if (parts[last].length > prevMin) {
if (diff === false) {
diff = parts[last].length - prevMin
}
parts[last] = parts[last].slice(0, -diff)
other.raws.before = parts.join('\n')
}
})
return this.disabled(node, result)
}

@@ -718,4 +591,131 @@

}
/**
* Normalize spaces in cascade declaration group
*/
reduceSpaces(decl) {
let stop = false
this.prefixes.group(decl).up(() => {
stop = true
return true
})
if (stop) {
return
}
let parts = decl.raw('before').split('\n')
let prevMin = parts[parts.length - 1].length
let diff = false
this.prefixes.group(decl).down(other => {
parts = other.raw('before').split('\n')
let last = parts.length - 1
if (parts[last].length > prevMin) {
if (diff === false) {
diff = parts[last].length - prevMin
}
parts[last] = parts[last].slice(0, -diff)
other.raws.before = parts.join('\n')
}
})
}
/**
* Remove unnecessary pefixes
*/
remove(css, result) {
// At-rules
let resolution = this.prefixes.remove['@resolution']
css.walkAtRules((rule, i) => {
if (this.prefixes.remove[`@${rule.name}`]) {
if (!this.disabled(rule, result)) {
rule.parent.removeChild(i)
}
} else if (
rule.name === 'media' &&
rule.params.includes('-resolution') &&
resolution
) {
resolution.clean(rule)
}
})
// Selectors
for (let checker of this.prefixes.remove.selectors) {
css.walkRules((rule, i) => {
if (checker.check(rule)) {
if (!this.disabled(rule, result)) {
rule.parent.removeChild(i)
}
}
})
}
return css.walkDecls((decl, i) => {
if (this.disabled(decl, result)) return
let rule = decl.parent
let unprefixed = this.prefixes.unprefixed(decl.prop)
// Transition
if (decl.prop === 'transition' || decl.prop === 'transition-property') {
this.prefixes.transition.remove(decl)
}
// Properties
if (
this.prefixes.remove[decl.prop] &&
this.prefixes.remove[decl.prop].remove
) {
let notHack = this.prefixes.group(decl).down(other => {
return this.prefixes.normalize(other.prop) === unprefixed
})
if (unprefixed === 'flex-flow') {
notHack = true
}
if (decl.prop === '-webkit-box-orient') {
let hacks = { 'flex-direction': true, 'flex-flow': true }
if (!decl.parent.some(j => hacks[j.prop])) return
}
if (notHack && !this.withHackValue(decl)) {
if (decl.raw('before').includes('\n')) {
this.reduceSpaces(decl)
}
rule.removeChild(i)
return
}
}
// Values
for (let checker of this.prefixes.values('remove', unprefixed)) {
if (!checker.check) continue
if (!checker.check(decl.value)) continue
unprefixed = checker.unprefixed
let notHack = this.prefixes.group(decl).down(other => {
return other.value.includes(unprefixed)
})
if (notHack) {
rule.removeChild(i)
return
}
}
})
}
/**
* Some rare old values, which is not in standard
*/
withHackValue(decl) {
return decl.prop === '-webkit-background-clip' && decl.value === 'text'
}
}
module.exports = Processor

@@ -11,2 +11,19 @@ let FractionJs = require('fraction.js')

/**
* Remove prefixed queries
*/
clean(rule) {
if (!this.bad) {
this.bad = []
for (let prefix of this.prefixes) {
this.bad.push(this.prefixName(prefix, 'min'))
this.bad.push(this.prefixName(prefix, 'max'))
}
}
rule.params = utils.editList(rule.params, queries => {
return queries.filter(query => this.bad.every(i => !query.includes(i)))
})
}
/**
* Return prefixed query name

@@ -44,19 +61,2 @@ */

/**
* Remove prefixed queries
*/
clean(rule) {
if (!this.bad) {
this.bad = []
for (let prefix of this.prefixes) {
this.bad.push(this.prefixName(prefix, 'min'))
this.bad.push(this.prefixName(prefix, 'max'))
}
}
rule.params = utils.editList(rule.params, queries => {
return queries.filter(query => this.bad.every(i => !query.includes(i)))
})
}
/**
* Add prefixed queries

@@ -63,0 +63,0 @@ */

@@ -15,35 +15,69 @@ let { list } = require('postcss')

/**
* Is rule selectors need to be prefixed
* Clone and add prefixes for at-rule
*/
check(rule) {
if (rule.selector.includes(this.name)) {
return !!rule.selector.match(this.regexp())
add(rule, prefix) {
let prefixeds = this.prefixeds(rule)
if (this.already(rule, prefixeds, prefix)) {
return
}
return false
let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })
rule.parent.insertBefore(rule, cloned)
}
/**
* Return prefixed version of selector
* Is rule already prefixed before
*/
prefixed(prefix) {
return this.name.replace(/^(\W*)/, `$1${prefix}`)
already(rule, prefixeds, prefix) {
let index = rule.parent.index(rule) - 1
while (index >= 0) {
let before = rule.parent.nodes[index]
if (before.type !== 'rule') {
return false
}
let some = false
for (let key in prefixeds[this.name]) {
let prefixed = prefixeds[this.name][key]
if (before.selector === prefixed) {
if (prefix === key) {
return true
} else {
some = true
break
}
}
}
if (!some) {
return false
}
index -= 1
}
return false
}
/**
* Lazy loadRegExp for name
* Is rule selectors need to be prefixed
*/
regexp(prefix) {
if (!this.regexpCache.has(prefix)) {
let name = prefix ? this.prefixed(prefix) : this.name
this.regexpCache.set(
prefix,
new RegExp(`(^|[^:"'=])${utils.escapeRegexp(name)}`, 'gi')
)
check(rule) {
if (rule.selector.includes(this.name)) {
return !!rule.selector.match(this.regexp())
}
return this.regexpCache.get(prefix)
return false
}
/**
* Return function to fast find prefixed selector
*/
old(prefix) {
return new OldSelector(this, prefix)
}
/**
* All possible prefixes

@@ -56,2 +90,9 @@ */

/**
* Return prefixed version of selector
*/
prefixed(prefix) {
return this.name.replace(/^(\W*)/, `$1${prefix}`)
}
/**
* Return all possible selector prefixes

@@ -89,34 +130,14 @@ */

/**
* Is rule already prefixed before
* Lazy loadRegExp for name
*/
already(rule, prefixeds, prefix) {
let index = rule.parent.index(rule) - 1
while (index >= 0) {
let before = rule.parent.nodes[index]
if (before.type !== 'rule') {
return false
}
let some = false
for (let key in prefixeds[this.name]) {
let prefixed = prefixeds[this.name][key]
if (before.selector === prefixed) {
if (prefix === key) {
return true
} else {
some = true
break
}
}
}
if (!some) {
return false
}
index -= 1
regexp(prefix) {
if (!this.regexpCache.has(prefix)) {
let name = prefix ? this.prefixed(prefix) : this.name
this.regexpCache.set(
prefix,
new RegExp(`(^|[^:"'=])${utils.escapeRegexp(name)}`, 'gi')
)
}
return false
return this.regexpCache.get(prefix)
}

@@ -130,25 +151,4 @@

}
/**
* Clone and add prefixes for at-rule
*/
add(rule, prefix) {
let prefixeds = this.prefixeds(rule)
if (this.already(rule, prefixeds, prefix)) {
return
}
let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })
rule.parent.insertBefore(rule, cloned)
}
/**
* Return function to fast find prefixed selector
*/
old(prefix) {
return new OldSelector(this, prefix)
}
}
module.exports = Selector

@@ -30,72 +30,88 @@ let featureQueries = require('caniuse-lite/data/features/css-featurequeries.js')

/**
* Return prefixer only with @supports supported browsers
* Add prefixes
*/
prefixer() {
if (this.prefixerCache) {
return this.prefixerCache
}
add(nodes, all) {
return nodes.map(i => {
if (this.isProp(i)) {
let prefixed = this.prefixed(i[0])
if (prefixed.length > 1) {
return this.convert(prefixed)
}
let filtered = this.all.browsers.selected.filter(i => {
return supported.includes(i)
return i
}
if (typeof i === 'object') {
return this.add(i, all)
}
return i
})
let browsers = new Browsers(
this.all.browsers.data,
filtered,
this.all.options
)
this.prefixerCache = new this.Prefixes(
this.all.data,
browsers,
this.all.options
)
return this.prefixerCache
}
/**
* Parse string into declaration property and value
* Clean brackets with one child
*/
parse(str) {
let parts = str.split(':')
let prop = parts[0]
let value = parts[1]
if (!value) value = ''
return [prop.trim(), value.trim()]
cleanBrackets(nodes) {
return nodes.map(i => {
if (typeof i !== 'object') {
return i
}
if (i.length === 1 && typeof i[0] === 'object') {
return this.cleanBrackets(i[0])
}
return this.cleanBrackets(i)
})
}
/**
* Create virtual rule to process it by prefixer
* Add " or " between properties and convert it to brackets format
*/
virtual(str) {
let [prop, value] = this.parse(str)
let rule = parse('a{}').first
rule.append({ prop, value, raws: { before: '' } })
return rule
convert(progress) {
let result = ['']
for (let i of progress) {
result.push([`${i.prop}: ${i.value}`])
result.push(' or ')
}
result[result.length - 1] = ''
return result
}
/**
* Return array of Declaration with all necessary prefixes
* Check global options
*/
prefixed(str) {
let rule = this.virtual(str)
if (this.disabled(rule.first)) {
return rule.nodes
disabled(node) {
if (!this.all.options.grid) {
if (node.prop === 'display' && node.value.includes('grid')) {
return true
}
if (node.prop.includes('grid') || node.prop === 'justify-items') {
return true
}
}
let result = { warn: () => null }
let prefixer = this.prefixer().add[rule.first.prop]
prefixer && prefixer.process && prefixer.process(rule.first, result)
for (let decl of rule.nodes) {
for (let value of this.prefixer().values('add', rule.first.prop)) {
value.process(decl)
if (this.all.options.flexbox === false) {
if (node.prop === 'display' && node.value.includes('flex')) {
return true
}
Value.save(this.all, decl)
let other = ['order', 'justify-content', 'align-items', 'align-content']
if (node.prop.includes('flex') || other.includes(node.prop)) {
return true
}
}
return rule.nodes
return false
}
/**
* Return true if prefixed property has no unprefixed
*/
isHack(all, unprefixed) {
let check = new RegExp(`(\\(|\\s)${utils.escapeRegexp(unprefixed)}:`)
return !check.test(all)
}
/**
* Return true if brackets node is "not" word

@@ -126,36 +142,98 @@ */

/**
* Return true if prefixed property has no unprefixed
* Compress value functions into a string nodes
*/
isHack(all, unprefixed) {
let check = new RegExp(`(\\(|\\s)${utils.escapeRegexp(unprefixed)}:`)
return !check.test(all)
normalize(nodes) {
if (typeof nodes !== 'object') {
return nodes
}
nodes = nodes.filter(i => i !== '')
if (typeof nodes[0] === 'string') {
let firstNode = nodes[0].trim()
if (
firstNode.includes(':') ||
firstNode === 'selector' ||
firstNode === 'not selector'
) {
return [brackets.stringify(nodes)]
}
}
return nodes.map(i => this.normalize(i))
}
/**
* Return true if we need to remove node
* Parse string into declaration property and value
*/
toRemove(str, all) {
let [prop, value] = this.parse(str)
let unprefixed = this.all.unprefixed(prop)
parse(str) {
let parts = str.split(':')
let prop = parts[0]
let value = parts[1]
if (!value) value = ''
return [prop.trim(), value.trim()]
}
let cleaner = this.all.cleaner()
if (
cleaner.remove[prop] &&
cleaner.remove[prop].remove &&
!this.isHack(all, unprefixed)
) {
return true
/**
* Return array of Declaration with all necessary prefixes
*/
prefixed(str) {
let rule = this.virtual(str)
if (this.disabled(rule.first)) {
return rule.nodes
}
for (let checker of cleaner.values('remove', unprefixed)) {
if (checker.check(value)) {
return true
let result = { warn: () => null }
let prefixer = this.prefixer().add[rule.first.prop]
prefixer && prefixer.process && prefixer.process(rule.first, result)
for (let decl of rule.nodes) {
for (let value of this.prefixer().values('add', rule.first.prop)) {
value.process(decl)
}
Value.save(this.all, decl)
}
return false
return rule.nodes
}
/**
* Return prefixer only with @supports supported browsers
*/
prefixer() {
if (this.prefixerCache) {
return this.prefixerCache
}
let filtered = this.all.browsers.selected.filter(i => {
return supported.includes(i)
})
let browsers = new Browsers(
this.all.browsers.data,
filtered,
this.all.options
)
this.prefixerCache = new this.Prefixes(
this.all.data,
browsers,
this.all.options
)
return this.prefixerCache
}
/**
* Add prefixed declaration
*/
process(rule) {
let ast = brackets.parse(rule.params)
ast = this.normalize(ast)
ast = this.remove(ast, rule.params)
ast = this.add(ast, rule.params)
ast = this.cleanBrackets(ast)
rule.params = brackets.stringify(ast)
}
/**
* Remove all unnecessary prefixes

@@ -190,116 +268,38 @@ */

/**
* Clean brackets with one child
* Return true if we need to remove node
*/
cleanBrackets(nodes) {
return nodes.map(i => {
if (typeof i !== 'object') {
return i
}
toRemove(str, all) {
let [prop, value] = this.parse(str)
let unprefixed = this.all.unprefixed(prop)
if (i.length === 1 && typeof i[0] === 'object') {
return this.cleanBrackets(i[0])
}
let cleaner = this.all.cleaner()
return this.cleanBrackets(i)
})
}
/**
* Add " or " between properties and convert it to brackets format
*/
convert(progress) {
let result = ['']
for (let i of progress) {
result.push([`${i.prop}: ${i.value}`])
result.push(' or ')
if (
cleaner.remove[prop] &&
cleaner.remove[prop].remove &&
!this.isHack(all, unprefixed)
) {
return true
}
result[result.length - 1] = ''
return result
}
/**
* Compress value functions into a string nodes
*/
normalize(nodes) {
if (typeof nodes !== 'object') {
return nodes
}
nodes = nodes.filter(i => i !== '')
if (typeof nodes[0] === 'string') {
let firstNode = nodes[0].trim()
if (
firstNode.includes(':') ||
firstNode === 'selector' ||
firstNode === 'not selector'
) {
return [brackets.stringify(nodes)]
for (let checker of cleaner.values('remove', unprefixed)) {
if (checker.check(value)) {
return true
}
}
return nodes.map(i => this.normalize(i))
}
/**
* Add prefixes
*/
add(nodes, all) {
return nodes.map(i => {
if (this.isProp(i)) {
let prefixed = this.prefixed(i[0])
if (prefixed.length > 1) {
return this.convert(prefixed)
}
return i
}
if (typeof i === 'object') {
return this.add(i, all)
}
return i
})
return false
}
/**
* Add prefixed declaration
* Create virtual rule to process it by prefixer
*/
process(rule) {
let ast = brackets.parse(rule.params)
ast = this.normalize(ast)
ast = this.remove(ast, rule.params)
ast = this.add(ast, rule.params)
ast = this.cleanBrackets(ast)
rule.params = brackets.stringify(ast)
virtual(str) {
let [prop, value] = this.parse(str)
let rule = parse('a{}').first
rule.append({ prop, raws: { before: '' }, value })
return rule
}
/**
* Check global options
*/
disabled(node) {
if (!this.all.options.grid) {
if (node.prop === 'display' && node.value.includes('grid')) {
return true
}
if (node.prop.includes('grid') || node.prop === 'justify-items') {
return true
}
}
if (this.all.options.flexbox === false) {
if (node.prop === 'display' && node.value.includes('flex')) {
return true
}
let other = ['order', 'justify-content', 'align-items', 'align-content']
if (node.prop.includes('flex') || other.includes(node.prop)) {
return true
}
}
return false
}
}
module.exports = Supports

@@ -83,17 +83,2 @@ let { list } = require('postcss')

/**
* Find property name
*/
findProp(param) {
let prop = param[0].value
if (/^\d/.test(prop)) {
for (let [i, token] of param.entries()) {
if (i !== 0 && token.type === 'word') {
return token.value
}
}
}
return prop
}
/**
* Does we already have this declaration

@@ -106,11 +91,2 @@ */

/**
* Add declaration if it is not exist
*/
cloneBefore(decl, prop, value) {
if (!this.already(decl, prop, value)) {
decl.cloneBefore({ prop, value })
}
}
/**
* Show transition-property warning

@@ -161,75 +137,26 @@ */

/**
* Process transition and remove all unnecessary properties
* Remove all non-webkit prefixes and unprefixed params if we have prefixed
*/
remove(decl) {
let params = this.parse(decl.value)
params = params.filter(i => {
let prop = this.prefixes.remove[this.findProp(i)]
return !prop || !prop.remove
})
let value = this.stringify(params)
cleanFromUnprefixed(params, prefix) {
let remove = params
.map(i => this.findProp(i))
.filter(i => i.slice(0, prefix.length) === prefix)
.map(i => this.prefixes.unprefixed(i))
if (decl.value === value) {
return
}
if (params.length === 0) {
decl.remove()
return
}
let double = decl.parent.some(i => {
return i.prop === decl.prop && i.value === value
})
let smaller = decl.parent.some(i => {
return i !== decl && i.prop === decl.prop && i.value.length > value.length
})
if (double || smaller) {
decl.remove()
return
}
decl.value = value
}
/**
* Parse properties list to array
*/
parse(value) {
let ast = parser(value)
let result = []
let param = []
for (let node of ast.nodes) {
param.push(node)
if (node.type === 'div' && node.value === ',') {
for (let param of params) {
let prop = this.findProp(param)
let p = vendor.prefix(prop)
if (!remove.includes(prop) && (p === prefix || p === '')) {
result.push(param)
param = []
}
}
result.push(param)
return result.filter(i => i.length > 0)
return result
}
/**
* Return properties string from array
*/
stringify(params) {
if (params.length === 0) {
return ''
}
let nodes = []
for (let param of params) {
if (param[param.length - 1].type !== 'div') {
param.push(this.div(params))
}
nodes = nodes.concat(param)
}
if (nodes[0].type === 'div') {
nodes = nodes.slice(1)
}
if (nodes[nodes.length - 1].type === 'div') {
nodes = nodes.slice(0, +-2 + 1 || undefined)
}
return parser.stringify({ nodes })
cleanOtherPrefixes(params, prefix) {
return params.filter(param => {
let current = vendor.prefix(this.findProp(param))
return current === '' || current === prefix
})
}

@@ -255,2 +182,28 @@

/**
* Add declaration if it is not exist
*/
cloneBefore(decl, prop, value) {
if (!this.already(decl, prop, value)) {
decl.cloneBefore({ prop, value })
}
}
/**
* Check property for disabled by option
*/
disabled(prop, prefix) {
let other = ['order', 'justify-content', 'align-self', 'align-content']
if (prop.includes('flex') || other.includes(prop)) {
if (this.prefixes.options.flexbox === false) {
return true
}
if (this.prefixes.options.flexbox === 'no-2009') {
return prefix.includes('2009')
}
}
return undefined
}
/**
* Find or create separator

@@ -266,47 +219,71 @@ */

}
return { type: 'div', value: ',', after: ' ' }
return { after: ' ', type: 'div', value: ',' }
}
cleanOtherPrefixes(params, prefix) {
return params.filter(param => {
let current = vendor.prefix(this.findProp(param))
return current === '' || current === prefix
})
/**
* Find property name
*/
findProp(param) {
let prop = param[0].value
if (/^\d/.test(prop)) {
for (let [i, token] of param.entries()) {
if (i !== 0 && token.type === 'word') {
return token.value
}
}
}
return prop
}
/**
* Remove all non-webkit prefixes and unprefixed params if we have prefixed
* Parse properties list to array
*/
cleanFromUnprefixed(params, prefix) {
let remove = params
.map(i => this.findProp(i))
.filter(i => i.slice(0, prefix.length) === prefix)
.map(i => this.prefixes.unprefixed(i))
parse(value) {
let ast = parser(value)
let result = []
for (let param of params) {
let prop = this.findProp(param)
let p = vendor.prefix(prop)
if (!remove.includes(prop) && (p === prefix || p === '')) {
let param = []
for (let node of ast.nodes) {
param.push(node)
if (node.type === 'div' && node.value === ',') {
result.push(param)
param = []
}
}
return result
result.push(param)
return result.filter(i => i.length > 0)
}
/**
* Check property for disabled by option
* Process transition and remove all unnecessary properties
*/
disabled(prop, prefix) {
let other = ['order', 'justify-content', 'align-self', 'align-content']
if (prop.includes('flex') || other.includes(prop)) {
if (this.prefixes.options.flexbox === false) {
return true
}
remove(decl) {
let params = this.parse(decl.value)
params = params.filter(i => {
let prop = this.prefixes.remove[this.findProp(i)]
return !prop || !prop.remove
})
let value = this.stringify(params)
if (this.prefixes.options.flexbox === 'no-2009') {
return prefix.includes('2009')
}
if (decl.value === value) {
return
}
return undefined
if (params.length === 0) {
decl.remove()
return
}
let double = decl.parent.some(i => {
return i.prop === decl.prop && i.value === value
})
let smaller = decl.parent.some(i => {
return i !== decl && i.prop === decl.prop && i.value.length > value.length
})
if (double || smaller) {
decl.remove()
return
}
decl.value = value
}

@@ -332,4 +309,27 @@

}
/**
* Return properties string from array
*/
stringify(params) {
if (params.length === 0) {
return ''
}
let nodes = []
for (let param of params) {
if (param[param.length - 1].type !== 'div') {
param.push(this.div(params))
}
nodes = nodes.concat(param)
}
if (nodes[0].type === 'div') {
nodes = nodes.slice(1)
}
if (nodes[nodes.length - 1].type === 'div') {
nodes = nodes.slice(0, +-2 + 1 || undefined)
}
return parser.stringify({ nodes })
}
}
module.exports = Transition

@@ -62,2 +62,21 @@ let Prefixer = require('./prefixer')

/**
* Save values with next prefixed token
*/
add(decl, prefix) {
if (!decl._autoprefixerValues) {
decl._autoprefixerValues = {}
}
let value = decl._autoprefixerValues[prefix] || this.value(decl)
let before
do {
before = value
value = this.replace(value, prefix)
if (value === false) return
} while (value !== before)
decl._autoprefixerValues[prefix] = value
}
/**
* Is declaration need to be prefixed

@@ -75,2 +94,9 @@ */

/**
* Return function to fast find prefixed value
*/
old(prefix) {
return new OldValue(this.name, prefix + this.name)
}
/**
* Lazy regexp loading

@@ -99,30 +125,4 @@ */

}
/**
* Save values with next prefixed token
*/
add(decl, prefix) {
if (!decl._autoprefixerValues) {
decl._autoprefixerValues = {}
}
let value = decl._autoprefixerValues[prefix] || this.value(decl)
let before
do {
before = value
value = this.replace(value, prefix)
if (value === false) return
} while (value !== before)
decl._autoprefixerValues[prefix] = value
}
/**
* Return function to fast find prefixed value
*/
old(prefix) {
return new OldValue(this.name, prefix + this.name)
}
}
module.exports = Value
{
"name": "autoprefixer",
"version": "10.4.14",
"version": "10.4.15",
"description": "Parse CSS and add vendor prefixes to CSS rules using values from the Can I Use website",

@@ -26,2 +26,6 @@ "engines": {

"url": "https://tidelift.com/funding/github/npm/autoprefixer"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}

@@ -39,4 +43,4 @@ ],

"dependencies": {
"browserslist": "^4.21.5",
"caniuse-lite": "^1.0.30001464",
"browserslist": "^4.21.10",
"caniuse-lite": "^1.0.30001520",
"fraction.js": "^4.2.0",

@@ -43,0 +47,0 @@ "normalize-range": "^0.1.2",

# Autoprefixer [![Cult Of Martians][cult-img]][cult]
<img align="right" width="94" height="71"
src="http://postcss.github.io/autoprefixer/logo.svg"
src="https://postcss.github.io/autoprefixer/logo.svg"
title="Autoprefixer logo by Anton Lovchikov">

@@ -60,5 +60,5 @@

[Can I Use]: https://caniuse.com/
[cult-img]: http://cultofmartians.com/assets/badges/badge.svg
[cult-img]: https://cultofmartians.com/assets/badges/badge.svg
[PostCSS]: https://github.com/postcss/postcss
[cult]: http://cultofmartians.com/tasks/autoprefixer-grid.html
[cult]: https://cultofmartians.com/tasks/autoprefixer-grid.html

@@ -65,0 +65,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc