8000 Support new webpack features and internalize CSS functions. · bootstarted/css-js-loader@fc5ae47 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit fc5ae47

Browse files
Support new webpack features and internalize CSS functions.
Support for `value-loader` has been added by checking to see if the source is an object instead of a string – this allows for a bunch of nice things (caching, support for `modules: false` in babel, nested dependency resolution, etc.) because `value-loader` spawns a child compiler that runs the full webpack process. We also update several packages here (lint, etc.) because why not. The internal react functions have been moved into the repo to remove the react dependency. This means you won't pull two versions of react into your project and get weird peer dependency warnings.
1 parent e0f13fd commit fc5ae47

File tree

10< 8000 !-- --> files changed

+4456
-1147
lines changed

10 files changed

+4456
-1147
lines changed

.eslintrc

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
{
2-
"extends": [
3-
"metalab/legacy",
4-
"metalab/node"
5-
],
6-
"rules": {
7-
"func-style": 0,
8-
"no-extra-semi": 0,
9-
"no-param-reassign": 0,
10-
"vars-on-top": 0,
11-
"max-len": 0,
12-
"import/no-commonjs": 0,
13-
"no-undef": 0,
14-
"no-unused-vars": 0,
15-
"space-before-function-paren": 0
16-
}
17-
}
1+
extends:
2+
- metalab/legacy
3+
env:
4+
node: true
5+
rules:
6+
vars-on-top: 0
7+
no-param-reassign: 0
8+

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Write your styles with in JavsScript.
1313
Install:
1414

1515
```sh
16-
yarn add css-js-loader
16+
npm install css-js-loader value-loader
1717
```
1818

1919
Add to your `webpack.config.js`:
@@ -27,15 +27,17 @@ module.exports = {
2727
loaders: ['style-loader', 'css-loader'],
2828
}, {
2929
test: /\.css\.js$/,
30-
loader: 'css-js-loader',
30+
loaders: ['css-js-loader', 'value-loader'],
3131
}],
3232
},
3333
};
3434
```
3535

36+
NOTE: You don't need to chain with [value-loader] per-se, but doing so gives you caching, nested dependency monitoring/reloading and the ability to use webpack's module rollup.
37+
3638
## Writing JS Styles
3739

38-
`css-js-loader` converts JS modules to CSS markup at runtime.
40+
`css-js-loader` converts JS modules to CSS markup at runtime.
3941

4042
A `.css.js` file:
4143

@@ -104,3 +106,4 @@ export default () =>
104106
```
105107

106108
[CSS Modules]: https://github.com/webpack-contrib/css-loader#css-modules
109+
[value-loader]: https://www.npmjs.com/package/value-loader

index.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ var omit = require('lodash/omit');
55
var isString = require('lodash/isString');
66
var isNumber = require('lodash/isNumber');
77
var loaderUtils = require('loader-utils');
8-
var dangerousStyleValue = require('react-dom/lib/dangerousStyleValue');
8+
var dangerousStyleValue = require('./internal/dangerousStyleValue');
99
var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');
1010

1111
function indent(pretty, depth) {
1212
return pretty ? Array(depth).join(' ') : '';
13-
};
13+
}
1414

1515
function space(pretty) {
1616
return pretty ? ' ' : '';
17-
};
17+
}
1818

