aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/button.style.js4
-rw-r--r--src/services/theme_data/iss_deserializer.js126
-rw-r--r--src/services/theme_data/iss_serializer.js16
-rw-r--r--src/services/theme_data/theme_data_3.service.js3
4 files changed, 126 insertions, 23 deletions
diff --git a/src/components/button.style.js b/src/components/button.style.js
index 6fec67a0..1bee8f8e 100644
--- a/src/components/button.style.js
+++ b/src/components/button.style.js
@@ -34,8 +34,8 @@ export default {
directives: {
'--defaultButtonHoverGlow': 'shadow | 0 0 4 --text',
'--defaultButtonShadow': 'shadow | 0 0 2 #000000',
- '--defaultButtonBevel': 'shadow | $borderSide(#FFFFFF, top, 0.2) | $borderSide(#000000, bottom, 0.2)',
- '--pressedButtonBevel': 'shadow | $borderSide(#FFFFFF, bottom, 0.2)| $borderSide(#000000, top, 0.2)'
+ '--defaultButtonBevel': 'shadow | $borderSide(#FFFFFF, top, 0.2), $borderSide(#000000, bottom, 0.2)',
+ '--pressedButtonBevel': 'shadow | $borderSide(#FFFFFF, bottom, 0.2), $borderSide(#000000, top, 0.2)'
}
},
{
diff --git a/src/services/theme_data/iss_deserializer.js b/src/services/theme_data/iss_deserializer.js
index 431e1b94..3cd2f15f 100644
--- a/src/services/theme_data/iss_deserializer.js
+++ b/src/services/theme_data/iss_deserializer.js
@@ -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)
+}
diff --git a/src/services/theme_data/iss_serializer.js b/src/services/theme_data/iss_serializer.js
index 8d6e9333..6bba85e4 100644
--- a/src/services/theme_data/iss_serializer.js
+++ b/src/services/theme_data/iss_serializer.js
@@ -1,6 +1,12 @@
import { unroll } from './iss_utils.js'
-const serializeShadow = s => `{${s.inset ? 'inset ' : ''}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}}`
+const serializeShadow = s => {
+ if (typeof s === 'object') {
+ return `{${s.inset ? 'inset ' : ''}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}}`
+ } else {
+ return s
+ }
+}
export const serialize = (ruleset) => {
return ruleset.map((rule) => {
@@ -8,8 +14,8 @@ export const serialize = (ruleset) => {
const header = unroll(rule).reverse().map(rule => {
const { component } = rule
- const newVariant = rule.variant === 'normal' ? '' : ('.' + rule.variant)
- const newState = rule.state.filter(st => st !== 'normal')
+ const newVariant = (rule.variant == null || rule.variant === 'normal') ? '' : ('.' + rule.variant)
+ const newState = (rule.state || []).filter(st => st !== 'normal')
return `${component}${newVariant}${newState.map(st => ':' + st).join('')}`
}).join(' ')
@@ -19,9 +25,9 @@ export const serialize = (ruleset) => {
const [valType, newValue] = value.split('|') // only first one! intentional!
switch (valType) {
case 'shadow':
- return ` ${directive}: ${newValue.map(serializeShadow).join(', ')}`
+ return ` ${directive}: ${valType.trim()} | ${newValue.map(serializeShadow).map(s => s.trim()).join(', ')}`
default:
- return ` ${directive}: ${newValue}`
+ return ` ${directive}: ${valType.trim()} | ${newValue.trim()}`
}
} else {
switch (directive) {
diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js
index b98cbb98..39c8b74f 100644
--- a/src/services/theme_data/theme_data_3.service.js
+++ b/src/services/theme_data/theme_data_3.service.js
@@ -23,9 +23,6 @@ import {
findRules
} from './iss_utils.js'
import { parseCssShadow } from './css_utils.js'
-import {
- serialize
-} from './iss_serializer.js'
// Ensuring the order of components
const components = {