conventions.js 3.0 KB

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