at last... it's complete
This commit is contained in:
parent
0c91c37645
commit
71a4781080
5 changed files with 136 additions and 64 deletions
|
|
@ -1,24 +1,51 @@
|
|||
import { flattenDeep } from 'lodash'
|
||||
|
||||
const parseShadow = string => {
|
||||
const modes = ['_full', 'inset', 'x', 'y', 'blur', 'spread', 'color', 'alpha']
|
||||
const regexPrep = [
|
||||
// inset keyword (optional)
|
||||
'^(?:(inset)\\s+)?',
|
||||
// x
|
||||
'(?:([0-9]+(?:\\.[0-9]+)?)\\s+)',
|
||||
// y
|
||||
'(?:([0-9]+(?:\\.[0-9]+)?)\\s+)',
|
||||
// blur (optional)
|
||||
'(?:([0-9]+(?:\\.[0-9]+)?)\\s+)?',
|
||||
// spread (optional)
|
||||
'(?:([0-9]+(?:\\.[0-9]+)?)\\s+)?',
|
||||
// either hex, variable or function
|
||||
'(#[0-9a-f]{6}|--[a-z\\-_]+|\\$[a-z\\-()_]+)',
|
||||
// opacity (optional)
|
||||
'(?:\\s+\\/\\s+([0-9]+(?:\\.[0-9]+)?)\\s*)?$'
|
||||
].join('')
|
||||
const regex = new RegExp(regexPrep, 'gis') // global, (stable) indices, single-string
|
||||
const result = regex.exec(string)
|
||||
if (result == null) {
|
||||
return string
|
||||
} else {
|
||||
return Object.fromEntries(modes.map((mode, i) => [mode, result[i]]))
|
||||
}
|
||||
}
|
||||
// this works nearly the same as HTML tree converter
|
||||
export const deserialize = (input) => {
|
||||
const buffer = []
|
||||
const parseIss = (input) => {
|
||||
const buffer = [{ selector: null, content: [] }]
|
||||
let textBuffer = ''
|
||||
|
||||
const getCurrentBuffer = () => {
|
||||
let current = buffer[buffer.length - 1][1]
|
||||
let current = buffer[buffer.length - 1]
|
||||
if (current == null) {
|
||||
current = { name: null, content: [] }
|
||||
current = { selector: null, content: [] }
|
||||
}
|
||||
buffer.push(current)
|
||||
return current
|
||||
}
|
||||
|
||||
// Processes current line buffer, adds it to output buffer and clears line buffer
|
||||
const flushText = (content) => {
|
||||
const flushText = (kind) => {
|
||||
if (textBuffer === '') return
|
||||
if (content) {
|
||||
getCurrentBuffer().content.push(textBuffer)
|
||||
if (kind === 'content') {
|
||||
getCurrentBuffer().content.push(textBuffer.trim())
|
||||
} else {
|
||||
getCurrentBuffer().name = textBuffer
|
||||
getCurrentBuffer().selector = textBuffer.trim()
|
||||
}
|
||||
textBuffer = ''
|
||||
}
|
||||
|
|
@ -27,17 +54,90 @@ export const deserialize = (input) => {
|
|||
const char = input[i]
|
||||
|
||||
if (char === ';') {
|
||||
flushText(true)
|
||||
flushText('content')
|
||||
} else if (char === '{') {
|
||||
flushText(false)
|
||||
flushText('header')
|
||||
} else if (char === '}') {
|
||||
buffer.push({ name: null, content: [] })
|
||||
flushText('content')
|
||||
buffer.push({ selector: null, content: [] })
|
||||
textBuffer = ''
|
||||
} else {
|
||||
textBuffer += char
|
||||
}
|
||||
}
|
||||
|
||||
flushText()
|
||||
return buffer
|
||||
}
|
||||
export const deserialize = (input) => {
|
||||
const ast = parseIss(input)
|
||||
const finalResult = ast.filter(i => i.selector != null).map(item => {
|
||||
const { selector, content } = item
|
||||
let stateCount = 0
|
||||
const selectors = selector.split(/,/g)
|
||||
const result = selectors.map(selector => {
|
||||
const output = { component: '' }
|
||||
let currentDepth = null
|
||||
|
||||
selector.split(/ /g).reverse().forEach((fragment, index, arr) => {
|
||||
const fragmentObject = { component: '' }
|
||||
|
||||
let mode = 'component'
|
||||
for (let i = 0; i < fragment.length; i++) {
|
||||
const char = fragment[i]
|
||||
switch (char) {
|
||||
case '.': {
|
||||
mode = 'variant'
|
||||
fragmentObject.variant = ''
|
||||
break
|
||||
}
|
||||
case ':': {
|
||||
mode = 'state'
|
||||
fragmentObject.state = fragmentObject.state || []
|
||||
stateCount++
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (mode === 'state') {
|
||||
const currentState = fragmentObject.state[stateCount - 1]
|
||||
if (currentState == null) {
|
||||
fragmentObject.state.push('')
|
||||
}
|
||||
fragmentObject.state[stateCount - 1] += char
|
||||
} else {
|
||||
fragmentObject[mode] += char
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentDepth !== null) {
|
||||
currentDepth.parent = { ...fragmentObject }
|
||||
currentDepth = currentDepth.parent
|
||||
} else {
|
||||
Object.keys(fragmentObject).forEach(key => {
|
||||
output[key] = fragmentObject[key]
|
||||
})
|
||||
if (index !== (arr.length - 1)) {
|
||||
output.parent = { component: '' }
|
||||
}
|
||||
currentDepth = output
|
||||
}
|
||||
})
|
||||
|
||||
output.directives = Object.fromEntries(content.map(d => {
|
||||
const [property, value] = d.split(':')
|
||||
console.log(property, value)
|
||||
let realValue = value.trim()
|
||||
if (property === 'shadow') {
|
||||
realValue = parseShadow(value.split(',').map(v => v.trim()))
|
||||
} if (!Number.isNaN(Number(value))) {
|
||||
realValue = Number(value)
|
||||
}
|
||||
return [property, realValue]
|
||||
}))
|
||||
|
||||
return output
|
||||
})
|
||||
return result
|
||||
})
|
||||
return flattenDeep(finalResult)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue