-
Notifications
You must be signed in to change notification settings - Fork 24
/
supported-value.js
101 lines (85 loc) · 2.77 KB
/
supported-value.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import isInBrowser from 'is-in-browser'
import prefix from './prefix'
import supportedProperty from './supported-property'
const cache = {}
const transitionProperties = {
transition: 1,
'transition-property': 1,
'-webkit-transition': 1,
'-webkit-transition-property': 1
}
const transPropsRegExp = /(^\s*[\w-]+)|, (\s*[\w-]+)(?![^()]*\))/g
let el
/**
* Returns prefixed value transition/transform if needed.
*
* @param {String} match
* @param {String} p1
* @param {String} p2
* @return {String}
* @api private
*/
function prefixTransitionCallback(match, p1, p2) {
if (p1 === 'var') return 'var'
if (p1 === 'all') return 'all'
if (p2 === 'all') return ', all'
const prefixedValue = p1 ? supportedProperty(p1) : `, ${supportedProperty(p2)}`
if (!prefixedValue) return p1 || p2
return prefixedValue
}
if (isInBrowser) el = document.createElement('p')
/**
* Returns prefixed value if needed. Returns `false` if value is not supported.
*
* @param {String} property
* @param {String} value
* @return {String|Boolean}
* @api public
*/
export default function supportedValue(property, value) {
// For server-side rendering.
let prefixedValue = value
if (!el || property === 'content') return value
// It is a string or a number as a string like '1'.
// We want only prefixable values here.
// eslint-disable-next-line no-restricted-globals
if (typeof prefixedValue !== 'string' || !isNaN(parseInt(prefixedValue, 10))) {
return prefixedValue
}
// Create cache key for current value.
const cacheKey = property + prefixedValue
// Remove cache for benchmark tests or return value from cache.
if (process.env.NODE_ENV !== 'benchmark' && cache[cacheKey] != null) {
return cache[cacheKey]
}
// IE can even throw an error in some cases, for e.g. style.content = 'bar'.
try {
// Test value as it is.
el.style[property] = prefixedValue
} catch (err) {
// Return false if value not supported.
cache[cacheKey] = false
return false
}
// If 'transition' or 'transition-property' property.
if (transitionProperties[property]) {
prefixedValue = prefixedValue.replace(transPropsRegExp, prefixTransitionCallback)
} else if (el.style[property] === '') {
// Value with a vendor prefix.
prefixedValue = prefix.css + prefixedValue
// Hardcode test to convert "flex" to "-ms-flexbox" for IE10.
if (prefixedValue === '-ms-flex') el.style[property] = '-ms-flexbox'
// Test prefixed value.
el.style[property] = prefixedValue
// Return false if value not supported.
if (el.style[property] === '') {
cache[cacheKey] = false
return false
}
}
// Reset styles for current property.
el.style[property] = ''
// Write current value to cache.
cache[cacheKey] = prefixedValue
return cache[cacheKey]
}