From 25f3cc0911abb23ab39261d2aecc7e179d905ac2 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Fri, 5 Jun 2015 16:41:15 +1000 Subject: [PATCH 1/8] added a test for the cssi format explicity --- test/cssi/interchange-format/colors.css | 7 +++++++ test/cssi/interchange-format/expected.css | 8 ++++++++ test/cssi/interchange-format/expected.json | 3 +++ test/cssi/interchange-format/source.css | 11 +++++++++++ 4 files changed, 29 insertions(+) create mode 100644 test/cssi/interchange-format/colors.css create mode 100644 test/cssi/interchange-format/expected.css create mode 100644 test/cssi/interchange-format/expected.json create mode 100644 test/cssi/interchange-format/source.css diff --git a/test/cssi/interchange-format/colors.css b/test/cssi/interchange-format/colors.css new file mode 100644 index 0000000..07e0229 --- /dev/null +++ b/test/cssi/interchange-format/colors.css @@ -0,0 +1,7 @@ +:export { + blackShadow: _single_import_export_source__localName; +} + +._single_import_export_colors__blackShadow { + box-shadow: 0 0 10px -2px black; +} diff --git a/test/cssi/interchange-format/expected.css b/test/cssi/interchange-format/expected.css new file mode 100644 index 0000000..81b058d --- /dev/null +++ b/test/cssi/interchange-format/expected.css @@ -0,0 +1,8 @@ + +._single_import_export_colors__blackShadow { + box-shadow: 0 0 10px -2px black; +} + +._single_import_export_source__localName { + color: red; +} diff --git a/test/cssi/interchange-format/expected.json b/test/cssi/interchange-format/expected.json new file mode 100644 index 0000000..35b62eb --- /dev/null +++ b/test/cssi/interchange-format/expected.json @@ -0,0 +1,3 @@ +{ + "localName": "_single_import_export_source__localName _single_import_export_colors__blackShadow" +} diff --git a/test/cssi/interchange-format/source.css b/test/cssi/interchange-format/source.css new file mode 100644 index 0000000..19d0f51 --- /dev/null +++ b/test/cssi/interchange-format/source.css @@ -0,0 +1,11 @@ +:imports("./colors.css") { + __tmp_import_djhgdsag: blackShadow; +} + +:exports { + localName: _single_import_export_source__localName __tmp_import_djhgdsag; +} + +._single_import_export_source__localName { + color: red; +} From 049d2d87fce71d1298ea37e46044a54fdd0f8aa2 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Fri, 5 Jun 2015 16:42:14 +1000 Subject: [PATCH 2/8] got that first test running --- src/file-system-loader.js | 5 +++-- src/index.js | 23 +++++++++++------------ test/test-cases.js | 37 ++++++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/file-system-loader.js b/src/file-system-loader.js index d2d9983..7afcef1 100644 --- a/src/file-system-loader.js +++ b/src/file-system-loader.js @@ -20,10 +20,11 @@ const traceKeySorter = ( a, b ) => { }; export default class FileSystemLoader { - constructor( root ) { + constructor( root, plugins ) { this.root = root this.sources = {} this.importNr = 0 + this.core = new Core(plugins) } fetch( _newPath, relativeTo, _trace ) { @@ -35,7 +36,7 @@ export default class FileSystemLoader { fs.readFile( fileRelativePath, "utf-8", ( err, source ) => { if ( err ) reject( err ) - Core.load( source, rootRelativePath, trace, this.fetch.bind( this ) ) + this.core.load( source, rootRelativePath, trace, this.fetch.bind( this ) ) .then( ( { injectableSource, exportTokens } ) => { this.sources[trace] = injectableSource resolve( exportTokens ) diff --git a/src/index.js b/src/index.js index a0dc57b..f5994ef 100644 --- a/src/index.js +++ b/src/index.js @@ -5,18 +5,10 @@ import scope from 'postcss-modules-scope' import Parser from './parser' -export default { - // These three plugins are aliased under this package for simplicity. - localByDefault, - extractImports, - scope, - - // The default set of plugins - plugins: [ - localByDefault, - extractImports, - scope - ], +export default class Core { + constructor( plugins ) { + this.plugins = plugins || Core.defaultPlugins + } load( sourceString, sourcePath, trace, pathFetcher ) { let parser = new Parser( pathFetcher, trace ) @@ -28,3 +20,10 @@ export default { } ) } } + + +// These three plugins are aliased under this package for simplicity. +Core.localByDefault = localByDefault +Core.extractImports = extractImports +Core.scope = scope +Core.defaultPlugins = [localByDefault, extractImports, scope] diff --git a/test/test-cases.js b/test/test-cases.js index 616c01b..a457e87 100644 --- a/test/test-cases.js +++ b/test/test-cases.js @@ -9,19 +9,26 @@ let normalize = ( str ) => { return str.replace( /\r\n?/g, "\n" ); } -describe( "test-cases", () => { - let testDir = path.join( __dirname, "test-cases" ) - fs.readdirSync( testDir ).forEach( testCase => { - if ( fs.existsSync( path.join( testDir, testCase, "source.css" ) ) ) { - it( "should " + testCase.replace( /-/g, " " ), done => { - let expected = normalize( fs.readFileSync( path.join( testDir, testCase, "expected.css" ), "utf-8" ) ) - let loader = new FileSystemLoader( testDir ) - let expectedTokens = JSON.parse( fs.readFileSync( path.join( testDir, testCase, "expected.json" ), "utf-8" ) ) - loader.fetch( `${testCase}/source.css`, "/" ).then( tokens => { - assert.equal( loader.finalSource, expected ) - assert.equal( JSON.stringify( tokens ), JSON.stringify( expectedTokens ) ) - } ).then( done, done ) - } ); - } +const pipelines = { + "test-cases": undefined, + "cssi": [] +} + +Object.keys( pipelines ).forEach( dirname => { + describe( dirname, () => { + let testDir = path.join( __dirname, dirname ) + fs.readdirSync( testDir ).forEach( testCase => { + if ( fs.existsSync( path.join( testDir, testCase, "source.css" ) ) ) { + it( "should " + testCase.replace( /-/g, " " ), done => { + let expected = normalize( fs.readFileSync( path.join( testDir, testCase, "expected.css" ), "utf-8" ) ) + let loader = new FileSystemLoader( testDir, pipelines[dirname] ) + let expectedTokens = JSON.parse( fs.readFileSync( path.join( testDir, testCase, "expected.json" ), "utf-8" ) ) + loader.fetch( `${testCase}/source.css`, "/" ).then( tokens => { + assert.equal( loader.finalSource, expected ) + assert.equal( JSON.stringify( tokens ), JSON.stringify( expectedTokens ) ) + } ).then( done, done ) + } ); + } + } ); } ); -} ); +} ) From 1b08b3e96cd738bf476290d47ce63a139974e150 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Fri, 5 Jun 2015 17:07:47 +1000 Subject: [PATCH 3/8] simple interchange format test passing --- test/cssi/interchange-format/expected.css | 2 -- test/cssi/interchange-format/expected.json | 2 +- test/cssi/interchange-format/source.css | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/cssi/interchange-format/expected.css b/test/cssi/interchange-format/expected.css index 81b058d..7dac9a4 100644 --- a/test/cssi/interchange-format/expected.css +++ b/test/cssi/interchange-format/expected.css @@ -1,8 +1,6 @@ - ._single_import_export_colors__blackShadow { box-shadow: 0 0 10px -2px black; } - ._single_import_export_source__localName { color: red; } diff --git a/test/cssi/interchange-format/expected.json b/test/cssi/interchange-format/expected.json index 35b62eb..a12c901 100644 --- a/test/cssi/interchange-format/expected.json +++ b/test/cssi/interchange-format/expected.json @@ -1,3 +1,3 @@ { - "localName": "_single_import_export_source__localName _single_import_export_colors__blackShadow" + "localName": "_single_import_export_source__localName __tmp_import_djhgdsag" } diff --git a/test/cssi/interchange-format/source.css b/test/cssi/interchange-format/source.css index 19d0f51..ae44e5e 100644 --- a/test/cssi/interchange-format/source.css +++ b/test/cssi/interchange-format/source.css @@ -1,8 +1,8 @@ -:imports("./colors.css") { +:import("./colors.css") { __tmp_import_djhgdsag: blackShadow; } -:exports { +:export { localName: _single_import_export_source__localName __tmp_import_djhgdsag; } From 84c37f03c38db3754396088af40810675404b949 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Sun, 7 Jun 2015 13:07:03 +1000 Subject: [PATCH 4/8] got replacement working in the CSSI tests, breaks the others --- src/parser.js | 11 ++++++++++- test/cssi/interchange-format/colors.css | 4 ++-- test/cssi/interchange-format/expected.css | 4 ++-- test/cssi/interchange-format/expected.json | 2 +- test/cssi/interchange-format/source.css | 6 +++--- test/cssi/pseudo-variables/colors.css | 4 ++++ test/cssi/pseudo-variables/expected.css | 5 +++++ test/cssi/pseudo-variables/expected.json | 3 +++ test/cssi/pseudo-variables/source.css | 13 +++++++++++++ 9 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 test/cssi/pseudo-variables/colors.css create mode 100644 test/cssi/pseudo-variables/expected.css create mode 100644 test/cssi/pseudo-variables/expected.json create mode 100644 test/cssi/pseudo-variables/source.css diff --git a/src/parser.js b/src/parser.js index e28f199..536e9cd 100644 --- a/src/parser.js +++ b/src/parser.js @@ -11,6 +11,7 @@ export default class Parser { plugin( css, result ) { return Promise.all( this.fetchAllImports( css ) ) + .then( _ => this.linkImportedSymbols( css ) ) .then( _ => this.extractExports( css ) ) } @@ -24,6 +25,14 @@ export default class Parser { return imports } + linkImportedSymbols( css ) { + css.eachDecl( decl => { + Object.keys(this.translations).forEach( translation => { + decl.value = decl.value.replace(translation, this.translations[translation]) + } ) + }) + } + extractExports( css ) { css.each( node => { if ( node.type == "rule" && node.selector == ":export" ) this.handleExport( node ) @@ -48,7 +57,7 @@ export default class Parser { return this.pathFetcher( file, relativeTo, depTrace ).then( exports => { importNode.each( decl => { if ( decl.type == 'decl' ) { - this.translations[decl.value] = exports[decl.prop] + this.translations[decl.prop] = exports[decl.value] } } ) importNode.removeSelf() diff --git a/test/cssi/interchange-format/colors.css b/test/cssi/interchange-format/colors.css index 07e0229..4057aae 100644 --- a/test/cssi/interchange-format/colors.css +++ b/test/cssi/interchange-format/colors.css @@ -1,7 +1,7 @@ :export { - blackShadow: _single_import_export_source__localName; + blackShadow: x__single_import_export_colors__blackShadow; } -._single_import_export_colors__blackShadow { +.x__single_import_export_colors__blackShadow { box-shadow: 0 0 10px -2px black; } diff --git a/test/cssi/interchange-format/expected.css b/test/cssi/interchange-format/expected.css index 7dac9a4..36f1092 100644 --- a/test/cssi/interchange-format/expected.css +++ b/test/cssi/interchange-format/expected.css @@ -1,6 +1,6 @@ -._single_import_export_colors__blackShadow { +.x__single_import_export_colors__blackShadow { box-shadow: 0 0 10px -2px black; } -._single_import_export_source__localName { +.x__single_import_export_source__localName { color: red; } diff --git a/test/cssi/interchange-format/expected.json b/test/cssi/interchange-format/expected.json index a12c901..43311c7 100644 --- a/test/cssi/interchange-format/expected.json +++ b/test/cssi/interchange-format/expected.json @@ -1,3 +1,3 @@ { - "localName": "_single_import_export_source__localName __tmp_import_djhgdsag" + "localName": "x__single_import_export_source__localName x__single_import_export_colors__blackShadow" } diff --git a/test/cssi/interchange-format/source.css b/test/cssi/interchange-format/source.css index ae44e5e..d7125a0 100644 --- a/test/cssi/interchange-format/source.css +++ b/test/cssi/interchange-format/source.css @@ -1,11 +1,11 @@ :import("./colors.css") { - __tmp_import_djhgdsag: blackShadow; + i__tmp_import_djhgdsag: blackShadow; } :export { - localName: _single_import_export_source__localName __tmp_import_djhgdsag; + localName: x__single_import_export_source__localName i__tmp_import_djhgdsag; } -._single_import_export_source__localName { +.x__single_import_export_source__localName { color: red; } diff --git a/test/cssi/pseudo-variables/colors.css b/test/cssi/pseudo-variables/colors.css new file mode 100644 index 0000000..3ac72d9 --- /dev/null +++ b/test/cssi/pseudo-variables/colors.css @@ -0,0 +1,4 @@ +:export { + black: #222; + white: #ddd; +} diff --git a/test/cssi/pseudo-variables/expected.css b/test/cssi/pseudo-variables/expected.css new file mode 100644 index 0000000..371497c --- /dev/null +++ b/test/cssi/pseudo-variables/expected.css @@ -0,0 +1,5 @@ + +.x__lol { + color: #222; + background: #ddd; +} diff --git a/test/cssi/pseudo-variables/expected.json b/test/cssi/pseudo-variables/expected.json new file mode 100644 index 0000000..b8c3c23 --- /dev/null +++ b/test/cssi/pseudo-variables/expected.json @@ -0,0 +1,3 @@ +{ + "lol": "x__lol" +} diff --git a/test/cssi/pseudo-variables/source.css b/test/cssi/pseudo-variables/source.css new file mode 100644 index 0000000..cc4b95a --- /dev/null +++ b/test/cssi/pseudo-variables/source.css @@ -0,0 +1,13 @@ +:import("./colors.css") { + i__black: black; + i__white: white; +} + +:export { + lol: x__lol; +} + +.x__lol { + color: i__black; + background: i__white; +} From c60dba6838da9f11c892e97ecd60e2bffbdd38ee Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Sun, 7 Jun 2015 13:36:06 +1000 Subject: [PATCH 5/8] pulling in new extract-importer --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a4ff9e7..5740dfb 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ }, "dependencies": { "postcss": "^4.1.11", - "postcss-modules-extract-imports": "0.0.2", - "postcss-modules-local-by-default": "0.0.7", - "postcss-modules-scope": "0.0.4" + "postcss-modules-extract-imports": "0.0.3", + "postcss-modules-local-by-default": "^0.0.7", + "postcss-modules-scope": "^0.0.4" }, "devDependencies": { - "babel": "^5.4.7", - "babel-eslint": "^3.1.11", + "babel": "^5.5.4", + "babel-eslint": "^3.1.14", "babelify": "^6.1.2", "chokidar-cli": "^0.2.1", "eslint": "^0.22.1", From a578d0e44270be94798d106334622d631552d98e Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Sun, 7 Jun 2015 14:00:26 +1000 Subject: [PATCH 6/8] brought in latest postcss-modules-scope --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5740dfb..3ff1f53 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "postcss": "^4.1.11", "postcss-modules-extract-imports": "0.0.3", "postcss-modules-local-by-default": "^0.0.7", - "postcss-modules-scope": "^0.0.4" + "postcss-modules-scope": "^0.0.5" }, "devDependencies": { "babel": "^5.5.4", From 8ea4b6e2263dee56c9d7cdc5d22275b604f7d213 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Sun, 7 Jun 2015 14:00:55 +1000 Subject: [PATCH 7/8] changing extends to composes and everything is passing! --- test/test-cases/multiple-dependencies/b.css | 2 +- test/test-cases/multiple-dependencies/source.css | 4 ++-- test/test-cases/single-import-export/source.css | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test-cases/multiple-dependencies/b.css b/test/test-cases/multiple-dependencies/b.css index 859eda9..c4dcd92 100644 --- a/test/test-cases/multiple-dependencies/b.css +++ b/test/test-cases/multiple-dependencies/b.css @@ -1,4 +1,4 @@ .b { - extends: d from "./d.css"; + composes: d from "./d.css"; color: #bbb; } diff --git a/test/test-cases/multiple-dependencies/source.css b/test/test-cases/multiple-dependencies/source.css index 72e7221..ee0c9d9 100644 --- a/test/test-cases/multiple-dependencies/source.css +++ b/test/test-cases/multiple-dependencies/source.css @@ -1,6 +1,6 @@ .a { - extends: b from "./b.css"; - extends: c from "./c.css"; + composes: b from "./b.css"; + composes: c from "./c.css"; color: #aaa; } diff --git a/test/test-cases/single-import-export/source.css b/test/test-cases/single-import-export/source.css index 2b196fb..e2df5ca 100644 --- a/test/test-cases/single-import-export/source.css +++ b/test/test-cases/single-import-export/source.css @@ -1,4 +1,4 @@ .localName { - extends: blackShadow from "./colors.css"; + composes: blackShadow from "./colors.css"; color: red; } From b19de0b9dcc5f9edf45b547c8125d703e198984e Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Sun, 7 Jun 2015 14:02:48 +1000 Subject: [PATCH 8/8] updating readme --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8bc5622..9b47dc5 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ ## API +```js +import Core from 'css-modules-loader-core' +let core = new Core() +``` + ### core.load( sourceString , sourcePath , pathFetcher ) =>
  Promise({ injectableSource, exportTokens }) Processes the input CSS `sourceString`, looking for dependencies such as `@import` or `:import`. Any localisation will happen by prefixing a sanitised version of `sourcePath` When dependencies are found, it will ask the `pathFetcher` for each dependency, resolve & inline any imports, and return the following object: @@ -12,22 +17,21 @@ Processes the input CSS `sourceString`, looking for dependencies such as `@impor These should map nicely to what your build-tool-specific loader needs to do its job. -### core.plugins = pluginArray +### new Core([plugins]) The default set of plugins is [[postcss-modules-local-by-default](https://github.com/css-modules/postcss-modules-local-by-default), [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports), [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope)] (i.e. the CSS Modules specification). This can override which PostCSS plugins you wish to execute, e.g. ```js -import core from 'css-loader-core' +import Core from 'css-loader-core' import autoprefixer from 'autoprefixer' import colorFunctions from 'postcss-color-function' // Don't run local-by-default, but use colorFunctions // beforehand and autoprefixer afterwards: -core.plugins = [ +let core = new Core([ colorFunctions, core.plugins.extractImports, core.plugins.scope, autoprefixer("Last 2 Versions") -] +]) ``` -