names.cjs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. 'use strict';
  2. const keywords = new Map();
  3. const properties = new Map();
  4. const HYPHENMINUS = 45; // '-'.charCodeAt()
  5. const keyword = getKeywordDescriptor;
  6. const property = getPropertyDescriptor;
  7. const vendorPrefix = getVendorPrefix;
  8. function isCustomProperty(str, offset) {
  9. offset = offset || 0;
  10. return str.length - offset >= 2 &&
  11. str.charCodeAt(offset) === HYPHENMINUS &&
  12. str.charCodeAt(offset + 1) === HYPHENMINUS;
  13. }
  14. function getVendorPrefix(str, offset) {
  15. offset = offset || 0;
  16. // verdor prefix should be at least 3 chars length
  17. if (str.length - offset >= 3) {
  18. // vendor prefix starts with hyper minus following non-hyper minus
  19. if (str.charCodeAt(offset) === HYPHENMINUS &&
  20. str.charCodeAt(offset + 1) !== HYPHENMINUS) {
  21. // vendor prefix should contain a hyper minus at the ending
  22. const secondDashIndex = str.indexOf('-', offset + 2);
  23. if (secondDashIndex !== -1) {
  24. return str.substring(offset, secondDashIndex + 1);
  25. }
  26. }
  27. }
  28. return '';
  29. }
  30. function getKeywordDescriptor(keyword) {
  31. if (keywords.has(keyword)) {
  32. return keywords.get(keyword);
  33. }
  34. const name = keyword.toLowerCase();
  35. let descriptor = keywords.get(name);
  36. if (descriptor === undefined) {
  37. const custom = isCustomProperty(name, 0);
  38. const vendor = !custom ? getVendorPrefix(name, 0) : '';
  39. descriptor = Object.freeze({
  40. basename: name.substr(vendor.length),
  41. name,
  42. prefix: vendor,
  43. vendor,
  44. custom
  45. });
  46. }
  47. keywords.set(keyword, descriptor);
  48. return descriptor;
  49. }
  50. function getPropertyDescriptor(property) {
  51. if (properties.has(property)) {
  52. return properties.get(property);
  53. }
  54. let name = property;
  55. let hack = property[0];
  56. if (hack === '/') {
  57. hack = property[1] === '/' ? '//' : '/';
  58. } else if (hack !== '_' &&
  59. hack !== '*' &&
  60. hack !== '$' &&
  61. hack !== '#' &&
  62. hack !== '+' &&
  63. hack !== '&') {
  64. hack = '';
  65. }
  66. const custom = isCustomProperty(name, hack.length);
  67. // re-use result when possible (the same as for lower case)
  68. if (!custom) {
  69. name = name.toLowerCase();
  70. if (properties.has(name)) {
  71. const descriptor = properties.get(name);
  72. properties.set(property, descriptor);
  73. return descriptor;
  74. }
  75. }
  76. const vendor = !custom ? getVendorPrefix(name, hack.length) : '';
  77. const prefix = name.substr(0, hack.length + vendor.length);
  78. const descriptor = Object.freeze({
  79. basename: name.substr(prefix.length),
  80. name: name.substr(hack.length),
  81. hack,
  82. vendor,
  83. prefix,
  84. custom
  85. });
  86. properties.set(property, descriptor);
  87. return descriptor;
  88. }
  89. exports.isCustomProperty = isCustomProperty;
  90. exports.keyword = keyword;
  91. exports.property = property;
  92. exports.vendorPrefix = vendorPrefix;