conventions.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Gengkun He @ahabhgk
  4. */
  5. "use strict";
  6. /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
  7. /**
  8. * @param {string} input input
  9. * @param {CssGeneratorExportsConvention | undefined} convention convention
  10. * @returns {string[]} results
  11. */
  12. exports.cssExportConvention = (input, convention) => {
  13. const set = new Set();
  14. if (typeof convention === "function") {
  15. set.add(convention(input));
  16. } else {
  17. switch (convention) {
  18. case "camel-case": {
  19. set.add(input);
  20. set.add(exports.camelCase(input));
  21. break;
  22. }
  23. case "camel-case-only": {
  24. set.add(exports.camelCase(input));
  25. break;
  26. }
  27. case "dashes": {
  28. set.add(input);
  29. set.add(exports.dashesCamelCase(input));
  30. break;
  31. }
  32. case "dashes-only": {
  33. set.add(exports.dashesCamelCase(input));
  34. break;
  35. }
  36. case "as-is": {
  37. set.add(input);
  38. break;
  39. }
  40. }
  41. }
  42. return Array.from(set);
  43. };
  44. // Copy from css-loader
  45. /**
  46. * @param {string} input input
  47. * @returns {string} result
  48. */
  49. exports.dashesCamelCase = input => {
  50. return input.replace(/-+(\w)/g, (match, firstLetter) =>
  51. firstLetter.toUpperCase()
  52. );
  53. };
  54. // Copy from css-loader
  55. /**
  56. * @param {string} input input
  57. * @returns {string} result
  58. */
  59. exports.camelCase = input => {
  60. let result = input.trim();
  61. if (result.length === 0) {
  62. return "";
  63. }
  64. if (result.length === 1) {
  65. return result.toLowerCase();
  66. }
  67. const hasUpperCase = result !== result.toLowerCase();
  68. if (hasUpperCase) {
  69. result = preserveCamelCase(result);
  70. }
  71. return result
  72. .replace(/^[_.\- ]+/, "")
  73. .toLowerCase()
  74. .replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toUpperCase())
  75. .replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toUpperCase());
  76. };
  77. // Copy from css-loader
  78. /**
  79. * @param {string} string string
  80. * @returns {string} result
  81. */
  82. const preserveCamelCase = string => {
  83. let result = string;
  84. let isLastCharLower = false;
  85. let isLastCharUpper = false;
  86. let isLastLastCharUpper = false;
  87. for (let i = 0; i < result.length; i++) {
  88. const character = result[i];
  89. if (isLastCharLower && /[\p{Lu}]/u.test(character)) {
  90. result = `${result.slice(0, i)}-${result.slice(i)}`;
  91. isLastCharLower = false;
  92. isLastLastCharUpper = isLastCharUpper;
  93. isLastCharUpper = true;
  94. i += 1;
  95. } else if (
  96. isLastCharUpper &&
  97. isLastLastCharUpper &&
  98. /[\p{Ll}]/u.test(character)
  99. ) {
  100. result = `${result.slice(0, i - 1)}-${result.slice(i - 1)}`;
  101. isLastLastCharUpper = isLastCharUpper;
  102. isLastCharUpper = false;
  103. isLastCharLower = true;
  104. } else {
  105. isLastCharLower =
  106. character.toLowerCase() === character &&
  107. character.toUpperCase() !== character;
  108. isLastLastCharUpper = isLastCharUpper;
  109. isLastCharUpper =
  110. character.toUpperCase() === character &&
  111. character.toLowerCase() !== character;
  112. }
  113. }
  114. return result;
  115. };