Update dependencies and code style

This commit is contained in:
Andrey Sitnik
2023-07-08 13:45:22 +02:00
parent 925c4b3b43
commit d4fd75400b
50 changed files with 2159 additions and 2039 deletions
+179 -179
View File
@@ -68,9 +68,9 @@ f(prefixBorderRadius, browsers =>
'border-bottom-left-radius'
],
{
mistakes: ['-khtml-', '-ms-', '-o-'],
browsers,
feature: 'border-radius',
browsers
mistakes: ['-khtml-', '-ms-', '-o-']
}
)
)
@@ -80,9 +80,9 @@ let prefixBoxshadow = require('caniuse-lite/data/features/css-boxshadow')
f(prefixBoxshadow, browsers =>
prefix(['box-shadow'], {
mistakes: ['-khtml-'],
browsers,
feature: 'css-boxshadow',
browsers
mistakes: ['-khtml-']
})
)
@@ -104,9 +104,9 @@ f(prefixAnimation, browsers =>
'@keyframes'
],
{
mistakes: ['-khtml-', '-ms-'],
browsers,
feature: 'css-animation',
browsers
mistakes: ['-khtml-', '-ms-']
}
)
)
@@ -124,9 +124,9 @@ f(prefixTransition, browsers =>
'transition-timing-function'
],
{
mistakes: ['-khtml-', '-ms-'],
browsers,
feature: 'css-transitions'
feature: 'css-transitions',
mistakes: ['-khtml-', '-ms-']
}
)
)
@@ -136,8 +136,8 @@ let prefixTransform2d = require('caniuse-lite/data/features/transforms2d')
f(prefixTransform2d, browsers =>
prefix(['transform', 'transform-origin'], {
feature: 'transforms2d',
browsers
browsers,
feature: 'transforms2d'
})
)
@@ -146,21 +146,21 @@ let prefixTransforms3d = require('caniuse-lite/data/features/transforms3d')
f(prefixTransforms3d, browsers => {
prefix(['perspective', 'perspective-origin'], {
feature: 'transforms3d',
browsers
})
return prefix(['transform-style'], {
mistakes: ['-ms-', '-o-'],
browsers,
feature: 'transforms3d'
})
return prefix(['transform-style'], {
browsers,
feature: 'transforms3d',
mistakes: ['-ms-', '-o-']
})
})
f(prefixTransforms3d, { match: /y\sx|y\s#2/ }, browsers =>
prefix(['backface-visibility'], {
mistakes: ['-ms-', '-o-'],
browsers,
feature: 'transforms3d',
browsers
mistakes: ['-ms-', '-o-']
})
)
@@ -176,6 +176,9 @@ f(prefixGradients, { match: /y\sx/ }, browsers =>
'repeating-radial-gradient'
],
{
browsers,
feature: 'css-gradients',
mistakes: ['-ms-'],
props: [
'background',
'background-image',
@@ -185,10 +188,7 @@ f(prefixGradients, { match: /y\sx/ }, browsers =>
'list-style-image',
'content',
'mask-image'
],
mistakes: ['-ms-'],
feature: 'css-gradients',
browsers
]
}
)
)
@@ -209,8 +209,8 @@ f(prefixGradients, { match: /a\sx/ }, browsers => {
'repeating-radial-gradient'
],
{
feature: 'css-gradients',
browsers
browsers,
feature: 'css-gradients'
}
)
})
@@ -220,8 +220,8 @@ let prefixBoxsizing = require('caniuse-lite/data/features/css3-boxsizing')
f(prefixBoxsizing, browsers =>
prefix(['box-sizing'], {
feature: 'css3-boxsizing',
browsers
browsers,
feature: 'css3-boxsizing'
})
)
@@ -230,8 +230,8 @@ let prefixFilters = require('caniuse-lite/data/features/css-filters')
f(prefixFilters, browsers =>
prefix(['filter'], {
feature: 'css-filters',
browsers
browsers,
feature: 'css-filters'
})
)
@@ -240,6 +240,8 @@ let prefixFilterFunction = require('caniuse-lite/data/features/css-filter-functi
f(prefixFilterFunction, browsers =>
prefix(['filter-function'], {
browsers,
feature: 'css-filter-function',
props: [
'background',
'background-image',
@@ -249,9 +251,7 @@ f(prefixFilterFunction, browsers =>
'list-style-image',
'content',
'mask-image'
],
feature: 'css-filter-function',
browsers
]
})
)
@@ -260,8 +260,8 @@ let prefixBackdrop = require('caniuse-lite/data/features/css-backdrop-filter')
f(prefixBackdrop, { match: /y\sx|y\s#2/ }, browsers =>
prefix(['backdrop-filter'], {
feature: 'css-backdrop-filter',
browsers
browsers,
feature: 'css-backdrop-filter'
})
)
@@ -270,6 +270,8 @@ let prefixElementFunction = require('caniuse-lite/data/features/css-element-func
f(prefixElementFunction, browsers =>
prefix(['element'], {
browsers,
feature: 'css-element-function',
props: [
'background',
'background-image',
@@ -279,9 +281,7 @@ f(prefixElementFunction, browsers =>
'list-style-image',
'content',
'mask-image'
],
feature: 'css-element-function',
browsers
]
})
)
@@ -303,15 +303,15 @@ f(prefixMulticolumns, browsers => {
'column-fill'
],
{
feature: 'multicolumn',
browsers
browsers,
feature: 'multicolumn'
}
)
let noff = browsers.filter(i => !/firefox/.test(i))
prefix(['break-before', 'break-after', 'break-inside'], {
feature: 'multicolumn',
browsers: noff
browsers: noff,
feature: 'multicolumn'
})
})
@@ -320,9 +320,9 @@ let prefixUserSelect = require('caniuse-lite/data/features/user-select-none')
f(prefixUserSelect, browsers =>
prefix(['user-select'], {
mistakes: ['-khtml-'],
browsers,
feature: 'user-select-none',
browsers
mistakes: ['-khtml-']
})
)
@@ -338,13 +338,13 @@ f(prefixFlexbox, { match: /a\sx/ }, browsers => {
}
})
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'
})
prefix(
[
@@ -358,20 +358,20 @@ f(prefixFlexbox, { match: /a\sx/ }, browsers => {
'align-content'
],
{
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
}
)
})
f(prefixFlexbox, { match: /y\sx/ }, browsers => {
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'
})
add(
[
@@ -385,8 +385,8 @@ f(prefixFlexbox, { match: /y\sx/ }, browsers => {
'align-content'
],
{
feature: 'flexbox',
browsers
browsers,
feature: 'flexbox'
}
)
})
@@ -396,9 +396,9 @@ let prefixCalc = require('caniuse-lite/data/features/calc')
f(prefixCalc, browsers =>
prefix(['calc'], {
props: ['*'],
browsers,
feature: 'calc',
browsers
props: ['*']
})
)
@@ -407,8 +407,8 @@ let prefixBackgroundOptions = require('caniuse-lite/data/features/background-img
f(prefixBackgroundOptions, browsers =>
prefix(['background-origin', 'background-size'], {
feature: 'background-img-opts',
browsers
browsers,
feature: 'background-img-opts'
})
)
@@ -417,8 +417,8 @@ let prefixBackgroundClipText = require('caniuse-lite/data/features/background-cl
f(prefixBackgroundClipText, browsers =>
prefix(['background-clip'], {
feature: 'background-clip-text',
browsers
browsers,
feature: 'background-clip-text'
})
)
@@ -433,8 +433,8 @@ f(prefixFontFeature, browsers =>
'font-language-override'
],
{
feature: 'font-feature',
browsers
browsers,
feature: 'font-feature'
}
)
)
@@ -444,8 +444,8 @@ let prefixFontKerning = require('caniuse-lite/data/features/font-kerning')
f(prefixFontKerning, browsers =>
prefix(['font-kerning'], {
feature: 'font-kerning',
browsers
browsers,
feature: 'font-kerning'
})
)
@@ -454,8 +454,8 @@ let prefixBorderImage = require('caniuse-lite/data/features/border-image')
f(prefixBorderImage, browsers =>
prefix(['border-image'], {
feature: 'border-image',
browsers
browsers,
feature: 'border-image'
})
)
@@ -464,9 +464,9 @@ let prefixSelection = require('caniuse-lite/data/features/css-selection')
f(prefixSelection, browsers =>
prefix(['::selection'], {
selector: true,
browsers,
feature: 'css-selection',
browsers
selector: true
})
)
@@ -475,9 +475,9 @@ let prefixPlaceholder = require('caniuse-lite/data/features/css-placeholder')
f(prefixPlaceholder, browsers => {
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
})
})
@@ -486,9 +486,9 @@ let prefixPlaceholderShown = require('caniuse-lite/data/features/css-placeholder
f(prefixPlaceholderShown, browsers => {
prefix([':placeholder-shown'], {
selector: true,
browsers,
feature: 'css-placeholder-shown',
browsers
selector: true
})
})
@@ -497,8 +497,8 @@ let prefixHyphens = require('caniuse-lite/data/features/css-hyphens')
f(prefixHyphens, browsers =>
prefix(['hyphens'], {
feature: 'css-hyphens',
browsers
browsers,
feature: 'css-hyphens'
})
)
@@ -507,17 +507,17 @@ let prefixFullscreen = require('caniuse-lite/data/features/fullscreen')
f(prefixFullscreen, browsers =>
prefix([':fullscreen'], {
selector: true,
browsers,
feature: 'fullscreen',
browsers
selector: true
})
)
f(prefixFullscreen, { match: /x(\s#2|$)/ }, browsers =>
prefix(['::backdrop'], {
selector: true,
browsers,
feature: 'fullscreen',
browsers
selector: true
})
)
@@ -526,9 +526,9 @@ let prefixFileSelectorButton = require('caniuse-lite/data/features/css-file-sele
f(prefixFileSelectorButton, browsers =>
prefix(['::file-selector-button'], {
selector: true,
browsers,
feature: 'file-selector-button',
browsers
selector: true
})
)
@@ -537,9 +537,9 @@ let prefixAutofill = require('caniuse-lite/data/features/css-autofill')
f(prefixAutofill, browsers =>
prefix([':autofill'], {
selector: true,
browsers,
feature: 'css-autofill',
browsers
selector: true
})
)
@@ -548,8 +548,8 @@ let prefixTabsize = require('caniuse-lite/data/features/css3-tabsize')
f(prefixTabsize, browsers =>
prefix(['tab-size'], {
feature: 'css3-tabsize',
browsers
browsers,
feature: 'css3-tabsize'
})
)
@@ -579,25 +579,25 @@ let sizeProps = [
f(prefixIntrinsic, browsers =>
prefix(['max-content', 'min-content'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})
)
f(prefixIntrinsic, { match: /x|\s#4/ }, browsers =>
prefix(['fill', 'fill-available'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})
)
f(prefixIntrinsic, { match: /x|\s#5/ }, browsers =>
prefix(['fit-content'], {
props: sizeProps,
browsers,
feature: 'intrinsic-width',
browsers
props: sizeProps
})
)
@@ -607,9 +607,9 @@ let prefixStretch = require('caniuse-lite/data/features/css-width-stretch')
f(prefixStretch, browsers =>
prefix(['stretch'], {
props: sizeProps,
browsers,
feature: 'css-width-stretch',
browsers
props: sizeProps
})
)
@@ -618,9 +618,9 @@ let prefixCursorsNewer = require('caniuse-lite/data/features/css3-cursors-newer'
f(prefixCursorsNewer, browsers =>
prefix(['zoom-in', 'zoom-out'], {
props: ['cursor'],
browsers,
feature: 'css3-cursors-newer',
browsers
props: ['cursor']
})
)
@@ -629,9 +629,9 @@ let prefixCursorsGrab = require('caniuse-lite/data/features/css3-cursors-grab')
f(prefixCursorsGrab, browsers =>
prefix(['grab', 'grabbing'], {
props: ['cursor'],
browsers,
feature: 'css3-cursors-grab',
browsers
props: ['cursor']
})
)
@@ -640,9 +640,9 @@ let prefixSticky = require('caniuse-lite/data/features/css-sticky')
f(prefixSticky, browsers =>
prefix(['sticky'], {
props: ['position'],
browsers,
feature: 'css-sticky',
browsers
props: ['position']
})
)
@@ -651,8 +651,8 @@ let prefixPointer = require('caniuse-lite/data/features/pointer')
f(prefixPointer, browsers =>
prefix(['touch-action'], {
feature: 'pointer',
browsers
browsers,
feature: 'pointer'
})
)
@@ -661,8 +661,8 @@ let prefixDecoration = require('caniuse-lite/data/features/text-decoration')
f(prefixDecoration, { match: /x.*#[235]/ }, browsers =>
prefix(['text-decoration-skip', 'text-decoration-skip-ink'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})
)
@@ -670,8 +670,8 @@ let prefixDecorationShorthand = require('caniuse-lite/data/features/mdn-text-dec
f(prefixDecorationShorthand, browsers =>
prefix(['text-decoration'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})
)
@@ -679,8 +679,8 @@ let prefixDecorationColor = require('caniuse-lite/data/features/mdn-text-decorat
f(prefixDecorationColor, browsers =>
prefix(['text-decoration-color'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})
)
@@ -688,8 +688,8 @@ let prefixDecorationLine = require('caniuse-lite/data/features/mdn-text-decorati
f(prefixDecorationLine, browsers =>
prefix(['text-decoration-line'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})
)
@@ -697,8 +697,8 @@ let prefixDecorationStyle = require('caniuse-lite/data/features/mdn-text-decorat
f(prefixDecorationStyle, browsers =>
prefix(['text-decoration-style'], {
feature: 'text-decoration',
browsers
browsers,
feature: 'text-decoration'
})
)
@@ -707,8 +707,8 @@ let prefixTextSizeAdjust = require('caniuse-lite/data/features/text-size-adjust'
f(prefixTextSizeAdjust, browsers =>
prefix(['text-size-adjust'], {
feature: 'text-size-adjust',
browsers
browsers,
feature: 'text-size-adjust'
})
)
@@ -727,8 +727,8 @@ f(prefixCssMasks, browsers => {
'mask-border-source'
],
{
feature: 'css-masks',
browsers
browsers,
feature: 'css-masks'
}
)
prefix(
@@ -742,8 +742,8 @@ f(prefixCssMasks, browsers => {
'mask-border-slice'
],
{
feature: 'css-masks',
browsers
browsers,
feature: 'css-masks'
}
)
})
@@ -753,8 +753,8 @@ let prefixClipPath = require('caniuse-lite/data/features/css-clip-path')
f(prefixClipPath, browsers =>
prefix(['clip-path'], {
feature: 'css-clip-path',
browsers
browsers,
feature: 'css-clip-path'
})
)
@@ -763,8 +763,8 @@ let prefixBoxdecoration = require('caniuse-lite/data/features/css-boxdecorationb
f(prefixBoxdecoration, browsers =>
prefix(['box-decoration-break'], {
feature: 'css-boxdecorationbreak',
browsers
browsers,
feature: 'css-boxdecorationbreak'
})
)
@@ -773,8 +773,8 @@ let prefixObjectFit = require('caniuse-lite/data/features/object-fit')
f(prefixObjectFit, browsers =>
prefix(['object-fit', 'object-position'], {
feature: 'object-fit',
browsers
browsers,
feature: 'object-fit'
})
)
@@ -783,8 +783,8 @@ let prefixShapes = require('caniuse-lite/data/features/css-shapes')
f(prefixShapes, browsers =>
prefix(['shape-margin', 'shape-outside', 'shape-image-threshold'], {
feature: 'css-shapes',
browsers
browsers,
feature: 'css-shapes'
})
)
@@ -793,8 +793,8 @@ let prefixTextOverflow = require('caniuse-lite/data/features/text-overflow')
f(prefixTextOverflow, browsers =>
prefix(['text-overflow'], {
feature: 'text-overflow',
browsers
browsers,
feature: 'text-overflow'
})
)
@@ -803,8 +803,8 @@ let prefixDeviceadaptation = require('caniuse-lite/data/features/css-deviceadapt
f(prefixDeviceadaptation, browsers =>
prefix(['@viewport'], {
feature: 'css-deviceadaptation',
browsers
browsers,
feature: 'css-deviceadaptation'
})
)
@@ -813,8 +813,8 @@ let prefixResolut = require('caniuse-lite/data/features/css-media-resolution')
f(prefixResolut, { match: /( x($| )|a #2)/ }, browsers =>
prefix(['@resolution'], {
feature: 'css-media-resolution',
browsers
browsers,
feature: 'css-media-resolution'
})
)
@@ -823,8 +823,8 @@ let prefixTextAlignLast = require('caniuse-lite/data/features/css-text-align-las
f(prefixTextAlignLast, browsers =>
prefix(['text-align-last'], {
feature: 'css-text-align-last',
browsers
browsers,
feature: 'css-text-align-last'
})
)
@@ -833,16 +833,16 @@ let prefixCrispedges = require('caniuse-lite/data/features/css-crisp-edges')
f(prefixCrispedges, { match: /y x|a x #1/ }, browsers =>
prefix(['pixelated'], {
props: ['image-rendering'],
browsers,
feature: 'css-crisp-edges',
browsers
props: ['image-rendering']
})
)
f(prefixCrispedges, { match: /a x #2/ }, browsers =>
prefix(['image-rendering'], {
feature: 'css-crisp-edges',
browsers
browsers,
feature: 'css-crisp-edges'
})
)
@@ -860,8 +860,8 @@ f(prefixLogicalProps, browsers =>
'padding-inline-end'
],
{
feature: 'css-logical-props',
browsers
browsers,
feature: 'css-logical-props'
}
)
)
@@ -877,8 +877,8 @@ f(prefixLogicalProps, { match: /x\s#2/ }, browsers =>
'padding-block-end'
],
{
feature: 'css-logical-props',
browsers
browsers,
feature: 'css-logical-props'
}
)
)
@@ -888,8 +888,8 @@ let prefixAppearance = require('caniuse-lite/data/features/css-appearance')
f(prefixAppearance, { match: /#2|x/ }, browsers =>
prefix(['appearance'], {
feature: 'css-appearance',
browsers
browsers,
feature: 'css-appearance'
})
)
@@ -906,8 +906,8 @@ f(prefixSnappoints, browsers =>
'scroll-snap-points-y'
],
{
feature: 'css-snappoints',
browsers
browsers,
feature: 'css-snappoints'
}
)
)
@@ -917,8 +917,8 @@ let prefixRegions = require('caniuse-lite/data/features/css-regions')
f(prefixRegions, browsers =>
prefix(['flow-into', 'flow-from', 'region-fragment'], {
feature: 'css-regions',
browsers
browsers,
feature: 'css-regions'
})
)
@@ -927,6 +927,8 @@ let prefixImageSet = require('caniuse-lite/data/features/css-image-set')
f(prefixImageSet, browsers =>
prefix(['image-set'], {
browsers,
feature: 'css-image-set',
props: [
'background',
'background-image',
@@ -937,9 +939,7 @@ f(prefixImageSet, browsers =>
'list-style',
'list-style-image',
'content'
],
feature: 'css-image-set',
browsers
]
})
)
@@ -948,8 +948,8 @@ let prefixWritingMode = require('caniuse-lite/data/features/css-writing-mode')
f(prefixWritingMode, { match: /a|x/ }, browsers =>
prefix(['writing-mode'], {
feature: 'css-writing-mode',
browsers
browsers,
feature: 'css-writing-mode'
})
)
@@ -958,6 +958,8 @@ let prefixCrossFade = require('caniuse-lite/data/features/css-cross-fade')
f(prefixCrossFade, browsers =>
prefix(['cross-fade'], {
browsers,
feature: 'css-cross-fade',
props: [
'background',
'background-image',
@@ -967,9 +969,7 @@ f(prefixCrossFade, browsers =>
'list-style-image',
'content',
'mask-image'
],
feature: 'css-cross-fade',
browsers
]
})
)
@@ -978,9 +978,9 @@ let prefixReadOnly = require('caniuse-lite/data/features/css-read-only-write')
f(prefixReadOnly, browsers =>
prefix([':read-only', ':read-write'], {
selector: true,
browsers,
feature: 'css-read-only-write',
browsers
selector: true
})
)
@@ -996,8 +996,8 @@ f(prefixTextEmphasis, browsers =>
'text-emphasis-color'
],
{
feature: 'text-emphasis',
browsers
browsers,
feature: 'text-emphasis'
}
)
)
@@ -1007,9 +1007,9 @@ let prefixGrid = require('caniuse-lite/data/features/css-grid')
f(prefixGrid, browsers => {
prefix(['display-grid', 'inline-grid'], {
props: ['display'],
browsers,
feature: 'css-grid',
browsers
props: ['display']
})
prefix(
[
@@ -1027,16 +1027,16 @@ f(prefixGrid, browsers => {
'place-self'
],
{
feature: 'css-grid',
browsers
browsers,
feature: 'css-grid'
}
)
})
f(prefixGrid, { match: /a x/ }, browsers =>
prefix(['grid-column-align', 'grid-row-align'], {
feature: 'css-grid',
browsers
browsers,
feature: 'css-grid'
})
)
@@ -1045,8 +1045,8 @@ let prefixTextSpacing = require('caniuse-lite/data/features/css-text-spacing')
f(prefixTextSpacing, browsers =>
prefix(['text-spacing'], {
feature: 'css-text-spacing',
browsers
browsers,
feature: 'css-text-spacing'
})
)
@@ -1055,9 +1055,9 @@ let prefixAnyLink = require('caniuse-lite/data/features/css-any-link')
f(prefixAnyLink, browsers =>
prefix([':any-link'], {
selector: true,
browsers,
feature: 'css-any-link',
browsers
selector: true
})
)
@@ -1067,9 +1067,9 @@ let bidiIsolate = require('caniuse-lite/data/features/mdn-css-unicode-bidi-isola
f(bidiIsolate, browsers =>
prefix(['isolate'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})
)
@@ -1077,9 +1077,9 @@ let bidiPlaintext = require('caniuse-lite/data/features/mdn-css-unicode-bidi-pla
f(bidiPlaintext, browsers =>
prefix(['plaintext'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})
)
@@ -1087,9 +1087,9 @@ let bidiOverride = require('caniuse-lite/data/features/mdn-css-unicode-bidi-isol
f(bidiOverride, { match: /y x/ }, browsers =>
prefix(['isolate-override'], {
props: ['unicode-bidi'],
browsers,
feature: 'css-unicode-bidi',
browsers
props: ['unicode-bidi']
})
)
@@ -1098,8 +1098,8 @@ let prefixOverscroll = require('caniuse-lite/data/features/css-overscroll-behavi
f(prefixOverscroll, { match: /a #1/ }, browsers =>
prefix(['overscroll-behavior'], {
feature: 'css-overscroll-behavior',
browsers
browsers,
feature: 'css-overscroll-behavior'
})
)
@@ -1108,8 +1108,8 @@ let prefixTextOrientation = require('caniuse-lite/data/features/css-text-orienta
f(prefixTextOrientation, browsers =>
prefix(['text-orientation'], {
feature: 'css-text-orientation',
browsers
browsers,
feature: 'css-text-orientation'
})
)
@@ -1118,7 +1118,7 @@ let prefixPrintAdjust = require('caniuse-lite/data/features/css-print-color-adju
f(prefixPrintAdjust, browsers =>
prefix(['print-color-adjust', 'color-adjust'], {
feature: 'css-print-color-adjust',
browsers
browsers,
feature: 'css-print-color-adjust'
})
)
+15 -15
View File
@@ -96,9 +96,9 @@ function plugin(...reqs) {
}
let brwlstOpts = {
env: options.env,
ignoreUnknownVersions: options.ignoreUnknownVersions,
stats: options.stats,
env: options.env
stats: options.stats
}
function loadPrefixes(opts) {
@@ -114,12 +114,21 @@ function plugin(...reqs) {
}
return {
postcssPlugin: 'autoprefixer',
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
})
return {
@@ -133,16 +142,7 @@ function plugin(...reqs) {
}
}
}
},
info(opts) {
opts = opts || {}
opts.from = opts.from || process.cwd()
return getInfo(loadPrefixes(opts))
},
options,
browsers: reqs
}
}
}
+12 -12
View File
@@ -4,6 +4,13 @@ let { agents } = require('caniuse-lite/dist/unpacker/agents')
let utils = require('./utils')
class Browsers {
constructor(data, requirements, options, browserslistOpts) {
this.data = data
this.options = options || {}
this.browserslistOpts = browserslistOpts || {}
this.selected = this.parse(requirements)
}
/**
* Return all prefixes for default browser data
*/
@@ -35,11 +42,11 @@ class Browsers {
return this.prefixesRegexp.test(value)
}
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)
}
/**
@@ -67,13 +74,6 @@ class Browsers {
}
return `-${prefix}-`
}
/**
* Is browser is selected by requirements
*/
isSelected(browser) {
return this.selected.includes(browser)
}
}
module.exports = Browsers
+97 -97
View File
@@ -4,78 +4,17 @@ let utils = require('./utils')
class Declaration extends Prefixer {
/**
* Always true, because we already get prefixer by property name
* Clone and add prefixes for declaration
*/
check(/* decl */) {
return true
}
/**
* Return prefixed version of property
*/
prefixed(prop, prefix) {
return prefix + prop
}
/**
* Return unprefixed version of property
*/
normalize(prop) {
return prop
}
/**
* Check `value`, that it contain other prefixes, rather than `prefix`
*/
otherPrefixes(value, prefix) {
for (let other of Browsers.prefixes()) {
if (other === prefix) {
continue
}
if (value.includes(other)) {
return value.replace(/var\([^)]+\)/, '').includes(other)
}
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 false
}
/**
* Set prefix to declaration
*/
set(decl, prefix) {
decl.prop = this.prefixed(decl.prop, prefix)
return decl
}
/**
* Should we use visual cascade for prefixes
*/
needCascade(decl) {
if (!decl._autoprefixerCascade) {
decl._autoprefixerCascade =
this.all.options.cascade !== false && decl.raw('before').includes('\n')
}
return decl._autoprefixerCascade
}
/**
* Return maximum length of possible prefixed property
*/
maxPrefixed(prefixes, decl) {
if (decl._autoprefixerMax) {
return decl._autoprefixerMax
}
let max = 0
for (let prefix of prefixes) {
prefix = utils.removeNote(prefix)
if (prefix.length > max) {
max = prefix.length
}
}
decl._autoprefixerMax = max
return decl._autoprefixerMax
return this.insert(decl, prefix, prefixes, result)
}
/**
@@ -94,22 +33,10 @@ class Declaration extends Prefixer {
}
/**
* Remove visual cascade
* Always true, because we already get prefixer by property name
*/
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')
check(/* decl */) {
return true
}
/**
@@ -144,17 +71,70 @@ class Declaration extends Prefixer {
}
/**
* Clone and add prefixes for declaration
* Return maximum length of possible prefixed 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
maxPrefixed(prefixes, decl) {
if (decl._autoprefixerMax) {
return decl._autoprefixerMax
}
return this.insert(decl, prefix, prefixes, result)
let max = 0
for (let prefix of prefixes) {
prefix = utils.removeNote(prefix)
if (prefix.length > max) {
max = prefix.length
}
}
decl._autoprefixerMax = max
return decl._autoprefixerMax
}
/**
* Should we use visual cascade for prefixes
*/
needCascade(decl) {
if (!decl._autoprefixerCascade) {
decl._autoprefixerCascade =
this.all.options.cascade !== false && decl.raw('before').includes('\n')
}
return decl._autoprefixerCascade
}
/**
* Return unprefixed version of property
*/
normalize(prop) {
return prop
}
/**
* Return list of prefixed properties to clean old prefixes
*/
old(prop, prefix) {
return [this.prefixed(prop, prefix)]
}
/**
* Check `value`, that it contain other prefixes, rather than `prefix`
*/
otherPrefixes(value, prefix) {
for (let other of Browsers.prefixes()) {
if (other === prefix) {
continue
}
if (value.includes(other)) {
return value.replace(/var\([^)]+\)/, '').includes(other)
}
}
return false
}
/**
* Return prefixed version of property
*/
prefixed(prop, prefix) {
return prefix + prop
}
/**
@@ -177,10 +157,30 @@ class Declaration extends Prefixer {
}
/**
* 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
}
}
+9 -9
View File
@@ -2,6 +2,13 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class AlignContent extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'align-content'
}
/**
* Change property name for 2012 spec
*/
@@ -14,13 +21,6 @@ class AlignContent extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'align-content'
}
/**
* Change value for 2012 spec and ignore prefix for 2009
*/
@@ -42,8 +42,8 @@ AlignContent.names = ['align-content', 'flex-line-pack']
AlignContent.oldValues = {
'flex-end': 'end',
'flex-start': 'start',
'space-between': 'justify',
'space-around': 'distribute'
'space-around': 'distribute',
'space-between': 'justify'
}
module.exports = AlignContent
+7 -7
View File
@@ -2,6 +2,13 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class AlignItems extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'align-items'
}
/**
* Change property name for 2009 and 2012 specs
*/
@@ -17,13 +24,6 @@ class AlignItems extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'align-items'
}
/**
* Change value for 2009 and 2012 specs
*/
+7 -7
View File
@@ -11,6 +11,13 @@ class AlignSelf extends Declaration {
)
}
/**
* Return property name by final spec
*/
normalize() {
return 'align-self'
}
/**
* Change property name for 2012 specs
*/
@@ -23,13 +30,6 @@ class AlignSelf extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'align-self'
}
/**
* Change value for 2012 spec and ignore prefix for 2009
*/
+10 -10
View File
@@ -1,16 +1,6 @@
let Declaration = require('../declaration')
class BlockLogical extends Declaration {
/**
* Use old syntax for -moz- and -webkit-
*/
prefixed(prop, prefix) {
if (prop.includes('-start')) {
return prefix + prop.replace('-block-start', '-before')
}
return prefix + prop.replace('-block-end', '-after')
}
/**
* Return property name by spec
*/
@@ -20,6 +10,16 @@ class BlockLogical extends Declaration {
}
return prop.replace('-after', '-block-end')
}
/**
* Use old syntax for -moz- and -webkit-
*/
prefixed(prop, prefix) {
if (prop.includes('-start')) {
return prefix + prop.replace('-block-start', '-before')
}
return prefix + prop.replace('-block-end', '-after')
}
}
BlockLogical.names = [
+7 -7
View File
@@ -1,6 +1,13 @@
let Declaration = require('../declaration')
class BorderRadius extends Declaration {
/**
* Return unprefixed version of property
*/
normalize(prop) {
return BorderRadius.toNormal[prop] || prop
}
/**
* Change syntax, when add Mozilla prefix
*/
@@ -10,13 +17,6 @@ class BorderRadius extends Declaration {
}
return super.prefixed(prop, prefix)
}
/**
* Return unprefixed version of property
*/
normalize(prop) {
return BorderRadius.toNormal[prop] || prop
}
}
BorderRadius.names = ['border-radius']
+16 -16
View File
@@ -2,10 +2,16 @@ let Declaration = require('../declaration')
class BreakProps extends 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)
}
/**
@@ -21,6 +27,13 @@ class BreakProps extends Declaration {
return 'break-after'
}
/**
* Change name for -webkit- and -moz- prefix
*/
prefixed(prop, prefix) {
return `${prefix}column-${prop}`
}
/**
* Change prefixed value for avoid-column and avoid-page
*/
@@ -33,19 +46,6 @@ class BreakProps extends Declaration {
}
return super.set(decl, prefix)
}
/**
* 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)
}
}
BreakProps.names = [
+9 -9
View File
@@ -17,6 +17,15 @@ class DisplayFlex extends Value {
return decl.prop === 'display' && decl.value === this.name
}
/**
* 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
*/
@@ -49,15 +58,6 @@ class DisplayFlex extends Value {
replace(string, prefix) {
return this.prefixed(prefix)
}
/**
* Change value for old specs
*/
old(prefix) {
let prefixed = this.prefixed(prefix)
if (!prefixed) return undefined
return new OldValue(this.name, prefixed)
}
}
DisplayFlex.names = ['display-flex', 'inline-flex']
+7 -7
View File
@@ -2,13 +2,6 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class FlexDirection extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'flex-direction'
}
/**
* Use two properties for 2009 spec
*/
@@ -53,6 +46,13 @@ class FlexDirection extends Declaration {
return decl.parent.insertBefore(decl, cloned)
}
/**
* Return property name by final spec
*/
normalize() {
return 'flex-direction'
}
/**
* Clean two properties for 2009 spec
*/
+7 -7
View File
@@ -4,6 +4,13 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class Flex extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'flex'
}
/**
* Change property name for 2009 spec
*/
@@ -16,13 +23,6 @@ class Flex extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'flex'
}
/**
* Spec 2009 supports only first argument
* Spec 2012 disallows unitless basis
+282 -282
View File
@@ -9,49 +9,211 @@ let IS_DIRECTION = /top|left|right|bottom/gi
class Gradient extends Value {
/**
* 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 undefined
}
/**
* Get div token from exists parameters
*/
cloneDiv(params) {
for (let i of params) {
if (i.type === 'div' && i.value === ',') {
return i
}
}
return ast.toString()
return { after: ' ', type: 'div', value: ',' }
}
/**
* Replace first token
* Change colors syntax to old webkit
*/
replaceFirst(params, ...words) {
let prefix = words.map(i => {
if (i === ' ') {
return { type: 'space', value: i }
colorStops(params) {
let result = []
for (let i = 0; i < params.length; i++) {
let pos
let param = params[i]
let item
if (i === 0) {
continue
}
return { type: 'word', value: i }
})
return prefix.concat(params.slice(1))
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
}
/**
* Convert angle unit to deg
* Change new direction to old
*/
normalizeUnit(str, full) {
let num = parseFloat(str)
let deg = (num / full) * 360
return `${deg}deg`
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
}
/**
* 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`
*/
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)
}
}
}
/**
* 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)
}
/**
* 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
}
/**
* 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
}
/**
@@ -95,146 +257,66 @@ class Gradient extends Value {
}
/**
* Replace old direction to new
* Convert angle unit to deg
*/
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
normalizeUnit(str, full) {
let num = parseFloat(str)
let deg = (num / full) * 360
return `${deg}deg`
}
/**
* Look for at word
* Remove old WebKit gradient too
*/
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
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 {
state = 'before'
type = 'radial'
}
}
return false
}
let string = '-gradient'
let regexp = utils.regexp(
`-webkit-(${type}-gradient|gradient\\(\\s*${type})`,
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)
}
return new OldValue(this.name, prefix + this.name, string, regexp)
} else {
return super.old(prefix)
}
}
/**
* Add 90 degrees
* Change direction syntax to old webkit
*/
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`
}
oldDirection(params) {
let div = this.cloneDiv(params[0])
/**
* 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)
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]
}
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))
}
/**
@@ -284,133 +366,51 @@ class Gradient extends Value {
}
/**
* Change direction syntax to old webkit
* Change degrees for webkit prefix
*/
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())
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
}
}
words = words.join(' ')
let old = Gradient.oldDirections[words] || words
params[0] = [{ type: 'word', value: old }, div]
return params[0]
}
return ast.toString()
}
/**
* Get div token from exists parameters
* Replace first token
*/
cloneDiv(params) {
for (let i of params) {
if (i.type === 'div' && i.value === ',') {
return i
replaceFirst(params, ...words) {
let prefix = words.map(i => {
if (i === ' ') {
return { type: 'space', value: i }
}
}
return { type: 'div', value: ',', after: ' ' }
return { type: 'word', value: i }
})
return prefix.concat(params.slice(1))
}
revertDirection(word) {
return Gradient.directions[word.toLowerCase()] || word
}
/**
* Change colors syntax to old webkit
* Round float and save digits under dot
*/
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
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 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
roundFloat(float, digits) {
return parseFloat(float.toFixed(digits))
}
}
@@ -422,27 +422,27 @@ Gradient.names = [
]
Gradient.directions = {
top: 'bottom', // default value
left: 'right',
bottom: 'top',
right: 'left'
left: 'right',
right: 'left',
top: 'bottom' // default value
}
// 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',
'bottom right': 'left top, right bottom',
'left': 'right top, left top',
'left bottom': 'right top, left bottom',
'left top': 'right bottom, left top',
'left bottom': 'right top, left bottom'
'right': 'left top, 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',
'top right': 'left bottom, right top'
}
module.exports = Gradient
+7 -7
View File
@@ -8,19 +8,19 @@ class GridColumnAlign extends Declaration {
return !decl.value.includes('flex-') && decl.value !== 'baseline'
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'grid-column-align'
}
/**
* Change IE property back
*/
normalize() {
return 'justify-self'
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'grid-column-align'
}
}
GridColumnAlign.names = ['grid-column-align']
+7 -7
View File
@@ -8,19 +8,19 @@ class GridRowAlign extends Declaration {
return !decl.value.includes('flex-') && decl.value !== 'baseline'
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'grid-row-align'
}
/**
* Change IE property back
*/
normalize() {
return 'align-self'
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'grid-row-align'
}
}
GridRowAlign.names = ['grid-row-align']
+23 -23
View File
@@ -1,31 +1,14 @@
let Declaration = require('../declaration')
let {
prefixTrackProp,
prefixTrackValue,
autoplaceGridItems,
getGridGap,
inheritGridGap
inheritGridGap,
prefixTrackProp,
prefixTrackValue
} = require('./grid-utils')
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) {
if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)
@@ -56,15 +39,15 @@ class GridRowsColumns extends Declaration {
}
let prefixValue = prefixTrackValue({
value,
gap: gapValue
gap: gapValue,
value
})
/**
* Insert prefixes
*/
decl.cloneBefore({
prop: prefixTrackProp({ prop, prefix }),
prop: prefixTrackProp({ prefix, prop }),
value: prefixValue
})
@@ -113,6 +96,23 @@ class GridRowsColumns extends Declaration {
return undefined
}
/**
* 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)
}
}
GridRowsColumns.names = [
+12 -12
View File
@@ -1,12 +1,12 @@
let Declaration = require('../declaration')
let {
getGridGap,
inheritGridGap,
parseGridAreas,
warnMissedAreas,
prefixTrackProp,
prefixTrackValue,
getGridGap,
warnGridGap,
inheritGridGap
warnMissedAreas
} = require('./grid-utils')
function getGridRows(tpl) {
@@ -39,8 +39,8 @@ class GridTemplateAreas extends Declaration {
hasRows = true
let { prop, value } = trackDecl
trackDecl.cloneBefore({
prop: prefixTrackProp({ prop, prefix }),
value: prefixTrackValue({ value, gap: gap.row })
prop: prefixTrackProp({ prefix, prop }),
value: prefixTrackValue({ gap: gap.row, value })
})
} else {
hasColumns = true
@@ -52,25 +52,25 @@ class GridTemplateAreas extends Declaration {
if (hasColumns && !hasRows && gap.row && gridRows.length > 1) {
decl.cloneBefore({
prop: '-ms-grid-rows',
raws: {},
value: prefixTrackValue({
value: `repeat(${gridRows.length}, auto)`,
gap: gap.row
}),
raws: {}
gap: gap.row,
value: `repeat(${gridRows.length}, auto)`
})
})
}
// warnings
warnGridGap({
decl,
gap,
hasColumns,
decl,
result
})
let areas = parseGridAreas({
rows: gridRows,
gap
gap,
rows: gridRows
})
warnMissedAreas(areas, decl, result)
+9 -9
View File
@@ -1,10 +1,10 @@
let Declaration = require('../declaration')
let {
parseTemplate,
warnMissedAreas,
getGridGap,
inheritGridGap,
parseTemplate,
warnGridGap,
inheritGridGap
warnMissedAreas
} = require('./grid-utils')
class GridTemplate extends Declaration {
@@ -26,7 +26,7 @@ class GridTemplate extends Declaration {
*/
let inheritedGap = inheritGridGap(decl, gap)
let { rows, columns, areas } = parseTemplate({
let { areas, columns, rows } = parseTemplate({
decl,
gap: inheritedGap || gap
})
@@ -36,9 +36,9 @@ class GridTemplate extends Declaration {
let hasColumns = Boolean(columns)
warnGridGap({
decl,
gap,
hasColumns,
decl,
result
})
@@ -47,16 +47,16 @@ class GridTemplate extends Declaration {
if ((hasRows && hasColumns) || hasAreas) {
decl.cloneBefore({
prop: '-ms-grid-rows',
value: rows,
raws: {}
raws: {},
value: rows
})
}
if (hasColumns) {
decl.cloneBefore({
prop: '-ms-grid-columns',
value: columns,
raws: {}
raws: {},
value: columns
})
}
+28 -28
View File
@@ -90,7 +90,7 @@ function insertDecl(decl, prop, value) {
exports.prefixTrackProp = prefixTrackProp
function prefixTrackProp({ prop, prefix }) {
function prefixTrackProp({ prefix, prop }) {
return prefix + prop.replace('template-', '')
}
@@ -105,9 +105,9 @@ function transformRepeat({ nodes }, { gap }) {
return result
},
{
count: [],
key: 'count',
size: [],
count: []
size: []
}
)
@@ -132,7 +132,7 @@ function transformRepeat({ nodes }, { gap }) {
exports.prefixTrackValue = prefixTrackValue
function prefixTrackValue({ value, gap }) {
function prefixTrackValue({ gap, value }) {
let result = parser(value).nodes.reduce((nodes, node) => {
if (node.type === 'function' && node.value === 'repeat') {
return nodes.concat({
@@ -164,7 +164,7 @@ function prefixTrackValue({ value, gap }) {
let DOTS = /^\.+$/
function track(start, end) {
return { start, end, span: end - start }
return { end, span: end - start, start }
}
function getColumns(line) {
@@ -173,7 +173,7 @@ function getColumns(line) {
exports.parseGridAreas = parseGridAreas
function parseGridAreas({ rows, gap }) {
function parseGridAreas({ gap, rows }) {
return rows.reduce((areas, line, rowIndex) => {
if (gap.row) rowIndex *= 2
@@ -248,25 +248,25 @@ function parseTemplate({ decl, gap }) {
return result
},
{
key: 'rows',
areas: [],
columns: [],
rows: [],
areas: []
key: 'rows',
rows: []
}
)
return {
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(' ')
})
}
}
@@ -429,12 +429,12 @@ function parseGridTemplatesData(css) {
parsed[index].allAreas = uniq([...allAreas, ...areaNames])
parsed[index].rules.push({
hasDuplicates: !hasNoDuplicates,
params: media.params,
selectors: rule.selectors,
node: rule,
areas,
duplicateAreaNames,
areas
hasDuplicates: !hasNoDuplicates,
node: rule,
params: media.params,
selectors: rule.selectors
})
} else {
// index is NOT found, push the new item to the parsed array
@@ -443,13 +443,13 @@ function parseGridTemplatesData(css) {
areasCount: 0,
rules: [
{
hasDuplicates: false,
duplicateRules: [],
params: media.params,
selectors: rule.selectors,
node: rule,
areas,
duplicateAreaNames: [],
areas
duplicateRules: [],
hasDuplicates: false,
node: rule,
params: media.params,
selectors: rule.selectors
}
]
})
@@ -993,7 +993,7 @@ function inheritGridGap(decl, gap) {
exports.warnGridGap = warnGridGap
function warnGridGap({ gap, hasColumns, decl, result }) {
function warnGridGap({ decl, gap, hasColumns, result }) {
let hasBothGaps = gap.row && gap.column
if (!hasColumns && (hasBothGaps || (gap.column && !gap.row))) {
delete gap.column
@@ -1079,7 +1079,7 @@ function autoplaceGridItems(decl, result, gap, autoflowValue = 'row') {
).join(' ')
})
let areas = parseGridAreas({ rows: filledRows, gap })
let areas = parseGridAreas({ gap, rows: filledRows })
let keys = Object.keys(areas)
let items = keys.map(i => areas[i])
+14 -14
View File
@@ -8,6 +8,13 @@ class ImageRendering extends Declaration {
return decl.value === 'pixelated'
}
/**
* Return property name by spec
*/
normalize() {
return 'image-rendering'
}
/**
* Change property name for IE
*/
@@ -18,6 +25,13 @@ class ImageRendering extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Warn on old value
*/
process(node, result) {
return super.process(node, result)
}
/**
* Change property and value for IE
*/
@@ -27,20 +41,6 @@ class ImageRendering extends Declaration {
decl.value = 'nearest-neighbor'
return decl
}
/**
* Return property name by spec
*/
normalize() {
return 'image-rendering'
}
/**
* Warn on old value
*/
process(node, result) {
return super.process(node, result)
}
}
ImageRendering.names = ['image-rendering', 'interpolation-mode']
+7 -7
View File
@@ -1,19 +1,19 @@
let Declaration = require('../declaration')
class InlineLogical extends Declaration {
/**
* Use old syntax for -moz- and -webkit-
*/
prefixed(prop, prefix) {
return prefix + prop.replace('-inline', '')
}
/**
* Return property name by spec
*/
normalize(prop) {
return prop.replace(/(margin|padding|border)-(start|end)/, '$1-inline-$2')
}
/**
* Use old syntax for -moz- and -webkit-
*/
prefixed(prop, prefix) {
return prefix + prop.replace('-inline', '')
}
}
InlineLogical.names = [
+17 -17
View File
@@ -6,9 +6,11 @@ function regexp(name) {
}
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)
}
isStretch() {
@@ -19,16 +21,6 @@ class Intrinsic extends Value {
)
}
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) {
let prefixed = prefix + this.name
if (this.isStretch()) {
@@ -41,11 +33,19 @@ class Intrinsic extends Value {
return new OldValue(this.name, prefixed, prefixed, regexp(prefixed))
}
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)
}
}
+9 -9
View File
@@ -2,6 +2,13 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class JustifyContent extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'justify-content'
}
/**
* Change property name for 2009 and 2012 specs
*/
@@ -17,13 +24,6 @@ class JustifyContent extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'justify-content'
}
/**
* Change value for 2009 and 2012 specs
*/
@@ -47,8 +47,8 @@ JustifyContent.names = ['justify-content', 'flex-pack', 'box-pack']
JustifyContent.oldValues = {
'flex-end': 'end',
'flex-start': 'start',
'space-between': 'justify',
'space-around': 'distribute'
'space-around': 'distribute',
'space-between': 'justify'
}
module.exports = JustifyContent
+2 -2
View File
@@ -73,9 +73,9 @@ MaskComposite.names = ['mask', 'mask-composite']
MaskComposite.oldValues = {
add: 'source-over',
subtract: 'source-out',
exclude: 'xor',
intersect: 'source-in',
exclude: 'xor'
subtract: 'source-out'
}
MaskComposite.regexp = new RegExp(
+7 -7
View File
@@ -2,6 +2,13 @@ let flexSpec = require('./flex-spec')
let Declaration = require('../declaration')
class Order extends Declaration {
/**
* Return property name by final spec
*/
normalize() {
return 'order'
}
/**
* Change property name for 2009 and 2012 specs
*/
@@ -17,13 +24,6 @@ class Order extends Declaration {
return super.prefixed(prop, prefix)
}
/**
* Return property name by final spec
*/
normalize() {
return 'order'
}
/**
* Fix value for 2009 spec
*/
+7 -7
View File
@@ -1,13 +1,6 @@
let Declaration = require('../declaration')
class OverscrollBehavior extends Declaration {
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'scroll-chaining'
}
/**
* Return property name by spec
*/
@@ -15,6 +8,13 @@ class OverscrollBehavior extends Declaration {
return 'overscroll-behavior'
}
/**
* Change property name for IE
*/
prefixed(prop, prefix) {
return prefix + 'scroll-chaining'
}
/**
* Change value for IE
*/
+13 -13
View File
@@ -2,19 +2,6 @@ let OldValue = require('../old-value')
let Value = require('../value')
class Pixelated extends Value {
/**
* Use non-standard name for WebKit and Firefox
*/
replace(string, prefix) {
if (prefix === '-webkit-') {
return string.replace(this.regexp(), '$1-webkit-optimize-contrast')
}
if (prefix === '-moz-') {
return string.replace(this.regexp(), '$1-moz-crisp-edges')
}
return super.replace(string, prefix)
}
/**
* Different name for WebKit and Firefox
*/
@@ -27,6 +14,19 @@ class Pixelated extends Value {
}
return super.old(prefix)
}
/**
* Use non-standard name for WebKit and Firefox
*/
replace(string, prefix) {
if (prefix === '-webkit-') {
return string.replace(this.regexp(), '$1-webkit-optimize-contrast')
}
if (prefix === '-moz-') {
return string.replace(this.regexp(), '$1-moz-crisp-edges')
}
return super.replace(string, prefix)
}
}
Pixelated.names = ['pixelated']
+7 -7
View File
@@ -1,6 +1,13 @@
let Declaration = require('../declaration')
class PrintColorAdjust extends Declaration {
/**
* Return property name by spec
*/
normalize() {
return 'print-color-adjust'
}
/**
* Change property name for WebKit-based browsers
*/
@@ -11,13 +18,6 @@ class PrintColorAdjust extends Declaration {
return prefix + 'print-color-adjust'
}
}
/**
* Return property name by spec
*/
normalize() {
return 'print-color-adjust'
}
}
PrintColorAdjust.names = ['print-color-adjust', 'color-adjust']
+25 -25
View File
@@ -1,20 +1,6 @@
let Declaration = require('../declaration')
class TransformDecl extends 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
*/
@@ -32,17 +18,6 @@ class TransformDecl extends Declaration {
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
}
/**
* Don't add prefix for IE in keyframes
*/
@@ -60,6 +35,31 @@ class TransformDecl extends Declaration {
}
return undefined
}
/**
* 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
}
}
TransformDecl.names = ['transform', 'transform-origin']
+10 -10
View File
@@ -1,16 +1,6 @@
let Declaration = require('../declaration')
class UserSelect extends 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
*/
@@ -21,6 +11,16 @@ class UserSelect extends Declaration {
return super.insert(decl, prefix, prefixes)
}
}
/**
* Change prefixed value for IE
*/
set(decl, prefix) {
if (prefix === '-ms-' && decl.value === 'contain') {
decl.value = 'element'
}
return super.set(decl, prefix)
}
}
UserSelect.names = ['user-select']
+4 -4
View File
@@ -29,13 +29,13 @@ WritingMode.names = ['writing-mode']
WritingMode.msValues = {
ltr: {
'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'
}
}
+6 -6
View File
@@ -5,17 +5,17 @@ function capitalize(str) {
}
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'
}
+16 -16
View File
@@ -12,6 +12,22 @@ class OldSelector {
this.nameRegexp = selector.regexp()
}
/**
* 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
*/
@@ -46,22 +62,6 @@ class OldSelector {
return true
}
/**
* 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
+20 -20
View File
@@ -34,6 +34,23 @@ function clone(obj, parent) {
}
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
*/
@@ -60,20 +77,10 @@ class Prefixer {
}
/**
* 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
}
constructor(name, prefixes, all) {
this.prefixes = prefixes
this.name = name
this.all = all
clone(node, overrides) {
return Prefixer.clone(node, overrides)
}
/**
@@ -132,13 +139,6 @@ class Prefixer {
return added
}
/**
* Shortcut for Prefixer.clone
*/
clone(node, overrides) {
return Prefixer.clone(node, overrides)
}
}
module.exports = Prefixer
+131 -131
View File
@@ -156,76 +156,77 @@ class Prefixes {
}
/**
* Select prefixes from data, which is necessary for selected browsers
* Declaration loader with caching
*/
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
}
decl(prop) {
if (!declsCache.has(prop)) {
declsCache.set(prop, Declaration.load(prop))
}
return selected
return declsCache.get(prop)
}
/**
* Sort vendor prefixes
* Group declaration by unprefixed property to check them
*/
sort(prefixes) {
return prefixes.sort((a, b) => {
let aLength = utils.removeNote(a).length
let bLength = utils.removeNote(b).length
group(decl) {
let rule = decl.parent
let index = rule.index(decl)
let { length } = rule.nodes
let unprefixed = this.unprefixed(decl.prop)
if (aLength === bLength) {
return b.length - a.length
} else {
return bLength - aLength
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 {
down(callback) {
return checker(+1, callback)
},
up(callback) {
return checker(-1, callback)
}
}
}
/**
* 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)
}
/**
@@ -233,8 +234,8 @@ class Prefixes {
*/
preprocess(selected) {
let add = {
'selectors': [],
'@supports': new Supports(Prefixes, this)
'@supports': new Supports(Prefixes, this),
'selectors': []
}
for (let name in selected.add) {
let prefixes = selected.add[name]
@@ -324,14 +325,76 @@ class Prefixes {
}
/**
* 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
}
})
}
/**
@@ -345,21 +408,6 @@ class Prefixes {
return value
}
/**
* 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
*/
@@ -375,54 +423,6 @@ class Prefixes {
return global || values || []
}
}
/**
* 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
+159 -159
View File
@@ -396,141 +396,6 @@ class Processor {
})
}
/**
* 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
*/
@@ -590,35 +455,43 @@ class Processor {
}
/**
* 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
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')
/**
* 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)
}
/**
@@ -713,6 +586,133 @@ class Processor {
node._autoprefixerGridStatus = value
return value
}
/**
* 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
+17 -17
View File
@@ -7,6 +7,23 @@ const REGEXP = /(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi
const SPLIT = /(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i
class Resolution extends Prefixer {
/**
* 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
*/
@@ -39,23 +56,6 @@ class Resolution extends Prefixer {
return this.prefixName(prefix, name) + colon + value
}
/**
* 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
*/
+81 -81
View File
@@ -12,75 +12,17 @@ class Selector extends Prefixer {
}
/**
* 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
}
/**
* Return prefixed version of selector
*/
prefixed(prefix) {
return this.name.replace(/^(\W*)/, `$1${prefix}`)
}
/**
* Lazy loadRegExp for name
*/
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 this.regexpCache.get(prefix)
}
/**
* All possible prefixes
*/
possible() {
return Browsers.prefixes()
}
/**
* Return all possible selector prefixes
*/
prefixeds(rule) {
if (rule._autoprefixerPrefixeds) {
if (rule._autoprefixerPrefixeds[this.name]) {
return rule._autoprefixerPrefixeds
}
} else {
rule._autoprefixerPrefixeds = {}
}
let prefixeds = {}
if (rule.selector.includes(',')) {
let ruleParts = list.comma(rule.selector)
let toProcess = ruleParts.filter(el => el.includes(this.name))
for (let prefix of this.possible()) {
prefixeds[prefix] = toProcess
.map(el => this.replace(el, prefix))
.join(', ')
}
} else {
for (let prefix of this.possible()) {
prefixeds[prefix] = this.replace(rule.selector, prefix)
}
}
rule._autoprefixerPrefixeds[this.name] = prefixeds
return rule._autoprefixerPrefixeds
let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })
rule.parent.insertBefore(rule, cloned)
}
/**
@@ -119,24 +61,14 @@ class Selector extends Prefixer {
}
/**
* Replace selectors by prefixed one
* Is rule selectors need to be prefixed
*/
replace(selector, prefix) {
return selector.replace(this.regexp(), `$1${this.prefixed(prefix)}`)
}
/**
* Clone and add prefixes for at-rule
*/
add(rule, prefix) {
let prefixeds = this.prefixeds(rule)
if (this.already(rule, prefixeds, prefix)) {
return
check(rule) {
if (rule.selector.includes(this.name)) {
return !!rule.selector.match(this.regexp())
}
let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })
rule.parent.insertBefore(rule, cloned)
return false
}
/**
@@ -145,6 +77,74 @@ class Selector extends Prefixer {
old(prefix) {
return new OldSelector(this, prefix)
}
/**
* All possible prefixes
*/
possible() {
return Browsers.prefixes()
}
/**
* Return prefixed version of selector
*/
prefixed(prefix) {
return this.name.replace(/^(\W*)/, `$1${prefix}`)
}
/**
* Return all possible selector prefixes
*/
prefixeds(rule) {
if (rule._autoprefixerPrefixeds) {
if (rule._autoprefixerPrefixeds[this.name]) {
return rule._autoprefixerPrefixeds
}
} else {
rule._autoprefixerPrefixeds = {}
}
let prefixeds = {}
if (rule.selector.includes(',')) {
let ruleParts = list.comma(rule.selector)
let toProcess = ruleParts.filter(el => el.includes(this.name))
for (let prefix of this.possible()) {
prefixeds[prefix] = toProcess
.map(el => this.replace(el, prefix))
.join(', ')
}
} else {
for (let prefix of this.possible()) {
prefixeds[prefix] = this.replace(rule.selector, prefix)
}
}
rule._autoprefixerPrefixeds[this.name] = prefixeds
return rule._autoprefixerPrefixeds
}
/**
* Lazy loadRegExp for name
*/
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 this.regexpCache.get(prefix)
}
/**
* Replace selectors by prefixed one
*/
replace(selector, prefix) {
return selector.replace(this.regexp(), `$1${this.prefixed(prefix)}`)
}
}
module.exports = Selector
+206 -206
View File
@@ -27,161 +27,25 @@ class Supports {
}
/**
* Return prefixer only with @supports supported browsers
* Add prefixes
*/
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
}
/**
* Parse string into declaration property and value
*/
parse(str) {
let parts = str.split(':')
let prop = parts[0]
let value = parts[1]
if (!value) value = ''
return [prop.trim(), value.trim()]
}
/**
* Create virtual rule to process it by prefixer
*/
virtual(str) {
let [prop, value] = this.parse(str)
let rule = parse('a{}').first
rule.append({ prop, value, raws: { before: '' } })
return rule
}
/**
* Return array of Declaration with all necessary prefixes
*/
prefixed(str) {
let rule = this.virtual(str)
if (this.disabled(rule.first)) {
return rule.nodes
}
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 rule.nodes
}
/**
* Return true if brackets node is "not" word
*/
isNot(node) {
return typeof node === 'string' && /not\s*/i.test(node)
}
/**
* Return true if brackets node is "or" word
*/
isOr(node) {
return typeof node === 'string' && /\s*or\s*/i.test(node)
}
/**
* Return true if brackets node is (prop: value)
*/
isProp(node) {
return (
typeof node === 'object' &&
node.length === 1 &&
typeof node[0] === 'string'
)
}
/**
* 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 we need to remove node
*/
toRemove(str, all) {
let [prop, value] = this.parse(str)
let unprefixed = this.all.unprefixed(prop)
let cleaner = this.all.cleaner()
if (
cleaner.remove[prop] &&
cleaner.remove[prop].remove &&
!this.isHack(all, unprefixed)
) {
return true
}
for (let checker of cleaner.values('remove', unprefixed)) {
if (checker.check(value)) {
return true
}
}
return false
}
/**
* Remove all unnecessary prefixes
*/
remove(nodes, all) {
let i = 0
while (i < nodes.length) {
if (
!this.isNot(nodes[i - 1]) &&
this.isProp(nodes[i]) &&
this.isOr(nodes[i + 1])
) {
if (this.toRemove(nodes[i][0], all)) {
nodes.splice(i, 2)
continue
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)
}
i += 2
continue
return i
}
if (typeof nodes[i] === 'object') {
nodes[i] = this.remove(nodes[i], all)
if (typeof i === 'object') {
return this.add(i, all)
}
i += 1
}
return nodes
return i
})
}
/**
@@ -214,64 +78,6 @@ class Supports {
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)]
}
}
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
})
}
/**
* 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)
}
/**
* Check global options
*/
@@ -297,6 +103,200 @@ class Supports {
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
*/
isNot(node) {
return typeof node === 'string' && /not\s*/i.test(node)
}
/**
* Return true if brackets node is "or" word
*/
isOr(node) {
return typeof node === 'string' && /\s*or\s*/i.test(node)
}
/**
* Return true if brackets node is (prop: value)
*/
isProp(node) {
return (
typeof node === 'object' &&
node.length === 1 &&
typeof node[0] === 'string'
)
}
/**
* 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)]
}
}
return nodes.map(i => this.normalize(i))
}
/**
* Parse string into declaration property and value
*/
parse(str) {
let parts = str.split(':')
let prop = parts[0]
let value = parts[1]
if (!value) value = ''
return [prop.trim(), value.trim()]
}
/**
* Return array of Declaration with all necessary prefixes
*/
prefixed(str) {
let rule = this.virtual(str)
if (this.disabled(rule.first)) {
return rule.nodes
}
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 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
*/
remove(nodes, all) {
let i = 0
while (i < nodes.length) {
if (
!this.isNot(nodes[i - 1]) &&
this.isProp(nodes[i]) &&
this.isOr(nodes[i + 1])
) {
if (this.toRemove(nodes[i][0], all)) {
nodes.splice(i, 2)
continue
}
i += 2
continue
}
if (typeof nodes[i] === 'object') {
nodes[i] = this.remove(nodes[i], all)
}
i += 1
}
return nodes
}
/**
* Return true if we need to remove node
*/
toRemove(str, all) {
let [prop, value] = this.parse(str)
let unprefixed = this.all.unprefixed(prop)
let cleaner = this.all.cleaner()
if (
cleaner.remove[prop] &&
cleaner.remove[prop].remove &&
!this.isHack(all, unprefixed)
) {
return true
}
for (let checker of cleaner.values('remove', unprefixed)) {
if (checker.check(value)) {
return true
}
}
return false
}
/**
* Create virtual rule to process it by prefixer
*/
virtual(str) {
let [prop, value] = this.parse(str)
let rule = parse('a{}').first
rule.append({ prop, raws: { before: '' }, value })
return rule
}
}
module.exports = Supports
+131 -131
View File
@@ -79,21 +79,6 @@ class Transition {
}
}
/**
* 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
*/
@@ -101,15 +86,6 @@ class Transition {
return decl.parent.some(i => i.prop === prop && i.value === value)
}
/**
* 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
*/
@@ -155,6 +131,123 @@ class Transition {
}
}
/**
* Remove all non-webkit prefixes and unprefixed params if we have prefixed
*/
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))
let result = []
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)
}
}
return result
}
cleanOtherPrefixes(params, prefix) {
return params.filter(param => {
let current = vendor.prefix(this.findProp(param))
return current === '' || current === prefix
})
}
/**
* Return new param array with different name
*/
clone(origin, name, param) {
let result = []
let changed = false
for (let i of param) {
if (!changed && i.type === 'word' && i.value === origin) {
result.push({ type: 'word', value: name })
changed = true
} else {
result.push(i)
}
}
return result
}
/**
* 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
*/
div(params) {
for (let param of params) {
for (let node of param) {
if (node.type === 'div' && node.value === ',') {
return node
}
}
}
return { after: ' ', type: 'div', value: ',' }
}
/**
* 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
}
/**
* 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 === ',') {
result.push(param)
param = []
}
}
result.push(param)
return result.filter(i => i.length > 0)
}
/**
* Process transition and remove all unnecessary properties
*/
@@ -191,21 +284,22 @@ class Transition {
}
/**
* Parse properties list to array
* Check if transition prop is inside vendor specific rule
*/
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 === ',') {
result.push(param)
param = []
}
ruleVendorPrefixes(decl) {
let { parent } = decl
if (parent.type !== 'rule') {
return false
} else if (!parent.selector.includes(':-')) {
return false
}
result.push(param)
return result.filter(i => i.length > 0)
let selectors = Browsers.prefixes().filter(s =>
parent.selector.includes(':' + s)
)
return selectors.length > 0 ? selectors : false
}
/**
@@ -230,100 +324,6 @@ class Transition {
}
return parser.stringify({ nodes })
}
/**
* Return new param array with different name
*/
clone(origin, name, param) {
let result = []
let changed = false
for (let i of param) {
if (!changed && i.type === 'word' && i.value === origin) {
result.push({ type: 'word', value: name })
changed = true
} else {
result.push(i)
}
}
return result
}
/**
* Find or create separator
*/
div(params) {
for (let param of params) {
for (let node of param) {
if (node.type === 'div' && node.value === ',') {
return node
}
}
}
return { type: 'div', value: ',', after: ' ' }
}
cleanOtherPrefixes(params, prefix) {
return params.filter(param => {
let current = vendor.prefix(this.findProp(param))
return current === '' || current === prefix
})
}
/**
* Remove all non-webkit prefixes and unprefixed params if we have prefixed
*/
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))
let result = []
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)
}
}
return result
}
/**
* 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
}
/**
* Check if transition prop is inside vendor specific rule
*/
ruleVendorPrefixes(decl) {
let { parent } = decl
if (parent.type !== 'rule') {
return false
} else if (!parent.selector.includes(':-')) {
return false
}
let selectors = Browsers.prefixes().filter(s =>
parent.selector.includes(':' + s)
)
return selectors.length > 0 ? selectors : false
}
}
module.exports = Transition
+26 -26
View File
@@ -58,6 +58,25 @@ class Value extends Prefixer {
return result
}
/**
* 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
*/
@@ -70,6 +89,13 @@ class Value extends Prefixer {
return !!value.match(this.regexp())
}
/**
* Return function to fast find prefixed value
*/
old(prefix) {
return new OldValue(this.name, prefix + this.name)
}
/**
* Lazy regexp loading
*/
@@ -94,32 +120,6 @@ class Value extends Prefixer {
return decl.value
}
}
/**
* 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
+12 -12
View File
@@ -43,27 +43,27 @@
"postcss": "^8.1.0"
},
"dependencies": {
"browserslist": "^4.21.5",
"caniuse-lite": "^1.0.30001470",
"browserslist": "^4.21.9",
"caniuse-lite": "^1.0.30001513",
"fraction.js": "^4.2.0",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
"postcss-value-parser": "^4.2.0"
},
"devDependencies": {
"@logux/eslint-config": "^49.0.0",
"@size-limit/preset-small-lib": "8.2.4",
"c8": "^7.13.0",
"clean-publish": "^4.1.1",
"eslint": "^8.36.0",
"eslint-config-standard": "^17.0.0",
"@logux/eslint-config": "^51.0.0",
"@size-limit/preset-small-lib": "8.2.6",
"c8": "^8.0.0",
"clean-publish": "^4.2.0",
"eslint": "^8.44.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.6.1",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-prefer-let": "^3.0.1",
"eslint-plugin-promise": "^6.1.1",
"nanospy": "^0.5.0",
"postcss": "^8.4.21",
"size-limit": "^8.2.4",
"nanospy": "^1.0.0",
"postcss": "^8.4.25",
"size-limit": "^8.2.6",
"uvu": "^0.5.6"
},
"prettier": {
+419 -301
View File
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -1,4 +1,4 @@
let { equal, throws, type, match, not } = require('uvu/assert')
let { equal, match, not, throws, type } = require('uvu/assert')
let { restoreAll, spyOn } = require('nanospy')
let { readFileSync } = require('fs')
let { join } = require('path')
@@ -8,9 +8,9 @@ let postcss = require('postcss')
let autoprefixer = require('..')
let grider = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Edge 12', 'IE 10'],
cascade: false,
grid: 'autoplace'
grid: 'autoplace',
overrideBrowserslist: ['Chrome 25', 'Edge 12', 'IE 10']
})
let cleaner = autoprefixer({
@@ -26,8 +26,8 @@ let borderer = autoprefixer({
overrideBrowserslist: ['Safari 4', 'Firefox 3.6']
})
let cascader = autoprefixer({
overrideBrowserslist: ['Chrome > 19', 'Firefox 21', 'IE 10'],
cascade: true
cascade: true,
overrideBrowserslist: ['Chrome > 19', 'Firefox 21', 'IE 10']
})
let keyframer = autoprefixer({
overrideBrowserslist: ['Chrome > 19', 'Opera 12']
@@ -48,8 +48,8 @@ let gradienter = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Opera 12', 'Android 2.3']
})
let grouping = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Firefox > 17', 'IE 10', 'Edge 12'],
grid: 'autoplace'
grid: 'autoplace',
overrideBrowserslist: ['Chrome 25', 'Firefox > 17', 'IE 10', 'Edge 12']
})
let ffgradienter = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Opera 12', 'Firefox 6']
@@ -532,8 +532,8 @@ test('does not remove unnecessary prefixes on request', () => {
test('does not add prefixes on request', () => {
for (let i of ['transition', 'values', 'fullscreen']) {
let remover = autoprefixer({
overrideBrowserslist: ['Opera 12'],
add: false
add: false,
overrideBrowserslist: ['Opera 12']
})
let unprefixed = read(i)
equal(postcss([remover]).process(unprefixed).css, unprefixed)
@@ -633,8 +633,8 @@ test('has disabled grid options by default', () => {
test('has different outputs for different grid options', () => {
function ap(gridValue) {
return autoprefixer({
overrideBrowserslist: ['Edge 12', 'IE 10'],
grid: gridValue
grid: gridValue,
overrideBrowserslist: ['Edge 12', 'IE 10']
})
}
let input = read('grid-options')
@@ -676,8 +676,8 @@ test('has different outputs for different grid environment variables', () => {
test('has option to disable flexbox support', () => {
let css = read('flexbox')
let instance = autoprefixer({
overrideBrowserslist: ['IE 10'],
flexbox: false
flexbox: false,
overrideBrowserslist: ['IE 10']
})
let result = postcss([instance]).process(css)
equal(result.css, css)
@@ -685,8 +685,8 @@ test('has option to disable flexbox support', () => {
test('has option to disable 2009 flexbox support', () => {
let ap = autoprefixer({
overrideBrowserslist: ['Chrome > 19'],
flexbox: 'no-2009'
flexbox: 'no-2009',
overrideBrowserslist: ['Chrome > 19']
})
let css = 'a{flex:1;transition:flex}'
let result = postcss([ap]).process(css)
@@ -718,8 +718,8 @@ test('ignores unknown versions on request', () => {
}, /Unknown version 100 of ie/)
not.throws(() => {
autoprefixer({
overrideBrowserslist: ['ie 100'],
ignoreUnknownVersions: true
ignoreUnknownVersions: true,
overrideBrowserslist: ['ie 100']
}).info()
})
})
@@ -1045,8 +1045,8 @@ test('supports grid autoplacement', () => {
test('shows Grid warnings only for IE', () => {
let input = 'a { grid-template-rows: repeat(auto-fit, 1px) }'
let instance = autoprefixer({
overrideBrowserslist: 'chrome 27',
grid: true
grid: true,
overrideBrowserslist: 'chrome 27'
})
let result = postcss([instance]).process(input)
equal(result.warnings().length, 0)
@@ -1130,8 +1130,8 @@ test('add prefix for backface-visibility for Safari 9', () => {
let input =
'a{ ' + 'backface-visibility: hidden; ' + 'transform-style: preserve-3d }'
let ap = autoprefixer({
overrideBrowserslist: ['Safari 9'],
flexbox: false
flexbox: false,
overrideBrowserslist: ['Safari 9']
})
equal(
postcss([ap]).process(input).css,
+7 -7
View File
@@ -10,18 +10,21 @@ let info = require('../lib/info')
let data = {
browsers: agents,
prefixes: {
'@keyframes': {
browsers: ['firefox 21']
},
'a': {
browsers: ['firefox 21', 'firefox 20', 'chrome 30'],
transition: true
},
'c': {
browsers: ['firefox 21'],
props: ['c']
},
'b': {
browsers: ['ie 6', 'firefox 20'],
props: ['a', '*']
},
'c': {
browsers: ['firefox 21'],
props: ['c']
},
'd': {
browsers: ['firefox 21'],
selector: true
@@ -33,9 +36,6 @@ let data = {
'grid-row': {
browsers: ['ie 6']
},
'@keyframes': {
browsers: ['firefox 21']
},
'transition': {
browsers: ['firefox 21']
}
+4 -4
View File
@@ -7,16 +7,16 @@ let autoprefixer = require('..')
test('works with other PostCSS plugins', () => {
let plugin = () => {
return {
postcssPlugin: 'test',
Rule(rule) {
rule.selector = 'b'
},
AtRule: {
mixin: (atRule, { Declaration }) => {
atRule.replaceWith(
new Declaration({ prop: 'user-select', value: 'none' })
)
}
},
postcssPlugin: 'test',
Rule(rule) {
rule.selector = 'b'
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
let { equal, type, is } = require('uvu/assert')
let { equal, is, type } = require('uvu/assert')
let { parse } = require('postcss')
let { test } = require('uvu')
+24 -22
View File
@@ -62,36 +62,38 @@ test('selects necessary prefixes', () => {
test('preprocesses prefixes add data', () => {
equal(fill.add, {
'selectors': [cSel],
'a': aProp,
'@supports': new Supports(Prefixes, fill),
'*': {
values: [bVal]
},
'@supports': new Supports(Prefixes, fill)
'a': aProp,
'selectors': [cSel]
})
})
test('preprocesses prefixes remove data', () => {
equal(
JSON.stringify(fill.remove),
JSON.stringify({
'selectors': [cSel.old('-moz-')],
'-webkit-a': {
remove: true
},
'-ms-a': {
remove: true
},
'-moz- olda': {
remove: true
},
'a': {
values: [old('-ms-b'), old('-moz-b'), old('-webkit-b')]
},
'*': {
values: [old('-ms-b'), old('-moz-b'), old('-webkit-b')]
}
})
JSON.parse(JSON.stringify(fill.remove)),
JSON.parse(
JSON.stringify({
'-moz- olda': {
remove: true
},
'-ms-a': {
remove: true
},
'-webkit-a': {
remove: true
},
'*': {
values: [old('-ms-b'), old('-moz-b'), old('-webkit-b')]
},
'a': {
values: [old('-ms-b'), old('-moz-b'), old('-webkit-b')]
},
'selectors': [cSel.old('-moz-')]
})
)
)
})
+6 -6
View File
@@ -42,16 +42,16 @@ test('grouping rule gets correct _autoprefixerPrefixeds property', () => {
rSel.prefixeds(css.first)
equal(css.first._autoprefixerPrefixeds, {
'::selection': {
'-webkit-': '.c::-webkit-selection',
'-moz-': '.c::-moz-selection',
'-ms-': '.c::-ms-selection',
'-o-': '.c::-o-selection'
'-o-': '.c::-o-selection',
'-webkit-': '.c::-webkit-selection'
},
':read-only': {
'-webkit-': '.d:-webkit-read-only',
'-moz-': '.d:-moz-read-only',
'-ms-': '.d:-ms-read-only',
'-o-': '.d:-o-read-only'
'-o-': '.d:-o-read-only',
'-webkit-': '.d:-webkit-read-only'
}
})
})
@@ -60,10 +60,10 @@ test('returns all available prefixed selectors', () => {
let css = parse('::selection {}')
equal(selector.prefixeds(css.first), {
'::selection': {
'-webkit-': '::-webkit-selection',
'-moz-': '::-moz-selection',
'-ms-': '::-ms-selection',
'-o-': '::-o-selection'
'-o-': '::-o-selection',
'-webkit-': '::-webkit-selection'
}
})
})