1919
function line(pretty) {
2020
return pretty ? '\n' : '';
@@ -44,7 +44,9 @@ function format(config, value, name, level, inProp) {
4444
// The `name` and `value` args currently represent a css property and value.
4545
// Use React's css style processing funcs to generate css markup.
4646

47-
css += indent(pretty, indentLevel) + hyphenateStyleName(name) + ':' + space(pretty);
47+
css += indent(pretty, indentLevel) +
48+
hyphenateStyleName(name) + ':' +
49+
space(pretty);
4850
css += dangerousStyleValue(name, value) + ';' + line(pretty);
4951
} else {
5052
// The `name` and `value` args currently represent a block containing css
@@ -54,7 +56,8 @@ function format(config, value, name, level, inProp) {
5456
if (name) {
5557
// Unless we are in the global css scope (`name` is undefined), add a new
5658
// block to the markup.
57-
css += indent(pretty, indentLevel) + name + space(pretty) + '{' + line(pretty);
59+
css += indent(pretty, indentLevel) + name + space(pretty) + '{' +
60+
line(pretty);
5861
indentLevel += 1;
5962
}
6063

@@ -91,14 +94,13 @@ function format(config, value, name, level, inProp) {
9194
module.exports = function(content) {
9295
this.cacheable();
9396

94-
config = defaults(
95-
loaderUtils.getLoaderConfig(this, 'jsCssLoader'),
97+
var config = defaults(
98+
loaderUtils.getOptions(this),
9699
{pretty: process.env.NODE_ENV !== 'production'}
97100
);
98101

99-
var styles = this.exec(content, this.resourcePath);
100-
101-
var css = '';
102+
var styles = typeof content === 'object' ? content :
103+
this.exec(content, this.resourcePath);
102104

103105
if (styles.__esModule) {
104106
// When using Babel, css classes can be defined as named es6 exports.
@@ -123,7 +125,7 @@ module.exports = function(content) {
123125
return format(config, [
124126
mapKeys(
125127
omit(styles, 'default'),
126-
function (value, key) {
128+
function(value, key) {
127129
return '.' + key;
128130
}
129131
),

internal/CSSProperty.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @providesModule CSSProperty
8+
*/
9+
10+
'use strict';
11+
12+
/**
13+
* CSS properties which accept numbers but are not in units of "px".
14+
*/
15+
var isUnitlessNumber = {
16+
animationIterationCount: true,
17+
borderImageOutset: true,
18+
borderImageSlice: true,
19+
borderImageWidth: true,
20+
boxFlex: true,
21+
boxFlexGroup: true,
22+
boxOrdinalGroup: true,
23+
columnCount: true,
24+
columns: true,
25+
flex: true,
26+
flexGrow: true,
27+
flexPositive: true,
28+
flexShrink: true,
29+
flexNegative: true,
30+
flexOrder: true,
31+
gridRow: true,
32+
gridRowEnd: true,
33+
gridRowSpan: true,
34+
gridRowStart: true,
35+
gridColumn: true,
36+
gridColumnEnd: true,
37+
gridColumnSpan: true,
38+
gridColumnStart: true,
39+
fontWeight: true,
40+
lineClamp: true,
41+
lineHeight: true,
42+
opacity: true,
43+
order: true,
44+
orphans: true,
45+
tabSize: true,
46+
widows: true,
47+
zIndex: true,
48+
zoom: true,
49+
50+
// SVG-related properties
51+
fillOpacity: true,
52+
floodOpacity: true,
53+
stopOpacity: true,
54+
strokeDasharray: true,
55+
strokeDashoffset: true,
56+
strokeMiterlimit: true,
57+
strokeOpacity: true,
58+
strokeWidth: true,
59+
};
60+
61+
/**
62+
* @param {string} prefix vendor-specific prefix, eg: Webkit
63+
* @param {string} key style name, eg: transitionDuration
64+
* @returns {string} style name prefixed with `prefix`, properly camelCased, eg:
65+
* WebkitTransitionDuration
66+
*/
67+
function prefixKey(prefix, key) {
68+
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
69+
}
70+
71+
/**
72+
* Support style names that may come passed in prefixed by adding permutations
73+
* of vendor prefixes.
74+
*/
75+
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
76+
77+
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
78+
// infinite loop, because it iterates over the newly added props too.
79+
Object.keys(isUnitlessNumber).forEach(function(prop) {
80+
prefixes.forEach(function(prefix) {
81+
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
82+
});
83+
});
84+
85+
var CSSProperty = {
86+
isUnitlessNumber: isUnitlessNumber,
87+
};
88+
89+
module.exports = CSSProperty;

internal/dangerousStyleValue.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @providesModule dangerousStyleValue
8+
*/
9+
10+
'use strict';
11+
12+
var CSSProperty = require('./CSSProperty');
13+
14+
var isUnitlessNumber = CSSProperty.isUnitlessNumber;
15+
16+
/**
17+
* Convert a value into the proper css writable value. The style name `name`
18+
* should be logical (no hyphens), as specified
19+
* in `CSSProperty.isUnitlessNumber`.
20+
*
21+
* @param {string} name CSS property name such as `topMargin`.
22+
* @param {*} value CSS property value such as `10px`.
23+
* @param {boolean} isCustomProperty Is it custom
24+
* @returns {string} Normalized style value with dimensions applied.
25+
*/
26+
function dangerousStyleValue(name, value, isCustomProperty) {
27+
// Note that we've removed escapeTextForBrowser() calls here since the
28+
// whole string will be escaped when the attribute is injected into
29+
// the markup. If you provide unsafe user data here they can inject
30+
// arbitrary CSS which may be problematic (I couldn't repro this):
31+
// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
32+
// http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
33+
// This is not an XSS hole but instead a potential CSS injection issue
34+
// which has lead to a greater discussion about how we're going to
35+
// trust URLs moving forward. See #2115901
36+
37+
var isEmpty = value === null || typeof value === 'boolean' || value === '';
38+
if (isEmpty) {
39+
return '';
40+
}
41+
42+
if (
43+
!isCustomProperty &&
44+
typeof value === 'number' &&
45+
value !== 0 &&
46+
!(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])
47+
) {
48+
return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
49+
}
50+
51+
return ('' + value).trim();
52+
}
53+
54+
module.exports = dangerousStyleValue;

0 commit comments

Comments
 (0)
0