Merge branch 'themes3-grand-finale-maybe' into shigusegubu-themes3
This commit is contained in:
commit
461eb8752d
15 changed files with 217 additions and 127 deletions
|
@ -3,6 +3,12 @@
|
||||||
class="ComponentPreview"
|
class="ComponentPreview"
|
||||||
:class="{ '-shadow-controls': shadowControl }"
|
:class="{ '-shadow-controls': shadowControl }"
|
||||||
>
|
>
|
||||||
|
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
||||||
|
<component
|
||||||
|
:is="'style'"
|
||||||
|
v-html="previewCss"
|
||||||
|
/>
|
||||||
|
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
||||||
<label
|
<label
|
||||||
v-show="shadowControl"
|
v-show="shadowControl"
|
||||||
class="header"
|
class="header"
|
||||||
|
@ -11,7 +17,7 @@
|
||||||
{{ $t('settings.style.shadows.offset') }}
|
{{ $t('settings.style.shadows.offset') }}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-show="shadowControl"
|
v-show="shadowControl && !hideControls"
|
||||||
:value="shadow?.y"
|
:value="shadow?.y"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:class="{ disabled }"
|
:class="{ disabled }"
|
||||||
|
@ -20,7 +26,7 @@
|
||||||
@input="e => updateProperty('y', e.target.value)"
|
@input="e => updateProperty('y', e.target.value)"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-show="shadowControl"
|
v-show="shadowControl && !hideControls"
|
||||||
:value="shadow?.y"
|
:value="shadow?.y"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:class="{ disabled }"
|
:class="{ disabled }"
|
||||||
|
@ -41,9 +47,14 @@
|
||||||
>
|
>
|
||||||
{{ $t('settings.style.themes3.editor.test_string') }}
|
{{ $t('settings.style.themes3.editor.test_string') }}
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="invalid" class="invalid-container">
|
||||||
|
<div class="alert error invalid-label">
|
||||||
|
{{ $t('settings.style.themes3.editor.invalid') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
v-show="shadowControl"
|
v-show="shadowControl && !hideControls"
|
||||||
:value="shadow?.x"
|
:value="shadow?.x"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:class="{ disabled }"
|
:class="{ disabled }"
|
||||||
|
@ -52,7 +63,7 @@
|
||||||
@input="e => updateProperty('x', e.target.value)"
|
@input="e => updateProperty('x', e.target.value)"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-show="shadowControl"
|
v-show="shadowControl && !hideControls"
|
||||||
:value="shadow?.x"
|
:value="shadow?.x"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:class="{ disabled }"
|
:class="{ disabled }"
|
||||||
|
@ -85,7 +96,9 @@ export default {
|
||||||
'shadowControl',
|
'shadowControl',
|
||||||
'previewClass',
|
'previewClass',
|
||||||
'previewStyle',
|
'previewStyle',
|
||||||
'disabled'
|
'previewCss',
|
||||||
|
'disabled',
|
||||||
|
'invalid'
|
||||||
],
|
],
|
||||||
emits: ['update:shadow'],
|
emits: ['update:shadow'],
|
||||||
data () {
|
data () {
|
||||||
|
@ -93,9 +106,14 @@ export default {
|
||||||
lightGrid: false
|
lightGrid: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
hideControls () {
|
||||||
|
return typeof this.shadow === 'string'
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateProperty (axis, value) {
|
updateProperty (axis, value) {
|
||||||
this.$emit('update:shadow', { axis, value })
|
this.$emit('update:shadow', { axis, value: Number(value) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +139,22 @@ export default {
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.invalid-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
justify-items: center;
|
||||||
|
background-color: rgba(100 0 0 / 50%);
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input-light-grid {
|
.input-light-grid {
|
||||||
grid-area: options;
|
grid-area: options;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
|
@ -170,6 +204,7 @@ export default {
|
||||||
--__grid-color2-disabled: rgba(255 255 255 / 20%);
|
--__grid-color2-disabled: rgba(255 255 255 / 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
position: relative;
|
||||||
grid-area: preview;
|
grid-area: preview;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'Modals',
|
name: 'Modals',
|
||||||
selector: '.modal-view',
|
selector: ['.modal-view', '#modal', '.shout-panel'],
|
||||||
lazy: true,
|
lazy: true,
|
||||||
notEditable: true,
|
notEditable: true,
|
||||||
validInnerComponents: [
|
validInnerComponents: [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'Scrollbar',
|
name: 'Scrollbar',
|
||||||
selector: '::-webkit-scrollbar',
|
selector: ['::-webkit-scrollbar-button', '::-webkit-scrollbar-thumb', '::-webkit-resizer'],
|
||||||
notEditable: true, // for now
|
notEditable: true, // for now
|
||||||
defaultRules: [
|
defaultRules: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -148,6 +148,7 @@
|
||||||
:shadow-control="isShadowTabOpen"
|
:shadow-control="isShadowTabOpen"
|
||||||
:preview-class="previewClass"
|
:preview-class="previewClass"
|
||||||
:preview-style="editorHintStyle"
|
:preview-style="editorHintStyle"
|
||||||
|
:preview-css="previewCss"
|
||||||
:disabled="!editedSubShadow && typeof editedShadow !== 'string'"
|
:disabled="!editedSubShadow && typeof editedShadow !== 'string'"
|
||||||
:shadow="editedSubShadow"
|
:shadow="editedSubShadow"
|
||||||
@update:shadow="({ axis, value }) => updateSubShadow(axis, value)"
|
@update:shadow="({ axis, value }) => updateSubShadow(axis, value)"
|
||||||
|
@ -285,7 +286,7 @@
|
||||||
:disabled="!isShadowPresent"
|
:disabled="!isShadowPresent"
|
||||||
:no-preview="true"
|
:no-preview="true"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'"
|
:static-vars="selectedPalette"
|
||||||
@subShadowSelected="onSubShadow"
|
@subShadowSelected="onSubShadow"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -408,14 +409,14 @@
|
||||||
</div>
|
</div>
|
||||||
<ShadowControl
|
<ShadowControl
|
||||||
v-if="selectedVirtualDirectiveValType === 'shadow'"
|
v-if="selectedVirtualDirectiveValType === 'shadow'"
|
||||||
v-model="selectedVirtualDirectiveParsed"
|
v-model="draftVirtualDirective"
|
||||||
:computeColor="computeColor"
|
:static-vars="selectedPalette"
|
||||||
: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>
|
||||||
|
|
|
@ -957,6 +957,7 @@
|
||||||
v-model="currentShadow"
|
v-model="currentShadow"
|
||||||
:separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'"
|
:separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'"
|
||||||
:fallback="currentShadowFallback"
|
:fallback="currentShadowFallback"
|
||||||
|
:static-vars="previewTheme.colors"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -5,9 +5,13 @@ import SelectMotion from 'src/components/select/select_motion.vue'
|
||||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
import Popover from 'src/components/popover/popover.vue'
|
||||||
import ComponentPreview from 'src/components/component_preview/component_preview.vue'
|
import ComponentPreview from 'src/components/component_preview/component_preview.vue'
|
||||||
import { getCssShadow, getCssShadowFilter } from '../../services/theme_data/theme_data.service.js'
|
import { rgb2hex } from 'src/services/color_convert/color_convert.js'
|
||||||
|
import { serializeShadow } from 'src/services/theme_data/iss_serializer.js'
|
||||||
|
import { deserializeShadow } from 'src/services/theme_data/iss_deserializer.js'
|
||||||
|
import { getCssShadow, getCssShadowFilter } from 'src/services/theme_data/css_utils.js'
|
||||||
|
import { findShadow, findColor } from 'src/services/theme_data/theme_data_3.service.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { throttle } from 'lodash'
|
import { throttle, flattenDeep } from 'lodash'
|
||||||
import {
|
import {
|
||||||
faTimes,
|
faTimes,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
|
@ -46,13 +50,14 @@ export default {
|
||||||
'separateInset',
|
'separateInset',
|
||||||
'noPreview',
|
'noPreview',
|
||||||
'disabled',
|
'disabled',
|
||||||
'computeColor',
|
'staticVars',
|
||||||
'compact'
|
'compact'
|
||||||
],
|
],
|
||||||
emits: ['update:modelValue', 'subShadowSelected'],
|
emits: ['update:modelValue', 'subShadowSelected'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
selectedId: 0
|
selectedId: 0,
|
||||||
|
invalid: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -97,7 +102,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
present () {
|
present () {
|
||||||
return this.selected != null && !this.usingFallback
|
return this.selected != null && this.modelValue != null
|
||||||
},
|
},
|
||||||
shadowsAreNull () {
|
shadowsAreNull () {
|
||||||
return this.modelValue == null
|
return this.modelValue == null
|
||||||
|
@ -105,31 +110,38 @@ export default {
|
||||||
currentFallback () {
|
currentFallback () {
|
||||||
return this.fallback?.[this.selectedId]
|
return this.fallback?.[this.selectedId]
|
||||||
},
|
},
|
||||||
usingFallback () {
|
getColorFallback () {
|
||||||
return this.modelValue == null
|
if (this.staticVars && this.selected?.color) {
|
||||||
},
|
const computedColor = findColor(this.selected.color, { dynamicVars: {}, staticVars: this.staticVars }, true)
|
||||||
getFallback () {
|
if (computedColor) return rgb2hex(computedColor)
|
||||||
if (typeof this.computeColor === 'function' && this.selected?.color) {
|
return null
|
||||||
return this.computeColor(this.selected.color)
|
|
||||||
} else {
|
} else {
|
||||||
return this.currentFallback?.color
|
return this.currentFallback?.color
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style () {
|
style () {
|
||||||
try {
|
try {
|
||||||
|
let result
|
||||||
|
const serialized = this.cValue.map(x => serializeShadow(x)).join(',')
|
||||||
|
deserializeShadow(serialized) // validate
|
||||||
|
const expandedShadow = flattenDeep(findShadow(this.cValue, { dynamicVars: {}, staticVars: this.staticVars }))
|
||||||
|
const fixedShadows = expandedShadow.map(x => ({ ...x, color: console.log(x) || rgb2hex(x.color) }))
|
||||||
|
|
||||||
if (this.separateInset) {
|
if (this.separateInset) {
|
||||||
return {
|
result = {
|
||||||
filter: getCssShadowFilter(this.cValue),
|
filter: getCssShadowFilter(fixedShadows),
|
||||||
boxShadow: getCssShadow(this.cValue, true)
|
boxShadow: getCssShadow(fixedShadows, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = {
|
||||||
|
boxShadow: getCssShadow(fixedShadows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
this.invalid = false
|
||||||
boxShadow: getCssShadow(this.cValue)
|
return result
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
console.error('Invalid shadow', e)
|
||||||
border: '1px solid red'
|
this.invalid = true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
>
|
>
|
||||||
<ComponentPreview
|
<ComponentPreview
|
||||||
v-if="!noPreview"
|
v-if="!noPreview"
|
||||||
|
:invalid="invalid"
|
||||||
class="shadow-preview"
|
class="shadow-preview"
|
||||||
:shadow-control="true"
|
:shadow-control="true"
|
||||||
:shadow="selected"
|
:shadow="selected"
|
||||||
|
:preview-style="style"
|
||||||
:disabled="disabled || !present"
|
:disabled="disabled || !present"
|
||||||
@update:shadow="({ axis, value }) => updateProperty(axis, value)"
|
@update:shadow="({ axis, value }) => updateProperty(axis, value)"
|
||||||
/>
|
/>
|
||||||
|
@ -165,7 +167,7 @@
|
||||||
:model-value="selected?.color"
|
:model-value="selected?.color"
|
||||||
:disabled="disabled || !present"
|
:disabled="disabled || !present"
|
||||||
:label="$t('settings.style.common.color')"
|
:label="$t('settings.style.common.color')"
|
||||||
:fallback="getFallback"
|
:fallback="getColorFallback"
|
||||||
:show-optional-tickbox="false"
|
:show-optional-tickbox="false"
|
||||||
name="shadow"
|
name="shadow"
|
||||||
@update:modelValue="e => updateProperty('color', e)"
|
@update:modelValue="e => updateProperty('color', e)"
|
||||||
|
|
|
@ -793,8 +793,10 @@
|
||||||
"text_color": "Text color",
|
"text_color": "Text color",
|
||||||
"icon_color": "Icon color",
|
"icon_color": "Icon color",
|
||||||
"link_color": "Link color",
|
"link_color": "Link color",
|
||||||
|
"border_color": "Border color",
|
||||||
"include_in_rule": "Add to rule",
|
"include_in_rule": "Add to rule",
|
||||||
"test_string": "TEST",
|
"test_string": "TEST",
|
||||||
|
"invalid": "Invalid",
|
||||||
"refresh_preview": "Refresh preview",
|
"refresh_preview": "Refresh preview",
|
||||||
"apply_preview": "Apply",
|
"apply_preview": "Apply",
|
||||||
"text_auto": {
|
"text_auto": {
|
||||||
|
|
|
@ -56,22 +56,7 @@ export const generateTheme = (inputRuleset, callbacks, debug) => {
|
||||||
|
|
||||||
getCssRules(themes3.eager, debug).forEach(rule => {
|
getCssRules(themes3.eager, debug).forEach(rule => {
|
||||||
// Hacks to support multiple selectors on same component
|
// Hacks to support multiple selectors on same component
|
||||||
if (rule.match(/::-webkit-scrollbar-button/)) {
|
onNewRule(rule, false)
|
||||||
const parts = rule.split(/[{}]/g)
|
|
||||||
const newRule = [
|
|
||||||
parts[0],
|
|
||||||
', ',
|
|
||||||
parts[0].replace(/button/, 'thumb'),
|
|
||||||
', ',
|
|
||||||
parts[0].replace(/scrollbar-button/, 'resizer'),
|
|
||||||
' {',
|
|
||||||
parts[1],
|
|
||||||
'}'
|
|
||||||
].join('')
|
|
||||||
onNewRule(newRule, false)
|
|
||||||
} else {
|
|
||||||
onNewRule(rule, false)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
onEagerFinished()
|
onEagerFinished()
|
||||||
|
|
||||||
|
@ -85,22 +70,7 @@ export const generateTheme = (inputRuleset, callbacks, debug) => {
|
||||||
const chunk = chunks[counter]
|
const chunk = chunks[counter]
|
||||||
Promise.all(chunk.map(x => x())).then(result => {
|
Promise.all(chunk.map(x => x())).then(result => {
|
||||||
getCssRules(result.filter(x => x), debug).forEach(rule => {
|
getCssRules(result.filter(x => x), debug).forEach(rule => {
|
||||||
if (rule.match(/\.modal-view/)) {
|
onNewRule(rule, true)
|
||||||
const parts = rule.split(/[{}]/g)
|
|
||||||
const newRule = [
|
|
||||||
parts[0],
|
|
||||||
', ',
|
|
||||||
parts[0].replace(/\.modal-view/, '#modal'),
|
|
||||||
', ',
|
|
||||||
parts[0].replace(/\.modal-view/, '.shout-panel'),
|
|
||||||
' {',
|
|
||||||
parts[1],
|
|
||||||
'}'
|
|
||||||
].join('')
|
|
||||||
onNewRule(newRule, true)
|
|
||||||
} else {
|
|
||||||
onNewRule(rule, true)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
// const t1 = performance.now()
|
// const t1 = performance.now()
|
||||||
// console.debug('Chunk ' + counter + ' took ' + (t1 - t0) + 'ms')
|
// console.debug('Chunk ' + counter + ' took ' + (t1 - t0) + 'ms')
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -24,11 +28,11 @@ export const parseShadow = string => {
|
||||||
if (string.startsWith('$') || string.startsWith('--')) {
|
if (string.startsWith('$') || string.startsWith('--')) {
|
||||||
return string
|
return string
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Invalid shadow definition: ${string}`)
|
throw new Error(`Invalid shadow definition: '${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
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,43 +56,74 @@ export const getAllPossibleCombinations = (array) => {
|
||||||
*
|
*
|
||||||
* @returns {String} CSS selector (or path)
|
* @returns {String} CSS selector (or path)
|
||||||
*/
|
*/
|
||||||
export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelector, isParent) => {
|
export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelector, liteMode, children) => {
|
||||||
|
const isParent = !!children
|
||||||
if (!rule && !isParent) return null
|
if (!rule && !isParent) return null
|
||||||
const component = components[rule.component]
|
const component = components[rule.component]
|
||||||
const { states = {}, variants = {}, selector, outOfTreeSelector } = component
|
const { states = {}, variants = {}, outOfTreeSelector } = component
|
||||||
|
|
||||||
const applicableStates = ((rule.state || []).filter(x => x !== 'normal')).map(state => states[state])
|
const expand = (array = [], subArray = []) => {
|
||||||
|
if (array.length === 0) return subArray.map(x => [x])
|
||||||
|
if (subArray.length === 0) return array.map(x => [x])
|
||||||
|
return array.map(a => {
|
||||||
|
return subArray.map(b => [a, b])
|
||||||
|
}).flat()
|
||||||
|
}
|
||||||
|
|
||||||
|
let componentSelectors = Array.isArray(component.selector) ? component.selector : [component.selector]
|
||||||
|
if (ignoreOutOfTreeSelector || liteMode) componentSelectors = [componentSelectors[0]]
|
||||||
|
componentSelectors = componentSelectors.map(selector => {
|
||||||
|
if (selector === ':root') {
|
||||||
|
return ''
|
||||||
|
} else if (isParent) {
|
||||||
|
return selector
|
||||||
|
} else {
|
||||||
|
if (outOfTreeSelector && !ignoreOutOfTreeSelector) return outOfTreeSelector
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const applicableVariantName = (rule.variant || 'normal')
|
const applicableVariantName = (rule.variant || 'normal')
|
||||||
let applicableVariant = ''
|
let variantSelectors = null
|
||||||
if (applicableVariantName !== 'normal') {
|
if (applicableVariantName !== 'normal') {
|
||||||
applicableVariant = variants[applicableVariantName]
|
variantSelectors = variants[applicableVariantName]
|
||||||
} else {
|
} else {
|
||||||
applicableVariant = variants?.normal ?? ''
|
variantSelectors = variants?.normal ?? ''
|
||||||
}
|
}
|
||||||
|
variantSelectors = Array.isArray(variantSelectors) ? variantSelectors : [variantSelectors]
|
||||||
|
if (ignoreOutOfTreeSelector || liteMode) variantSelectors = [variantSelectors[0]]
|
||||||
|
|
||||||
let realSelector
|
const applicableStates = (rule.state || []).filter(x => x !== 'normal')
|
||||||
if (selector === ':root') {
|
// const applicableStates = (rule.state || [])
|
||||||
realSelector = ''
|
const statesSelectors = applicableStates.map(state => {
|
||||||
} else if (isParent) {
|
const selector = states[state] || ''
|
||||||
realSelector = selector
|
let arraySelector = Array.isArray(selector) ? selector : [selector]
|
||||||
} else {
|
if (ignoreOutOfTreeSelector || liteMode) arraySelector = [arraySelector[0]]
|
||||||
if (outOfTreeSelector && !ignoreOutOfTreeSelector) realSelector = outOfTreeSelector
|
arraySelector
|
||||||
else realSelector = selector
|
.sort((a, b) => {
|
||||||
}
|
if (a.startsWith(':')) return 1
|
||||||
|
if (/^[a-z]/.exec(a)) return -1
|
||||||
|
else return 0
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
return arraySelector
|
||||||
|
})
|
||||||
|
|
||||||
const selectors = [realSelector, applicableVariant, ...applicableStates]
|
const statesSelectorsFlat = statesSelectors.reduce((acc, s) => {
|
||||||
.sort((a, b) => {
|
return expand(acc, s).map(st => st.join(''))
|
||||||
if (a.startsWith(':')) return 1
|
}, [])
|
||||||
if (/^[a-z]/.exec(a)) return -1
|
|
||||||
else return 0
|
const componentVariant = expand(componentSelectors, variantSelectors).map(cv => cv.join(''))
|
||||||
})
|
const componentVariantStates = expand(componentVariant, statesSelectorsFlat).map(cvs => cvs.join(''))
|
||||||
.join('')
|
const selectors = expand(componentVariantStates, children).map(cvsc => cvsc.join(' '))
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
if (rule.parent) {
|
if (rule.parent) {
|
||||||
return (genericRuleToSelector(components)(rule.parent, ignoreOutOfTreeSelector, true) + ' ' + selectors).trim()
|
return genericRuleToSelector(components)(rule.parent, ignoreOutOfTreeSelector, liteMode, selectors)
|
||||||
}
|
}
|
||||||
return selectors.trim()
|
|
||||||
|
return selectors.join(', ').trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 = {
|
||||||
|
@ -37,7 +37,7 @@ const components = {
|
||||||
ChatMessage: null
|
ChatMessage: null
|
||||||
}
|
}
|
||||||
|
|
||||||
const findShadow = (shadows, { dynamicVars, staticVars }) => {
|
export const findShadow = (shadows, { dynamicVars, staticVars }) => {
|
||||||
return (shadows || []).map(shadow => {
|
return (shadows || []).map(shadow => {
|
||||||
let targetShadow
|
let targetShadow
|
||||||
if (typeof shadow === 'string') {
|
if (typeof shadow === 'string') {
|
||||||
|
@ -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…
Add table
Reference in a new issue