use draft logic for virtualDirective to catch errors
This commit is contained in:
parent
21b17f333d
commit
f4d29b5d5e
|
@ -4,7 +4,7 @@
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
:disabled="disabled || shadowsAreNull"
|
:disabled="disabled"
|
||||||
@click="add"
|
@click="add"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
getScopedVersion
|
getScopedVersion
|
||||||
} from 'src/services/theme_data/css_utils.js'
|
} from 'src/services/theme_data/css_utils.js'
|
||||||
import { serializeShadow, serialize } from 'src/services/theme_data/iss_serializer.js'
|
import { serializeShadow, serialize } from 'src/services/theme_data/iss_serializer.js'
|
||||||
import { parseShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
import { deserializeShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||||
import {
|
import {
|
||||||
rgb2hex,
|
rgb2hex,
|
||||||
hex2rgb,
|
hex2rgb,
|
||||||
|
@ -371,7 +371,11 @@ export default {
|
||||||
return shadow
|
return shadow
|
||||||
}
|
}
|
||||||
if (typeof shadow === 'string') {
|
if (typeof shadow === 'string') {
|
||||||
return parseShadow(shadow)
|
try {
|
||||||
|
return deserializeShadow(shadow)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
@ -580,6 +584,7 @@ export default {
|
||||||
|
|
||||||
const selectedVirtualDirectiveId = ref(0)
|
const selectedVirtualDirectiveId = ref(0)
|
||||||
exports.selectedVirtualDirectiveId = selectedVirtualDirectiveId
|
exports.selectedVirtualDirectiveId = selectedVirtualDirectiveId
|
||||||
|
|
||||||
const selectedVirtualDirective = computed({
|
const selectedVirtualDirective = computed({
|
||||||
get () {
|
get () {
|
||||||
return virtualDirectives[selectedVirtualDirectiveId.value]
|
return virtualDirectives[selectedVirtualDirectiveId.value]
|
||||||
|
@ -589,6 +594,7 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
exports.selectedVirtualDirective = selectedVirtualDirective
|
exports.selectedVirtualDirective = selectedVirtualDirective
|
||||||
|
|
||||||
exports.selectedVirtualDirectiveValType = computed({
|
exports.selectedVirtualDirectiveValType = computed({
|
||||||
get () {
|
get () {
|
||||||
return virtualDirectives[selectedVirtualDirectiveId.value].valType
|
return virtualDirectives[selectedVirtualDirectiveId.value].valType
|
||||||
|
@ -607,35 +613,56 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
exports.selectedVirtualDirectiveParsed = computed({
|
|
||||||
get () {
|
const draftVirtualDirectiveValid = ref(true)
|
||||||
switch (selectedVirtualDirective.value.valType) {
|
const draftVirtualDirective = ref({})
|
||||||
|
exports.draftVirtualDirective = draftVirtualDirective
|
||||||
|
|
||||||
|
watch(
|
||||||
|
selectedVirtualDirective,
|
||||||
|
(directive) => {
|
||||||
|
switch (directive.valType) {
|
||||||
case 'shadow': {
|
case 'shadow': {
|
||||||
const directiveValue = selectedVirtualDirective.value.value
|
if (Array.isArray(directive.value)) {
|
||||||
if (Array.isArray(directiveValue)) {
|
draftVirtualDirective.value = normalizeShadows(directive.value)
|
||||||
return normalizeShadows(directiveValue)
|
|
||||||
} else {
|
} else {
|
||||||
const splitShadow = directiveValue.split(/,/g).map(x => x.trim())
|
const splitShadow = directive.value.split(/,/g).map(x => x.trim())
|
||||||
return normalizeShadows(splitShadow)
|
draftVirtualDirective.value = normalizeShadows(splitShadow)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
case 'color':
|
|
||||||
return selectedVirtualDirective.value.value
|
|
||||||
default:
|
|
||||||
return selectedVirtualDirective.value.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
switch (selectedVirtualDirective.value.valType) {
|
|
||||||
case 'shadow': {
|
|
||||||
virtualDirectives[selectedVirtualDirectiveId.value].value = value.map(x => serializeShadow(x)).join(', ')
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'color':
|
||||||
|
draftVirtualDirective.value = directive.value
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
virtualDirectives[selectedVirtualDirectiveId.value].value = value
|
draftVirtualDirective.value = directive.value
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
draftVirtualDirective,
|
||||||
|
(directive) => {
|
||||||
|
try {
|
||||||
|
switch (selectedVirtualDirective.value.valType) {
|
||||||
|
case 'shadow': {
|
||||||
|
virtualDirectives[selectedVirtualDirectiveId.value].value =
|
||||||
|
directive.map(x => serializeShadow(x)).join(', ')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
virtualDirectives[selectedVirtualDirectiveId.value].value = directive
|
||||||
|
}
|
||||||
|
draftVirtualDirectiveValid.value = true
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Invalid virtual directive value', e)
|
||||||
|
draftVirtualDirectiveValid.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
exports.getNewVirtualDirective = () => ({
|
exports.getNewVirtualDirective = () => ({
|
||||||
name: 'newDirective',
|
name: 'newDirective',
|
||||||
|
|
|
@ -285,7 +285,7 @@
|
||||||
:disabled="!isShadowPresent"
|
:disabled="!isShadowPresent"
|
||||||
:no-preview="true"
|
:no-preview="true"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'"
|
:compute-color="computeColor"
|
||||||
@subShadowSelected="onSubShadow"
|
@subShadowSelected="onSubShadow"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -408,14 +408,14 @@
|
||||||
</div>
|
</div>
|
||||||
<ShadowControl
|
<ShadowControl
|
||||||
v-if="selectedVirtualDirectiveValType === 'shadow'"
|
v-if="selectedVirtualDirectiveValType === 'shadow'"
|
||||||
v-model="selectedVirtualDirectiveParsed"
|
v-model="draftVirtualDirective"
|
||||||
:computeColor="computeColor"
|
:compute-color="computeColor"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-if="selectedVirtualDirectiveValType === 'color'"
|
v-if="selectedVirtualDirectiveValType === 'color'"
|
||||||
v-model="selectedVirtualDirectiveParsed"
|
v-model="draftVirtualDirective"
|
||||||
:fallback="computeColor(selectedVirtualDirectiveParsed)"
|
:fallback="computeColor(draftVirtualDirective)"
|
||||||
:label="$t('settings.style.themes3.editor.variables.virtual_color')"
|
:label="$t('settings.style.themes3.editor.variables.virtual_color')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { flattenDeep } from 'lodash'
|
import { flattenDeep } from 'lodash'
|
||||||
|
|
||||||
export const parseShadow = string => {
|
export const deserializeShadow = string => {
|
||||||
const modes = ['_full', 'inset', 'x', 'y', 'blur', 'spread', 'color', 'alpha']
|
const modes = ['_full', 'inset', 'x', 'y', 'blur', 'spread', 'color', 'alpha', 'name']
|
||||||
const regexPrep = [
|
const regexPrep = [
|
||||||
// inset keyword (optional)
|
// inset keyword (optional)
|
||||||
'^(?:(inset)\\s+)?',
|
'^',
|
||||||
|
'(?:(inset)\\s+)?',
|
||||||
// x
|
// x
|
||||||
'(?:(-?[0-9]+(?:\\.[0-9]+)?)\\s+)',
|
'(?:(-?[0-9]+(?:\\.[0-9]+)?)\\s+)',
|
||||||
// y
|
// y
|
||||||
|
@ -16,7 +17,10 @@ export const parseShadow = string => {
|
||||||
// either hex, variable or function
|
// either hex, variable or function
|
||||||
'(#[0-9a-f]{6}|--[a-z\\-_]+|\\$[a-z\\-()_]+)',
|
'(#[0-9a-f]{6}|--[a-z\\-_]+|\\$[a-z\\-()_]+)',
|
||||||
// opacity (optional)
|
// opacity (optional)
|
||||||
'(?:\\s+\\/\\s+([0-9]+(?:\\.[0-9]+)?)\\s*)?$'
|
'(?:\\s+\\/\\s+([0-9]+(?:\\.[0-9]+)?)\\s*)?',
|
||||||
|
// name
|
||||||
|
'(?:\\s+#(\\w+)\\s*)?',
|
||||||
|
'$'
|
||||||
].join('')
|
].join('')
|
||||||
const regex = new RegExp(regexPrep, 'gis') // global, (stable) indices, single-string
|
const regex = new RegExp(regexPrep, 'gis') // global, (stable) indices, single-string
|
||||||
const result = regex.exec(string)
|
const result = regex.exec(string)
|
||||||
|
@ -28,7 +32,7 @@ export const parseShadow = string => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const numeric = new Set(['x', 'y', 'blur', 'spread', 'alpha'])
|
const numeric = new Set(['x', 'y', 'blur', 'spread', 'alpha'])
|
||||||
const { x, y, blur, spread, alpha, inset, color } = Object.fromEntries(modes.map((mode, i) => {
|
const { x, y, blur, spread, alpha, inset, color, name } = Object.fromEntries(modes.map((mode, i) => {
|
||||||
if (numeric.has(mode)) {
|
if (numeric.has(mode)) {
|
||||||
const number = Number(result[i])
|
const number = Number(result[i])
|
||||||
if (Number.isNaN(number)) {
|
if (Number.isNaN(number)) {
|
||||||
|
@ -43,7 +47,7 @@ export const parseShadow = string => {
|
||||||
}
|
}
|
||||||
}).filter(([k, v]) => v !== false).slice(1))
|
}).filter(([k, v]) => v !== false).slice(1))
|
||||||
|
|
||||||
return { x, y, blur, spread, color, alpha, inset }
|
return { x, y, blur, spread, color, alpha, inset, name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this works nearly the same as HTML tree converter
|
// this works nearly the same as HTML tree converter
|
||||||
|
@ -150,7 +154,7 @@ export const deserialize = (input) => {
|
||||||
if (realValue === 'none') {
|
if (realValue === 'none') {
|
||||||
realValue = []
|
realValue = []
|
||||||
} else {
|
} else {
|
||||||
realValue = value.split(',').map(v => parseShadow(v.trim()))
|
realValue = value.split(',').map(v => deserializeShadow(v.trim()))
|
||||||
}
|
}
|
||||||
} if (!Number.isNaN(Number(value))) {
|
} if (!Number.isNaN(Number(value))) {
|
||||||
realValue = Number(value)
|
realValue = Number(value)
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import { unroll } from './iss_utils.js'
|
import { unroll } from './iss_utils.js'
|
||||||
|
import { deserializeShadow } from './iss_deserializer.js'
|
||||||
|
|
||||||
export const serializeShadow = (s, throwOnInvalid) => {
|
export const serializeShadow = (s, throwOnInvalid) => {
|
||||||
if (typeof s === 'object') {
|
if (typeof s === 'object') {
|
||||||
return `${s.inset ? 'inset ' : ''}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}`
|
const inset = s.inset ? 'inset ' : ''
|
||||||
|
const name = s.name ? ` #${s.name} ` : ''
|
||||||
|
const result = `${inset}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}${name}`
|
||||||
|
deserializeShadow(result) // Verify that output is valid and parseable
|
||||||
|
return result
|
||||||
} else {
|
} else {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {
|
||||||
normalizeCombination,
|
normalizeCombination,
|
||||||
findRules
|
findRules
|
||||||
} from './iss_utils.js'
|
} from './iss_utils.js'
|
||||||
import { parseShadow } from './iss_deserializer.js'
|
import { deserializeShadow } from './iss_deserializer.js'
|
||||||
|
|
||||||
// Ensuring the order of components
|
// Ensuring the order of components
|
||||||
const components = {
|
const components = {
|
||||||
|
@ -48,7 +48,7 @@ const findShadow = (shadows, { dynamicVars, staticVars }) => {
|
||||||
const variableSlot = shadow.substring(2)
|
const variableSlot = shadow.substring(2)
|
||||||
return findShadow(staticVars[variableSlot], { dynamicVars, staticVars })
|
return findShadow(staticVars[variableSlot], { dynamicVars, staticVars })
|
||||||
} else {
|
} else {
|
||||||
targetShadow = parseShadow(shadow)
|
targetShadow = deserializeShadow(shadow)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targetShadow = shadow
|
targetShadow = shadow
|
||||||
|
|
Loading…
Reference in a new issue