Spaces:
Runtime error
Runtime error
; | |
const keywords = new Map(); | |
const properties = new Map(); | |
const HYPHENMINUS = 45; // '-'.charCodeAt() | |
const keyword = getKeywordDescriptor; | |
const property = getPropertyDescriptor; | |
const vendorPrefix = getVendorPrefix; | |
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 | |
const secondDashIndex = str.indexOf('-', offset + 2); | |
if (secondDashIndex !== -1) { | |
return str.substring(offset, secondDashIndex + 1); | |
} | |
} | |
} | |
return ''; | |
} | |
function getKeywordDescriptor(keyword) { | |
if (keywords.has(keyword)) { | |
return keywords.get(keyword); | |
} | |
const name = keyword.toLowerCase(); | |
let descriptor = keywords.get(name); | |
if (descriptor === undefined) { | |
const custom = isCustomProperty(name, 0); | |
const vendor = !custom ? getVendorPrefix(name, 0) : ''; | |
descriptor = Object.freeze({ | |
basename: name.substr(vendor.length), | |
name, | |
prefix: vendor, | |
vendor, | |
custom | |
}); | |
} | |
keywords.set(keyword, descriptor); | |
return descriptor; | |
} | |
function getPropertyDescriptor(property) { | |
if (properties.has(property)) { | |
return properties.get(property); | |
} | |
let name = property; | |
let hack = property[0]; | |
if (hack === '/') { | |
hack = property[1] === '/' ? '//' : '/'; | |
} else if (hack !== '_' && | |
hack !== '*' && | |
hack !== '$' && | |
hack !== '#' && | |
hack !== '+' && | |
hack !== '&') { | |
hack = ''; | |
} | |
const custom = isCustomProperty(name, hack.length); | |
// re-use result when possible (the same as for lower case) | |
if (!custom) { | |
name = name.toLowerCase(); | |
if (properties.has(name)) { | |
const descriptor = properties.get(name); | |
properties.set(property, descriptor); | |
return descriptor; | |
} | |
} | |
const vendor = !custom ? getVendorPrefix(name, hack.length) : ''; | |
const prefix = name.substr(0, hack.length + vendor.length); | |
const descriptor = Object.freeze({ | |
basename: name.substr(prefix.length), | |
name: name.substr(hack.length), | |
hack, | |
vendor, | |
prefix, | |
custom | |
}); | |
properties.set(property, descriptor); | |
return descriptor; | |
} | |
exports.isCustomProperty = isCustomProperty; | |
exports.keyword = keyword; | |
exports.property = property; | |
exports.vendorPrefix = vendorPrefix; | |