| 'use strict'; |
| |
| var hasOwnProperty = Object.prototype.hasOwnProperty; |
| var keywords = Object.create(null); |
| var properties = Object.create(null); |
| var HYPHENMINUS = 45; // '-'.charCodeAt() |
| |
| function isCustomProperty(str, offset) { |
| offset = offset || 0; |
| |
| return str.length - offset >= 2 && |
| str.charCodeAt(offset) === HYPHENMINUS && |
| str.charCodeAt(offset + 1) === HYPHENMINUS; |
| } |
| |
| function getVendorPrefix(str, offset) { |
| offset = offset || 0; |
| |
| // verdor prefix should be at least 3 chars length |
| if (str.length - offset >= 3) { |
| // vendor prefix starts with hyper minus following non-hyper minus |
| if (str.charCodeAt(offset) === HYPHENMINUS && |
| str.charCodeAt(offset + 1) !== HYPHENMINUS) { |
| // vendor prefix should contain a hyper minus at the ending |
| var secondDashIndex = str.indexOf('-', offset + 2); |
| |
| if (secondDashIndex !== -1) { |
| return str.substring(offset, secondDashIndex + 1); |
| } |
| } |
| } |
| |
| return ''; |
| } |
| |
| function getKeywordDescriptor(keyword) { |
| if (hasOwnProperty.call(keywords, keyword)) { |
| return keywords[keyword]; |
| } |
| |
| var name = keyword.toLowerCase(); |
| |
| if (hasOwnProperty.call(keywords, name)) { |
| return keywords[keyword] = keywords[name]; |
| } |
| |
| var custom = isCustomProperty(name, 0); |
| var vendor = !custom ? getVendorPrefix(name, 0) : ''; |
| |
| return keywords[keyword] = Object.freeze({ |
| basename: name.substr(vendor.length), |
| name: name, |
| vendor: vendor, |
| prefix: vendor, |
| custom: custom |
| }); |
| } |
| |
| function getPropertyDescriptor(property) { |
| if (hasOwnProperty.call(properties, property)) { |
| return properties[property]; |
| } |
| |
| var name = property; |
| var hack = property[0]; |
| |
| if (hack === '/') { |
| hack = property[1] === '/' ? '//' : '/'; |
| } else if (hack !== '_' && |
| hack !== '*' && |
| hack !== '$' && |
| hack !== '#' && |
| hack !== '+') { |
| hack = ''; |
| } |
| |
| var custom = isCustomProperty(name, hack.length); |
| |
| // re-use result when possible (the same as for lower case) |
| if (!custom) { |
| name = name.toLowerCase(); |
| if (hasOwnProperty.call(properties, name)) { |
| return properties[property] = properties[name]; |
| } |
| } |
| |
| var vendor = !custom ? getVendorPrefix(name, hack.length) : ''; |
| var prefix = name.substr(0, hack.length + vendor.length); |
| |
| return properties[property] = Object.freeze({ |
| basename: name.substr(prefix.length), |
| name: name.substr(hack.length), |
| hack: hack, |
| vendor: vendor, |
| prefix: prefix, |
| custom: custom |
| }); |
| } |
| |
| module.exports = { |
| keyword: getKeywordDescriptor, |
| property: getPropertyDescriptor, |
| isCustomProperty: isCustomProperty, |
| vendorPrefix: getVendorPrefix |
| }; |