inline-style-prefixer
Advanced tools
Comparing version 0.2.5 to 0.3.0
@@ -6,43 +6,27 @@ 'use strict'; | ||
}); | ||
exports.addPrefixedProperties = addPrefixedProperties; | ||
exports.getPrefixedValue = getPrefixedValue; | ||
exports.getPrefixedProperty = getPrefixedProperty; | ||
exports.caplitalizeString = caplitalizeString; | ||
exports.isPrefixProperty = isPrefixProperty; | ||
exports.resolveHack = resolveHack; | ||
exports.generateRequiredProperties = generateRequiredProperties; | ||
exports.resolveProps = resolveProps; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _browserinfo = require('./browserinfo'); | ||
var _objectAssign = require('object-assign'); | ||
var _browserinfo2 = _interopRequireDefault(_browserinfo); | ||
var _objectAssign2 = _interopRequireDefault(_objectAssign); | ||
var _caniuseData = require('../caniuseData'); | ||
var _getBrowserInformation = require('./getBrowserInformation'); | ||
var _getBrowserInformation2 = _interopRequireDefault(_getBrowserInformation); | ||
var _caniuseData = require('./caniuseData'); | ||
var _caniuseData2 = _interopRequireDefault(_caniuseData); | ||
var _hacks = require('./hacks'); | ||
var _Plugins = require('./Plugins'); | ||
var _hacks2 = _interopRequireDefault(_hacks); | ||
var _Plugins2 = _interopRequireDefault(_Plugins); | ||
var browserinfo = undefined; | ||
var requiredHacks = []; | ||
var requiredProperties = []; | ||
var defaultUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : undefined; | ||
var browserProps = undefined; | ||
var lastUserAgent = undefined; | ||
var generated = false; | ||
/** | ||
* Transforms camel case to dash case (param case) | ||
* @param {string} str - str that gets transformed | ||
* Thanks to @ianobermiller for this short method | ||
* https://github.com/rofrischmann/inline-style-prefixer/issues/9 | ||
*/ | ||
var CAMEL_CASE_REGEXP = /([a-z]|^)([A-Z])/g; | ||
var camelToDashCase = function camelToDashCase(str) { | ||
return str.replace(CAMEL_CASE_REGEXP, function (match, p1, p2) { | ||
return p1 + '-' + p2.toLowerCase(); | ||
}); | ||
}; | ||
var defaultUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : undefined; | ||
@@ -52,3 +36,3 @@ /** | ||
* @param {Object} styles - Styles object that gets prefixed | ||
* @param {Boolean} hacks - If hacks should be used to resolve browser differences | ||
* @param {string} userAgent - userAgent to gather prefix information according to caniuse.com | ||
*/ | ||
@@ -59,10 +43,23 @@ | ||
if (lastUserAgent !== userAgent) { | ||
generated = false; | ||
generateRequiredProperties(userAgent); | ||
if (userAgent && lastUserAgent !== userAgent) { | ||
var _ret = (function () { | ||
browserinfo = (0, _getBrowserInformation2['default'])(userAgent); | ||
var data = _caniuseData2['default'][browserinfo.browser]; | ||
if (data) { | ||
browserProps = Object.keys(data).filter(function (key) { | ||
return data[key] >= browserinfo.version; | ||
}); | ||
} else { | ||
console.warn('Your userAgent seems to be not supported by inline-style-prefixer. Feel free to open an issue.'); | ||
return { | ||
v: styles | ||
}; | ||
} | ||
})(); | ||
if (typeof _ret === 'object') return _ret.v; | ||
} | ||
//only add prefixes if needed | ||
if (requiredProperties.length > 0) { | ||
addPrefixedProperties(styles); | ||
if (browserProps && browserProps.length > 0) { | ||
resolveProps(styles); | ||
} | ||
@@ -73,2 +70,10 @@ return styles; | ||
/** | ||
* Capitalizes first letter of a string | ||
* @param {String} str - str to caplitalize | ||
*/ | ||
var caplitalizeString = function caplitalizeString(str) { | ||
return str.charAt(0).toUpperCase() + str.slice(1); | ||
}; | ||
/** | ||
* Adds prefixed properties to a style object | ||
@@ -78,3 +83,3 @@ * @param {Object} styles - Style object that gets prefixed properties added | ||
function addPrefixedProperties(styles) { | ||
function resolveProps(styles) { | ||
Object.keys(styles).forEach(function (property) { | ||
@@ -84,161 +89,16 @@ var value = styles[property]; | ||
//recursively loop through nested style objects | ||
addPrefixedProperties(value); | ||
resolveProps(value); | ||
} else { | ||
//add prefixes if needed | ||
if (isPrefixProperty(property)) { | ||
styles[getPrefixedProperty(property)] = value; | ||
if (browserProps.indexOf(property) > -1) { | ||
styles[browserinfo.prefix.inline + caplitalizeString(property)] = value; | ||
delete styles[property]; | ||
} | ||
//resolve hacks | ||
requiredHacks.forEach(function (hack) { | ||
resolveHack(hack, styles, property, value); | ||
//resolve plugins | ||
_Plugins2['default'].forEach(function (plugin) { | ||
return (0, _objectAssign2['default'])(styles, plugin(property, value, browserinfo, styles)); | ||
}); | ||
} | ||
}); | ||
return styles; | ||
} | ||
/** | ||
* Returns a prefixed value | ||
* Optionaly uses an alternative value | ||
* @param {string} property - CSS property that gets prefixed | ||
* @param {any} value - old value that gets prefixed | ||
* @param {any} alternative - alternative value used for prefixing | ||
*/ | ||
function getPrefixedValue(property, value, alternative) { | ||
if (alternative) { | ||
return value.replace(value, browserinfo.prefix.CSS + alternative, 'g') + ';' + camelToDashCase(property) + ':' + value; | ||
} else { | ||
return browserinfo.prefix.CSS + value + ';' + camelToDashCase(property) + ':' + value; | ||
} | ||
} | ||
/** | ||
* Returns a prefixed style property | ||
* @param {String} property - a style property in camelCase | ||
* @param {String} prefix - evaluated vendor prefix that will be added | ||
*/ | ||
function getPrefixedProperty(property) { | ||
return browserinfo.prefix.inline + caplitalizeString(property); | ||
} | ||
/** | ||
* Capitalizes first letter of a string | ||
* @param {String} str - str to caplitalize | ||
*/ | ||
function caplitalizeString(str) { | ||
return str.charAt(0).toUpperCase() + str.slice(1); | ||
} | ||
/** | ||
* Checks if a property needs to be prefixed | ||
* @param {String} property - a style property | ||
*/ | ||
function isPrefixProperty(property) { | ||
return requiredProperties.indexOf(property) > -1; | ||
} | ||
/** | ||
* Resolves browser issues using some hacks | ||
* @param {Object} hackData - contains a condition and properties/values that need to be corrected | ||
* @param {Object} styles - a style object | ||
* @param {string} property - property that gets corrected | ||
* @param {any} value - property value | ||
*/ | ||
function resolveHack(hackData, styles, property, value) { | ||
//prefix ordinary values | ||
if (hackData.prefixValue) { | ||
var values = hackData.prefixValue[property]; | ||
if (values) { | ||
if (hackData.containValue) { | ||
values.forEach(function (val) { | ||
if (value.indexOf(val) > -1) { | ||
styles[property] = getPrefixedValue(property, value, val); | ||
} | ||
}); | ||
} else { | ||
if (values.indexOf(value) > -1) { | ||
styles[property] = getPrefixedValue(property, value); | ||
} | ||
} | ||
} | ||
} | ||
//resolve property issues | ||
if (hackData.alternativeProperty) { | ||
var oldProperty = hackData.alternativeProperty[property]; | ||
if (oldProperty) { | ||
if (oldProperty instanceof Array) { | ||
oldProperty.forEach(function (prop) { | ||
var oldValue = hackData.alternativeValue[prop]; | ||
var alternativeValue = oldValue && oldValue.hasOwnProperty(value) ? oldValue[value] : value; | ||
styles[prop] = alternativeValue; | ||
}); | ||
} else { | ||
var oldValue = hackData.alternativeValue[oldProperty]; | ||
var alternativeValue = oldValue && oldValue.hasOwnProperty(value) ? oldValue[value] : value; | ||
styles[oldProperty] = alternativeValue; | ||
} | ||
} | ||
} | ||
//resolve alternative values | ||
if (hackData.alternativeValue) { | ||
var oldValue = hackData.alternativeValue[property]; | ||
if (oldValue && oldValue[value]) { | ||
styles[property] = oldValue[value] + ';' + camelToDashCase(property) + ':' + value; | ||
} | ||
} | ||
} | ||
/** | ||
* Generates an array of all relevant properties according to the userAgent | ||
* @param {string} userAgent - userAgent which gets used to gather information | ||
*/ | ||
function generateRequiredProperties(userAgent) { | ||
requiredProperties = []; | ||
requiredHacks = []; | ||
if (userAgent) { | ||
browserinfo = (0, _browserinfo2['default'])(userAgent); | ||
var data = _caniuseData2['default'][browserinfo.browser.toLowerCase()]; | ||
//only generate if there is browser data provided | ||
if (data) { | ||
var property = undefined; | ||
for (property in data) { | ||
if (data[property] >= browserinfo.version) { | ||
requiredProperties.push(property); | ||
} | ||
} | ||
//add all required hacks for current browser | ||
var hack = undefined; | ||
for (hack in _hacks2['default']) { | ||
var hackData = _hacks2['default'][hack](browserinfo); | ||
if (hackData) { | ||
requiredHacks.push(hackData); | ||
} | ||
} | ||
generated = true; | ||
return requiredProperties; | ||
} else { | ||
console.warn('Your browser seems to not be supported by inline-style-prefixer.'); | ||
console.warn('Please create an issue at https://github.com/rofrischmann/inline-style-prefixer'); | ||
return false; | ||
} | ||
} else { | ||
console.warn('userAgent needs to be set first. Use `.setUserAgent(userAgent)`'); | ||
return false; | ||
} | ||
} |
{ | ||
"name": "inline-style-prefixer", | ||
"version": "0.2.5", | ||
"version": "0.3.0", | ||
"description": "Autoprefixer for Inline Style objects using userAgent and caniuse data", | ||
@@ -9,4 +9,3 @@ "main": "lib/Prefixer.js", | ||
"README.md", | ||
"lib/", | ||
"generator/" | ||
"lib/" | ||
], | ||
@@ -21,4 +20,3 @@ "scripts": { | ||
"build": "npm run clean && mkdir dist && npm run transpile && npm run generate && npm run bundle", | ||
"release": "npm run build && npm publish", | ||
"postinstall": "npm run generate" | ||
"release": "npm run build && npm publish" | ||
}, | ||
@@ -42,3 +40,4 @@ "repository": { | ||
"bowser": "^1.0.0", | ||
"caniuse-api": "^1.3.2" | ||
"caniuse-api": "^1.3.2", | ||
"object-assign": "^4.0.1" | ||
}, | ||
@@ -45,0 +44,0 @@ "devDependencies": { |
@@ -6,4 +6,2 @@ # Autoprefixer for Inline Style objects | ||
![Dependencies](https://david-dm.org/rofrischmann/inline-style-prefixer.svg) | ||
> **Warning**: Very early stage supporting only a small set of prefixes by now. | ||
**Usage on your own risk**! | ||
@@ -14,4 +12,2 @@ npm install inline-style-prefixer | ||
See [SupportedProps.md](SupportedProps.md) for detail informaton on supported properties that get evaluated and prefixed. | ||
## Usage | ||
@@ -33,17 +29,13 @@ ```javascript | ||
Prefixer(styles) | ||
``` | ||
Assuming you are using .e.g Chrome version 27.0 this would output the following styles object: | ||
```javascript | ||
{ | ||
// Assuming you are using e.g. Chrome version 27.0 this would | ||
// transform your styles object to the following the following | ||
let output = { | ||
transition: '200ms all linear', | ||
WebkitUserSelect: 'none', | ||
userSelect: 'none', | ||
nested: { | ||
boxSizing: 'border-box', | ||
WebkitAppearance: 'none', | ||
appearance: 'none', | ||
color: 'blue', | ||
WebkitFlex: 1, | ||
flex: 1 | ||
WebkitFlex: 1 | ||
} | ||
@@ -59,13 +51,69 @@ } | ||
Prefixer(styles, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36') | ||
const customUserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36' | ||
Prefixer(styles, customUserAgent) | ||
``` | ||
## How it works | ||
While installing it automatically searches the latest **caniuse.com data** for CSS properties and creates a data map sort by browsers. Those maps include pairs of properties and the maximum version that needs a prefix.<br> | ||
## Supported properties | ||
The following list shows all supported properties that get evaluated.<br> | ||
They are grouped in caniuse groups. | ||
Based on browser and browser version it then generates a list of properties that need to be prefixed. | ||
> Conclusion: It only adds prefixes that are really needed! | ||
* borderRadius | ||
* borderImage, borderImageOutset, borderImageRepeat, borderImageSlice, borderImageSource, borderImageWidth | ||
* flex, flexBasis, flexDirection, flexGrow, flexFlow, flexShrink, alignContent, alignItems, alignSelf, justifyContent, order | ||
* transition, transitionDelay, transitionDuration, transitionProperty, transitionTimingFunction | ||
* backfaceVisibility, perspective, perspectiveOrigin, transform, transformOrigin, transformStyle, transformOriginX, transformOriginY | ||
* animation, animationDelay, animationDirection, animationFillMode, animationDuration, anmationIterationCount, animationName, animationPlayState, animationTimingFunction | ||
* appearance | ||
* userSelect | ||
* backdropFilter | ||
* boxSizing | ||
* fontKerning | ||
* wrapFlow, wrapThrough, wrapMargin | ||
* scrollSnapType, scrollSnapPointsX, scrollSnapPointsY, scrollSnapDestination, scrollSnapCoordinate | ||
* textEmphasisPosition, textEmphasis, textEmphasisStyle, textEmphasisColor | ||
* textAlignLast | ||
* boxDecorationBreak | ||
* clipPath | ||
* maskImage, maskMode, maskRepeat, maskPosition, maskClip, maskOrigin, maskSize, maskComposite, mask, maskBorderSource, maskBorderMode, maskBorderSlice, maskBorderWidth, maskBorderOutset, maskBorderRepeat, maskBorder, maskType | ||
* touchAction | ||
* textSizeAdjust | ||
* textDecorationStyle, textDecorationSkip, textDecorationLine, textDecorationColor | ||
* shapeImageThreshold, shapeImageMargin, shapeImageOutside | ||
* tabSize | ||
* filter | ||
* resize | ||
* hyphens | ||
* flowInto, flowFrom, breakBefore, breakAfter, breakInside, regionFragment | ||
* gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridTemplate, gridAutoColumns, gridAutoRows, gridAutoFlow, grid, gridRowStart, gridColumnStart, gridRowEnd, gridRow, gridColumn, gridArea, rowGap, columnGap, gridGap | ||
* objectFit, objectPosition | ||
* textOverflow | ||
* backgroundClip, backgroundOrigin, backgroundSize | ||
* fontFeatureSettings | ||
* boxShadow | ||
* breakAfter, breakBefore, breakInside, columnCount, columnFill, columnGap, columnRule, columnRuleColor, columnRuleStyle, columnRuleWidth, columns, columnSpan, columnWidth | ||
## Special Plugins | ||
Sometimes it is not enough to just prefix a property, but you also need to prefix the value or even transform the value at all.<br> | ||
Therefore special plugins are used to tackle browser incompatibilities.<br> | ||
Right now there are 7 plugins. More might come if suggested. | ||
<br> | ||
* `calc`: Adds support for prefixed `calc` values on any property. | ||
* `cursor`: Adds support for prefixed new `cursor` values `zoom-in`, `zoom-out`, `grab`, `grabbing`. | ||
* `flex`: Adds support for prefixed `display` values using `display: flex` or `display: inline-flex`. | ||
* `flexboxIE`: Adds trasformators for the early 2012 flexbox specification used in IE 10 and IE Mobile 10. | ||
* `flexboxOld`: Adds trasformators for the old 2009 flexbox specification used in old Webkit-based browsers. | ||
* `gradient`: Adds support for prefixed `background` and `backgroundImage` values `linear-gradient`, `radial-gradient`, `repeating-linear-gradient` and `repeating-radial-gradient`. | ||
* `sizing`: Adds support for prefixed `maxHeight`, `maxWidth`, `width`, `height`, `columnWidth`,`minWidth`, `minHeight` intrinsic & extrinsic sizing values `min-content`, `max-content`, `fill-available`, `fit-content`, `contain-floats` | ||
# License | ||
**inline-style-prefixer** is licensed under the [MIT License](LICENSE).<br> | ||
Created with ♥ by [@rofrischmann](http://rofrischmann.de). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
35280
116
0
0
3
302
1
+ Addedobject-assign@^4.0.1
+ Addedobject-assign@4.1.1(transitive)