names.js 2.9 KB

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