<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta charset="utf-8" />
  <title>CSS Module JSPM Fork</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
</head>

<body>

  <main id="outlet"></main>
  <script src="https://jspm.io/system@0.16.11.src.js"></script>
  <script src="jspm.config.js"></script>
  <script>
    System.import('src/main');
  </script>

</body>

</html>
# CSS Module JSPM Fork

Extracted from https://github.com/geelen/jspm-loader-css
/* global System */

System.config({
  
  "transpiler": "babel",
  "babelOptions": {
    "stage": 0,
    "optional": [
      "runtime"
    ]
  }
  
});

System.config({
  
  "paths": {
    "*": "*.js",
    "github:*": "https://github.jspm.io/*.js",
    "npm:css-modules-loader-core": "css/index",
    "npm:*": "https://npm.jspm.io/*.js"
  }
  
});

System.config({
  
  "map": {
    //"css": "npm:css-modules-loader-core@0.0.11",
    "angular2": "npm:angular2@2.0.0-alpha.28",
    "babel": "npm:babel-core@5.6.7",
    "babel-runtime": "npm:babel-runtime@5.6.7",
    "core-js": "npm:core-js@0.9.17",
    
    "amdefine": "npm:amdefine@0.1.1",
    "css-modules-loader-core": "npm:css-modules-loader-core@0.0.11",
    "path": "npm:path@0.11.14",
    "toposort": "npm:toposort@0.2.10",
    "debounce": "npm:debounce@1.0.0",
    "process": "npm:process@0.10.1"
  }
  
});

import theAstyles from './a0.css!';
import theBstyles from './b0.css!';

const styles = {
  ...theAstyles,
  ...theBstyles
};

document.querySelector('main#outlet').innerHTML = `
  <div class="${styles.a}">A0 style</div>
  <div class="${styles.b}">B0 style</div>
`;
.a {
  composes: a from "./a1.css";
  border: 1px solid red;
}
.b {
  composes: b from "./b1.css";
  composes: c from "./c1.css";
  font-size: 1.5rem;
}
//

import Core from 'css-modules-loader-core';
import path from 'path';
import debounce from 'debounce';
import toposort from 'toposort';

const cssModulesLoder = new Core();
const stylesDependencyTree = new Set();
const stylesDependencies = new Set();
const styleMeta = new Map();

const head = document.getElementsByTagName('head')[0];
const jspmCssModulesContainer = document.createElement('jspm-css-modules');
const debouncedSortingAndInject = debounce(sortAndInjectInDom, 500);

head.appendChild(jspmCssModulesContainer);

export function fetch(load, fetch){

  const sourcePath =  load.metadata.pluginArgument;

  const styleSheet = {
    name: sourcePath,
    injectableSource: null,
    exportedTokens: null
  };
  stylesDependencies.add(sourcePath);
  styleMeta.set(sourcePath, styleSheet);

  return fetch(load)
  .then((source) => cssModulesLoder.load(source, sourcePath, '', fetchDependencies))
  .then(({ injectableSource, exportTokens }) => {
    styleSheet.exportedTokens = styleExportModule(exportTokens)
    styleSheet.injectableSource = injectableSource
  })
  // Debounce dep sorting and injection in the DOM
  .then(debouncedSortingAndInject)
  // Return the export tokens to the js files
  .then(() => styleSheet.exportedTokens);

};


function styleExportModule(exportTokens){
  return `
  export default ${JSON.stringify( exportTokens )}
  `;
}

function fetchDependencies( _newPath, relativeTo ){
  // Figure out the path that System will need to find the right file,
  // and trigger the import (which will instantiate this loader once more)
  let newPath = _newPath.replace( /^["']|["']$/g, "" ),
    canonicalPath = path.resolve( path.dirname( relativeTo ), newPath ).replace( /^\//, '' ),
    canonicalParent = relativeTo.replace( /^\//, '' )

  stylesDependencyTree.add([canonicalParent, canonicalPath]);

  return System.normalize(newPath, canonicalParent)
    .then((normalizedLocation) => System.import( `${normalizedLocation}!${__moduleName}` ))
    .then((exportedTokens) => exportedTokens.default || exportedTokens);
}


function sortAndInjectInDom(){

  const sortedDependencies =
    toposort.array(
      Array.from(stylesDependencies),
      Array.from(stylesDependencyTree)
    )
    .reverse();

  jspmCssModulesContainer.innerHTML = sortedDependencies
    .map((depName) => `<style>${styleMeta.get(depName).injectableSource}</style>`)
    .join('')
  ;

}
.a {
  composes: a from "./a3.css";
  font-size: 2rem;
}
.b {
  font-size: 5rem;
}
.c {
  composes: a from "./a2.css";
  border: 1px solid red;
}
.a {
  composes: a from "./a3.css";
  font-size: 9rem;
}

.a {
  background: green; 
}