Skip to content
This repository has been archived by the owner on May 14, 2021. It is now read-only.

Commit

Permalink
Merge pull request #3 from styled-components/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
mxstbr committed Oct 25, 2016
2 parents 7f0b543 + 8a8ec20 commit 78e43fd
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 49 deletions.
63 changes: 22 additions & 41 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
const path = require('path')
const babylon = require('babylon')
const traverse = require('babel-traverse').default

const isStyled = require('./utils/styled').isStyled
const isHelper = require('./utils/styled').isHelper
const isStyledImport = require('./utils/styled').isStyledImport
const getCSS = require('./utils/general').getCSS
const getKeyframes = require('./utils/general').getKeyframes

const wrapSelector = require('./utils/general').wrapSelector
const wrapKeyframes = require('./utils/general').wrapKeyframes
const fixIndentation = require('./utils/general').fixIndentation

const getTTLContent = require('./utils/tagged-template-literal.js').getTaggedTemplateLiteralContent
const parseImports = require('./utils/parse').parseImports
const getSourceMap = require('./utils/parse').getSourceMap

// TODO Fix ampersand in selectors
// TODO ENFORCE THESE RULES
Expand Down Expand Up @@ -44,7 +49,7 @@ module.exports = (/* options */) => ({
})

let extractedCSS = ''
const importedNames = {
let importedNames = {
default: 'styled',
css: 'css',
keyframes: 'keyframes',
Expand All @@ -53,48 +58,24 @@ module.exports = (/* options */) => ({
traverse(ast, {
enter({ node }) {
if (isStyledImport(node)) {
const imports = node.specifiers.filter((specifier) => (
specifier.type === 'ImportDefaultSpecifier'
|| specifier.type === 'ImportSpecifier'
))

if (imports.length <= 0) return

imports.forEach((singleImport) => {
if (singleImport.imported) {
// Is helper method
importedNames[singleImport.imported.name] = singleImport.local.name
} else {
// Is default import
importedNames.default = singleImport.local.name
}
})
importedNames = parseImports(node)
return
}

const helper = isHelper(node, importedNames)

const addCSSFromNode = (contentGetter) => {
const css = contentGetter(node)
extractedCSS += css
// Save which line in the extracted CSS is which line in the source
const fullCSSLength = extractedCSS.split(/\n/).length
const currentCSSLength = css.split(/\n/).length
const currentCSSStart = (fullCSSLength - currentCSSLength) + 1
// eslint-disable-next-line no-plusplus
for (let i = 0; i < currentCSSLength + 1; i++) {
sourceMapsCorrections[absolutePath][currentCSSStart + i] = node.loc.start.line + i
}
}

if (helper === 'keyframes') {
addCSSFromNode(getKeyframes)
return
}
if (!helper && !isStyled(node, importedNames.default)) return

if (isStyled(node, importedNames.default) || helper === 'css' || helper === 'injectGlobal') {
addCSSFromNode(getCSS)
return
}
const content = getTTLContent(node)
const fixedContent = fixIndentation(content).text
const wrapperFn = helper === 'keyframes' ? wrapKeyframes : wrapSelector
const wrappedContent = wrapperFn(fixedContent)
extractedCSS += wrappedContent
// Save source location, merging existing corrections with current corrections
sourceMapsCorrections[absolutePath] = Object.assign(
sourceMapsCorrections[absolutePath],
getSourceMap(extractedCSS, wrappedContent, node.loc.start.line)
)
},
})

Expand Down
13 changes: 5 additions & 8 deletions src/utils/general.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const getTaggedTemplateLiteralContent = require('./tagged-template-literal').getTaggedTemplateLiteralContent

/**
* Based on https://github.com/mapbox/stylelint-processor-markdown
* @author @davidtheclark
Expand All @@ -25,10 +23,9 @@ const fixIndentation = (str) => {
}
}

const getContent = (node) => fixIndentation(getTaggedTemplateLiteralContent(node)).text

const getCSS = (node) => `.selector {${getContent(node)}}\n`
const getKeyframes = (node) => `@keyframes {${getContent(node)}}\n`
const wrapSelector = (content) => `.selector {${content}}\n`
const wrapKeyframes = (content) => `@keyframes {${content}}\n`

exports.getKeyframes = getKeyframes
exports.getCSS = getCSS
exports.wrapKeyframes = wrapKeyframes
exports.wrapSelector = wrapSelector
exports.fixIndentation = fixIndentation
39 changes: 39 additions & 0 deletions src/utils/parse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Parsing helpers
*/

const parseImports = (node, currentNames) => {
const names = Object.assign({}, currentNames)
const imports = node.specifiers.filter((specifier) => (
specifier.type === 'ImportDefaultSpecifier'
|| specifier.type === 'ImportSpecifier'
))

imports.forEach((singleImport) => {
if (singleImport.imported) {
// Is helper method
names[singleImport.imported.name] = singleImport.local.name
} else {
// Is default import
names.default = singleImport.local.name
}
})

return names
}

const getSourceMap = (fullCSS, fragmentCSS, startInSource) => {
const correction = {}
// Save which line in the full CSS is which line in the source
const fullCSSLength = fullCSS.split(/\n/).length
const currentCSSLength = fragmentCSS.split(/\n/).length
const currentCSSStart = (fullCSSLength - currentCSSLength) + 1
// eslint-disable-next-line no-plusplus
for (let i = 0; i < currentCSSLength + 1; i++) {
correction[currentCSSStart + i] = startInSource + i
}
return correction
}

exports.parseImports = parseImports
exports.getSourceMap = getSourceMap

0 comments on commit 78e43fd

Please sign in to comment.