UNPKG

bootstrap-less-port

Version:
100 lines (73 loc) 2.81 kB
// // Helper Functions // function lookupVariable(context, variableName) { const { frames, importantScope } = context return tree.Variable.prototype.find(frames, frame => { const { value, important } = frame.variable(variableName) || {} if (value === undefined) return if (important && importantScope[importantScope.length - 1]) importantScope[importantScope.length - 1].important = important return value.eval(context) }) } // @TODO: [@calvinjuarez] unify this function between files, maybe even canonize it as a // `Ruleset`/`DetachedRuleset` method at some point. function rulesetToMap(context, { ruleset: { rules } } = { ruleset: { rules: [] } }) { const map = {} rules.forEach(rule => { // Not exactly sure how to handle other types (or if they should be handled at all). if (! (rule instanceof tree.Declaration)) return const { name: key, value } = rule.eval(context) map[key] = value }) return map } // // Less Functions // // Requires the use of quotes around data URIs. functions.add('escape-svg', function (value = {}) { let escapedStr = value.toCSS ? value.toCSS() : '' if (! escapedStr.includes('data:image/svg+xml')) return value const escapeCharsVar = lookupVariable(this.context, '@escaped-characters') let escapeCharsMap = {} // Currently Less treats the `@escaped-characters` variable as a string instead of a ruleset, due // to its unconventional use of special characters like `<` as property names. In case this is // fixed in the future, we’ll handle both possible values here (string and ruleset). if (escapeCharsVar instanceof tree.Quoted) { // Remove leading `{` and trailing `}` as well as the last instance of a `;`, then split by // `;`. const escapeCharsKeyValueArr = escapeCharsVar.value.replace(/[{}\s]+|;(?=\n})/g, '').split(';') escapeCharsKeyValueArr.forEach(escapeCharKeyValueStr => { const [key, value] = escapeCharKeyValueStr.split(':') escapeCharsMap[key] = value }) } else escapeCharsMap = rulesetToMap(this.context, lookupVariable(this.context, '@escaped-characters')) let escapeCharsMapKeys = [] try { escapeCharsMapKeys = Object.keys(escapeCharsMap) } catch (err) { // Do nothing. } let shouldAddURLWrapper = false // Strip the `url()` wrapping the string, if present (to prevent it from being escaped). if (escapedStr.startsWith('url(')) { escapedStr = escapedStr.replace(/^url\(|\)$/g, '') shouldAddURLWrapper = true } escapeCharsMapKeys.forEach(key => { const value = escapeCharsMap[key] if (key === ')' || key === '(') key = `\\${key}` escapedStr = escapedStr.replace(new RegExp(key, 'g'), value) }) // Re-add the `url()` wrapper if necessary. if (shouldAddURLWrapper) escapedStr = `url(${escapedStr})` return new tree.Quoted('', escapedStr) })