From 11ef79f1e646217defece3f486419232d05c4761 Mon Sep 17 00:00:00 2001 From: Rasmus Porsager Date: Mon, 17 Jun 2019 10:02:52 +0200 Subject: [PATCH] Performance improvements --- lib/index.js | 19 +++++++++++-------- lib/utils.js | 14 +++++++++----- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/index.js b/lib/index.js index e705c12..f598f15 100644 --- a/lib/index.js +++ b/lib/index.js @@ -87,7 +87,7 @@ function chain(instance) { get: function() { return Object.keys(this.__style).reduce((acc, key) => { if (typeof this.__style[key] === 'number' || typeof this.__style[key] === 'string') - acc[key.replace(/^!/, '')] = this.__style[key] + acc[key.charAt(0) === '!' ? key.slice(1) : key] = this.__style[key] return acc }, {}) } @@ -144,12 +144,11 @@ function $media(value, style) { return b } +const hasUrl = /^('|"|url\('|url\(")/i function $import(value) { - if (value && !/^('|"|url\('|url\(")/.test(value)) - value = '"' + value + '"' - - if (value) - insert('@import ' + value + ';', 0) + value && insert('@import ' + + (hasUrl.test(value) ? value : '"' + value + '"') + + ';', 0) return chain(this) } @@ -255,15 +254,19 @@ function short(prop) { return short } +const blockEndMatch = /;(?![^("]*[)"])|\n/ +const commentsMatch = /\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*(?![^("]*[)"])/g +const propSeperator = /[ :]+/ + const stringToObject = memoize(string => { let last = '' , prev - return string.trim().replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*(?![^("]*[)"])/g, '').split(/;(?![^("]*[)"])|\n/).reduce((acc, line) => { + return string.trim().replace(commentsMatch, '').split(blockEndMatch).reduce((acc, line) => { if (!line) return acc line = last + line.trim() - const [key, ...tokens] = line.replace(/[ :]+/, ' ').split(' ') + const [key, ...tokens] = line.replace(propSeperator, ' ').split(' ') last = line.charAt(line.length - 1) === ',' ? line : '' if (last) diff --git a/lib/utils.js b/lib/utils.js index c2d53d2..dc6e184 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -66,20 +66,24 @@ export function assign(obj, obj2) { return obj } +const hyphenSeparator = /-([a-z])/g export function hyphenToCamelCase(hyphen) { - return hyphen.slice(hyphen.charAt(0) === '-' ? 1 : 0).replace(/-([a-z])/g, function(match) { + return hyphen.slice(hyphen.charAt(0) === '-' ? 1 : 0).replace(hyphenSeparator, function(match) { return match[1].toUpperCase() }) } +const camelSeparator = /(\B[A-Z])/g export function camelCaseToHyphen(camelCase) { - return camelCase.replace(/(\B[A-Z])/g, '-$1').toLowerCase() + return camelCase.replace(camelSeparator, '-$1').toLowerCase() } +const initialMatch = /([A-Z])/g export function initials(camelCase) { - return camelCase.charAt(0) + (camelCase.match(/([A-Z])/g) || []).join('').toLowerCase() + return camelCase.charAt(0) + (camelCase.match(initialMatch) || []).join('').toLowerCase() } +const ampersandMatch = /&/g export function objectToRules(style, selector, suffix = '', single) { const base = {} const extra = suffix.indexOf('&') > -1 && suffix.indexOf(',') === -1 ? '' : '&' @@ -96,7 +100,7 @@ export function objectToRules(style, selector, suffix = '', single) { if (Object.keys(base).length) { rules.unshift( - ((single || (suffix.charAt(0) === ' ') ? '' : '&') + extra + suffix).replace(/&/g, selector).trim() + + ((single || (suffix.charAt(0) === ' ') ? '' : '&') + extra + suffix).replace(ampersandMatch, selector).trim() + '{' + stylesToCss(base) + '}' ) } @@ -108,7 +112,7 @@ export const selectorSplit = /,(?=(?:(?:[^"]*"){2})*[^"]*$)/ export function stylesToCss(style) { return Object.keys(style).reduce((acc, prop) => - acc + propToString(prop.replace(/!/g, ''), style[prop]) + acc + propToString(prop.charAt(0) === '!' ? prop.slice(1) : prop, style[prop]) , '') }