parser.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _icssReplaceSymbols = require("icss-replace-symbols");
  6. var _icssReplaceSymbols2 = _interopRequireDefault(_icssReplaceSymbols);
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. // Copied from https://github.com/css-modules/css-modules-loader-core
  9. const importRegexp = /^:import\((.+)\)$/;
  10. class Parser {
  11. constructor(pathFetcher, trace) {
  12. this.pathFetcher = pathFetcher;
  13. this.plugin = this.plugin.bind(this);
  14. this.exportTokens = {};
  15. this.translations = {};
  16. this.trace = trace;
  17. }
  18. plugin(css) {
  19. return Promise.all(this.fetchAllImports(css)).then(() => this.linkImportedSymbols(css)).then(() => this.extractExports(css));
  20. }
  21. fetchAllImports(css) {
  22. let imports = [];
  23. css.each(node => {
  24. if (node.type == "rule" && node.selector.match(importRegexp)) {
  25. imports.push(this.fetchImport(node, css.source.input.from, imports.length));
  26. }
  27. });
  28. return imports;
  29. }
  30. linkImportedSymbols(css) {
  31. (0, _icssReplaceSymbols2.default)(css, this.translations);
  32. }
  33. extractExports(css) {
  34. css.each(node => {
  35. if (node.type == "rule" && node.selector == ":export") this.handleExport(node);
  36. });
  37. }
  38. handleExport(exportNode) {
  39. exportNode.each(decl => {
  40. if (decl.type == "decl") {
  41. Object.keys(this.translations).forEach(translation => {
  42. decl.value = decl.value.replace(translation, this.translations[translation]);
  43. });
  44. this.exportTokens[decl.prop] = decl.value;
  45. }
  46. });
  47. exportNode.remove();
  48. }
  49. fetchImport(importNode, relativeTo, depNr) {
  50. let file = importNode.selector.match(importRegexp)[1],
  51. depTrace = this.trace + String.fromCharCode(depNr);
  52. return this.pathFetcher(file, relativeTo, depTrace).then(exports => {
  53. importNode.each(decl => {
  54. if (decl.type == "decl") {
  55. this.translations[decl.prop] = exports[decl.value];
  56. }
  57. });
  58. importNode.remove();
  59. }, err => console.log(err));
  60. }
  61. }
  62. exports.default = Parser;