105 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 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 !== '&') {
 | |
|         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
 | |
| };
 |