Skip to content

Commit 15e02a4

Browse files
committed
Basic support for css preprocessing. No support for async preprocessing and multiple <style> tags
Suggestion for sveltejs#181 and sveltejs#876
1 parent be0837e commit 15e02a4

File tree

19 files changed

+391
-42
lines changed

19 files changed

+391
-42
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ The Svelte compiler optionally takes a second argument, an object of configurati
9090
| | | |
9191
| `onerror` | `function` | Specify a callback for when Svelte encounters an error while compiling the component. Passed two arguments: the error object, and another function that is Svelte's default onerror handling. | (exception is thrown) |
9292
| `onwarn` | `function` | Specify a callback for when Svelte encounters a non-fatal warning while compiling the component. Passed two arguments: the warning object, and another function that is Svelte's default onwarn handling. | (warning is logged to console) |
93+
| `preprocessor` | `function`, `false` | Specify a `function` to **synchronously** preprocess the contents of the component's inline styles. It does not support async functions and components with multiple `<style>` tags.| `false` |
9394

9495
## Example/starter repos
9596

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"mocha": "^3.2.0",
5959
"nightmare": "^2.10.0",
6060
"node-resolve": "^1.3.3",
61+
"node-sass": "^4.7.1",
6162
"nyc": "^11.1.0",
6263
"prettier": "^1.7.0",
6364
"rollup": "^0.48.2",
@@ -70,6 +71,7 @@
7071
"rollup-watch": "^4.3.1",
7172
"source-map": "^0.5.6",
7273
"source-map-support": "^0.4.8",
74+
"stylus": "^0.54.5",
7375
"tslib": "^1.8.0",
7476
"typescript": "^2.3.2"
7577
},

src/index.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Stylesheet from './css/Stylesheet';
88
import { Parsed, CompileOptions, Warning } from './interfaces';
99

1010
function normalizeOptions(options: CompileOptions): CompileOptions {
11-
let normalizedOptions = assign({ generate: 'dom' }, options);
11+
let normalizedOptions = assign({ generate: 'dom', preprocessor: false }, options);
1212
const { onwarn, onerror } = normalizedOptions;
1313
normalizedOptions.onwarn = onwarn
1414
? (warning: Warning) => onwarn(warning, defaultOnwarn)
@@ -33,9 +33,24 @@ function defaultOnerror(error: Error) {
3333
throw error;
3434
}
3535

36-
export function compile(source: string, _options: CompileOptions) {
37-
const options = normalizeOptions(_options);
36+
function preprocess(compile: Function) {
37+
return (source: string, _options: CompileOptions) => {
38+
const options = normalizeOptions(_options);
39+
const preprocessor: ((raw: string) => string) | boolean = options.preprocessor;
3840

41+
const match = /<style[\S\s]*?>([\S\s]*?)<\/style>/ig.exec(source);
42+
if (match) {
43+
if (!!preprocessor) {
44+
const styles: string = match[1];
45+
const processed: string = preprocessor(styles);
46+
source = source.replace(styles, processed);
47+
}
48+
}
49+
return compile(source, options);
50+
}
51+
}
52+
53+
export const compile = preprocess((source: string, options: CompileOptions) => {
3954
let parsed: Parsed;
4055

4156
try {
@@ -52,7 +67,7 @@ export function compile(source: string, _options: CompileOptions) {
5267
const compiler = options.generate === 'ssr' ? generateSSR : generate;
5368

5469
return compiler(parsed, source, stylesheet, options);
55-
}
70+
});
5671

5772
export function create(source: string, _options: CompileOptions = {}) {
5873
_options.format = 'eval';

src/interfaces.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export interface CompileOptions {
5959

6060
onerror?: (error: Error) => void;
6161
onwarn?: (warning: Warning) => void;
62+
preprocessor?: ((raw: string) => string) | false ;
6263
}
6364

6465
export interface GenerateOptions {
@@ -77,4 +78,4 @@ export interface Visitor {
7778
export interface CustomElementOptions {
7879
tag?: string;
7980
props?: string[];
80-
}
81+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as sass from 'node-sass';
2+
import * as path from 'path';
3+
4+
export default {
5+
preprocessor: (styles) => sass.renderSync({
6+
data: styles,
7+
includePaths: [
8+
path.resolve(__dirname)
9+
]
10+
}).css.toString(),
11+
cascade: false,
12+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
$foo-color: red;
2+
$baz-color: blue;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<div foo='bar'></div>
2+
<div baz></div>
3+
4+
<style type="text/scss">
5+
@import 'variables';
6+
7+
[foo] {
8+
color: $foo-color;
9+
}
10+
[baz] {
11+
color: $baz-color;
12+
}
13+
</style>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as sass from 'node-sass';
2+
3+
export default {
4+
preprocessor: (styles) => sass.renderSync({data: styles}).css.toString(),
5+
cascade: false,
6+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div foo='bar'></div>
2+
<div baz></div>
3+
4+
<style type="text/scss">
5+
$foo-color: red;
6+
$baz-color: blue;
7+
8+
[foo] {
9+
color: $foo-color;
10+
}
11+
[baz] {
12+
color: $baz-color;
13+
}
14+
</style>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as stylus from 'stylus';
2+
import * as path from 'path';
3+
4+
export default {
5+
preprocessor: (styles) =>
6+
stylus(styles).include(path.resolve(__dirname)).render(),
7+
cascade: false,
8+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div foo='bar'></div>
2+
<div baz></div>
3+
4+
<style type="text/stylus">
5+
@import 'variables.styl'
6+
7+
[foo]
8+
color foo-color
9+
[baz]
10+
color baz-color
11+
12+
</style>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
foo-color = red
2+
baz-color = blue
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as stylus from 'stylus';
2+
3+
export default {
4+
preprocessor: (styles) => stylus(styles).render(),
5+
cascade: false,
6+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<div foo='bar'></div>
2+
<div baz></div>
3+
4+
<style type="text/stylus">
5+
foo-color = red
6+
baz-color = blue
7+
8+
[foo]
9+
color foo-color
10+
[baz]
11+
color baz-color
12+
13+
</style>

0 commit comments

Comments
 (0)