728 lines
20 KiB
Go
728 lines
20 KiB
Go
|
package wp
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"github.com/fthvgb1/wp-go/app/cmd/reload"
|
||
|
"github.com/fthvgb1/wp-go/app/wpconfig"
|
||
|
"github.com/fthvgb1/wp-go/helper"
|
||
|
"github.com/fthvgb1/wp-go/helper/maps"
|
||
|
"github.com/fthvgb1/wp-go/helper/number"
|
||
|
"github.com/fthvgb1/wp-go/helper/slice"
|
||
|
str "github.com/fthvgb1/wp-go/helper/strings"
|
||
|
"github.com/fthvgb1/wp-go/safety"
|
||
|
"math"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var scripts = reload.MapBy[string, *Script](func(m *safety.Map[string, *Script]) {
|
||
|
suffix := ".min"
|
||
|
defaultScripts(m, suffix)
|
||
|
})
|
||
|
|
||
|
func addScript(handle string, src string, deps []string, ver string, args any) {
|
||
|
script := NewScript(handle, src, deps, ver, args)
|
||
|
scripts.Store(handle, script)
|
||
|
}
|
||
|
|
||
|
func localize(handle, objectname string, l10n map[string]any) string {
|
||
|
if "jquery" == handle {
|
||
|
handle = "jquery-core"
|
||
|
}
|
||
|
after, ok := maps.GetStrAnyVal[string](l10n, "l10n_print_after")
|
||
|
if ok {
|
||
|
delete(l10n, "l10n_print_after")
|
||
|
}
|
||
|
v, _ := json.Marshal(l10n)
|
||
|
script := fmt.Sprintf("var %s = %s;", objectname, string(v))
|
||
|
if after != "" {
|
||
|
script = str.Join(script, "\n", after, ";")
|
||
|
}
|
||
|
return script
|
||
|
}
|
||
|
|
||
|
func AddStaticLocalize(handle, objectname string, l10n map[string]any) {
|
||
|
addData(handle, "data", localize(handle, objectname, l10n))
|
||
|
}
|
||
|
func AddDynamicLocalize(h *Handle, handle, objectname string, l10n map[string]any) {
|
||
|
AddDynamicData(h, handle, "data", localize(handle, objectname, l10n))
|
||
|
}
|
||
|
|
||
|
func getData(handle, key string) string {
|
||
|
h, ok := scripts.Load(handle)
|
||
|
if !ok {
|
||
|
return ""
|
||
|
}
|
||
|
return strings.Join(h.Extra[key], "\n")
|
||
|
}
|
||
|
func GetData(h *Handle, handle, key string) string {
|
||
|
hh, ok := scripts.Load(handle)
|
||
|
if !ok {
|
||
|
return ""
|
||
|
}
|
||
|
d := hh.Extra[key]
|
||
|
d = append(d, GetDynamicData(h, handle, key))
|
||
|
return strings.Join(d, "\n")
|
||
|
}
|
||
|
|
||
|
func addData(handle, key, data string) {
|
||
|
s, ok := scripts.Load(handle)
|
||
|
if !ok {
|
||
|
s = NewScript(handle, "", nil, "", nil)
|
||
|
}
|
||
|
if s.Extra == nil {
|
||
|
s.Extra = make(map[string][]string)
|
||
|
}
|
||
|
s.Extra[key] = append(s.Extra[key], data)
|
||
|
}
|
||
|
|
||
|
func AddInlineScript(handle, data, position string) {
|
||
|
if handle == "" || data == "" {
|
||
|
return
|
||
|
}
|
||
|
if position != "after" {
|
||
|
position = "before"
|
||
|
}
|
||
|
addData(handle, position, data)
|
||
|
}
|
||
|
|
||
|
func AddInlineStyle(handle, data string) {
|
||
|
if handle == "" || data == "" {
|
||
|
return
|
||
|
}
|
||
|
addData(handle, "after", data)
|
||
|
}
|
||
|
|
||
|
func InlineScripts(handle, position string, display bool) string {
|
||
|
ss := getData(handle, position)
|
||
|
if ss == "" {
|
||
|
return ""
|
||
|
}
|
||
|
scp := strings.Trim(ss, "\n")
|
||
|
if display {
|
||
|
return fmt.Sprintf("<script id='%s-js-%s'>\n%s\n</script>\n", handle, position, scp)
|
||
|
}
|
||
|
return scp
|
||
|
}
|
||
|
|
||
|
func AddScript(handle string, src string, deps []string, ver string, args any) {
|
||
|
script := NewScript(handle, src, deps, ver, args)
|
||
|
scripts.Store(handle, script)
|
||
|
}
|
||
|
|
||
|
type Script struct {
|
||
|
Handle string `json:"handle,omitempty"`
|
||
|
Src string `json:"src,omitempty"`
|
||
|
Deps []string `json:"deps,omitempty"`
|
||
|
Ver string `json:"ver,omitempty"`
|
||
|
Args any `json:"args,omitempty"`
|
||
|
Extra map[string][]string `json:"extra,omitempty"`
|
||
|
Textdomain string `json:"textdomain,omitempty"`
|
||
|
TranslationsPath string `json:"translations_path,omitempty"`
|
||
|
}
|
||
|
|
||
|
func NewScript(handle string, src string, deps []string, ver string, args any) *Script {
|
||
|
return &Script{Handle: handle, Src: src, Deps: deps, Ver: ver, Args: args}
|
||
|
}
|
||
|
|
||
|
func AddDynamicData(h *Handle, handle, key, data string) {
|
||
|
da := helper.GetContextVal(h.C, "__scriptDynamicData__", map[string]map[string][]string{})
|
||
|
m, ok := da[handle]
|
||
|
if !ok {
|
||
|
m = map[string][]string{}
|
||
|
}
|
||
|
m[key] = append(m[key], data)
|
||
|
da[handle] = m
|
||
|
}
|
||
|
|
||
|
func GetDynamicData(h *Handle, handle, key string) string {
|
||
|
da := helper.GetContextVal(h.C, "__scriptDynamicData__", map[string]map[string][]string{})
|
||
|
if len(da) < 1 {
|
||
|
return ""
|
||
|
}
|
||
|
m, ok := da[handle]
|
||
|
if !ok {
|
||
|
return ""
|
||
|
}
|
||
|
mm, ok := m[key]
|
||
|
if !ok {
|
||
|
return ""
|
||
|
}
|
||
|
return strings.Join(mm, "\n")
|
||
|
}
|
||
|
|
||
|
func SetTranslation(handle, domain, path string) {
|
||
|
hh, ok := scripts.Load(handle)
|
||
|
if !ok {
|
||
|
return
|
||
|
}
|
||
|
if !slice.IsContained(hh.Deps, handle) {
|
||
|
hh.Deps = append(hh.Deps, "wp-i18n")
|
||
|
}
|
||
|
if domain == "" {
|
||
|
domain = "default"
|
||
|
}
|
||
|
hh.Textdomain = domain
|
||
|
hh.TranslationsPath = path
|
||
|
}
|
||
|
|
||
|
var __elements = map[string]string{
|
||
|
"link": "a:where(:not(.wp-element-button))", // The `where` is needed to lower the specificity.
|
||
|
"heading": "h1, h2, h3, h4, h5, h6",
|
||
|
"h1": "h1",
|
||
|
"h2": "h2",
|
||
|
"h3": "h3",
|
||
|
"h4": "h4",
|
||
|
"h5": "h5",
|
||
|
"h6": "h6",
|
||
|
// We have the .wp-block-button__link class so that this will target older buttons that have been serialized.
|
||
|
"button": ".wp-element-button, .wp-block-button__link",
|
||
|
// The block classes are necessary to target older content that won't use the new class names.
|
||
|
"caption": ".wp-element-caption, .wp-block-audio figcaption, .wp-block-embed figcaption, .wp-block-gallery figcaption, .wp-block-image figcaption, .wp-block-table figcaption, .wp-block-video figcaption",
|
||
|
"cite": "cite",
|
||
|
}
|
||
|
|
||
|
const RootBlockSelector = "body"
|
||
|
|
||
|
type node struct {
|
||
|
Path []string
|
||
|
Selector string
|
||
|
}
|
||
|
|
||
|
var __validElementPseudoSelectors = map[string][]string{
|
||
|
"link": {":link", ":any-link", ":visited", ":hover", ":focus", ":active"},
|
||
|
"button": {":link", ":any-link", ":visited", ":hover", ":focus", ":active"},
|
||
|
}
|
||
|
|
||
|
var blockSupportFeatureLevelSelectors = map[string]string{
|
||
|
"__experimentalBorder": "border",
|
||
|
"color": "color",
|
||
|
"spacing": "spacing",
|
||
|
"typography": "typography",
|
||
|
}
|
||
|
|
||
|
func appendToSelector(selector, toAppend, position string) string {
|
||
|
s := strings.Split(selector, ",")
|
||
|
if position == "" {
|
||
|
position = "right"
|
||
|
}
|
||
|
return strings.Join(slice.Map(s, func(t string) string {
|
||
|
var l, r string
|
||
|
if position == "right" {
|
||
|
l = t
|
||
|
r = toAppend
|
||
|
} else {
|
||
|
l = toAppend
|
||
|
r = t
|
||
|
}
|
||
|
return str.Join(l, r)
|
||
|
}), ",")
|
||
|
}
|
||
|
|
||
|
func __removeComment(m map[string]any) {
|
||
|
delete(m, "//")
|
||
|
for _, v := range m {
|
||
|
mm, ok := v.(map[string]any)
|
||
|
if ok {
|
||
|
__removeComment(mm)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func scopeSelector(scope, selector string) string {
|
||
|
scopes := strings.Split(scope, ",")
|
||
|
selectors := strings.Split(selector, ",")
|
||
|
var a []string
|
||
|
for _, outer := range scopes {
|
||
|
outer = strings.Trim(outer, " \t\n\r\x00\x0B")
|
||
|
for _, inner := range selectors {
|
||
|
inner = strings.Trim(inner, " \t\n\r\x00\x0B")
|
||
|
if outer != "" && inner != "" {
|
||
|
a = append(a, str.Join(outer, " ", inner))
|
||
|
} else if outer == "" {
|
||
|
a = append(a, inner)
|
||
|
} else if inner == "" {
|
||
|
a = append(a, outer)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return strings.Join(a, ", ")
|
||
|
}
|
||
|
|
||
|
func getBlockNodes(m map[string]any) []map[string]any {
|
||
|
selectors, _ := maps.GetStrAnyVal[map[string]any](m, "blocks_metadata")
|
||
|
mm, _ := maps.GetStrAnyVal[map[string]any](m, "theme_json.styles.blocks")
|
||
|
var nodes []map[string]any
|
||
|
for k, v := range mm {
|
||
|
vv, ok := v.(map[string]any)
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
s, _ := maps.GetStrAnyVal[string](selectors, str.Join(k, ".supports.selector"))
|
||
|
d, _ := maps.GetStrAnyVal[string](selectors, str.Join(k, ".duotone"))
|
||
|
f, _ := maps.GetStrAnyVal[string](selectors, str.Join(k, ".features"))
|
||
|
n, ok := maps.GetStrAnyVal[map[string]any](vv, "variations")
|
||
|
var variationSelectors []node
|
||
|
if ok {
|
||
|
for variation := range n {
|
||
|
ss, _ := maps.GetStrAnyVal[string](selectors, str.Join(k, ".styleVariations.", variation))
|
||
|
variationSelectors = append(variationSelectors, node{
|
||
|
Path: []string{"styles", "blocks", k, "variations", variation},
|
||
|
Selector: ss,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
nodes = append(nodes, map[string]any{
|
||
|
"name": k,
|
||
|
"path": []string{"styles", "blocks", k},
|
||
|
"selector": s,
|
||
|
"duotone": d,
|
||
|
"features": f,
|
||
|
"variations": variationSelectors,
|
||
|
})
|
||
|
e, ok := maps.GetStrAnyVal[map[string]any](vv, "elements")
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
for element, vvv := range e {
|
||
|
_, ok = vvv.(map[string]any)
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
key := str.Join(k, ".elements.", element)
|
||
|
selector, _ := maps.GetStrAnyVal[string](selectors, key)
|
||
|
nodes = append(nodes, map[string]any{
|
||
|
"path": []string{"styles", "blocks", k, "elements", element},
|
||
|
"selector": selector,
|
||
|
})
|
||
|
if val, ok := __validElementPseudoSelectors[element]; ok {
|
||
|
for _, ss := range val {
|
||
|
_, ok = maps.GetStrAnyVal[string](vv, str.Join("elements.", ss))
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
nodes = append(nodes, map[string]any{
|
||
|
"path": []string{"styles", "blocks", k, "elements", element},
|
||
|
"selector": appendToSelector(selector, ss, ""),
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return nodes
|
||
|
}
|
||
|
|
||
|
func getSettingNodes(m, setting map[string]any) []node {
|
||
|
var nodes []node
|
||
|
nodes = append(nodes, node{
|
||
|
Path: []string{"settings"},
|
||
|
Selector: RootBlockSelector,
|
||
|
})
|
||
|
selectors, _ := maps.GetStrAnyVal[map[string]any](m, "blocks_metadata")
|
||
|
s, ok := maps.GetStrAnyVal[map[string]any](setting, "settings.blocks")
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
for name := range s {
|
||
|
selector, ok := maps.GetStrAnyVal[string](selectors, str.Join(name, ".supports.selector"))
|
||
|
if ok {
|
||
|
nodes = append(nodes, node{
|
||
|
Path: []string{"settings", "blocks", name},
|
||
|
Selector: selector,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
return nodes
|
||
|
}
|
||
|
|
||
|
type ThemeJson struct {
|
||
|
blocksMetaData map[string]any
|
||
|
themeJson map[string]any
|
||
|
}
|
||
|
|
||
|
var presetsMetadata = []presetMeta{
|
||
|
{
|
||
|
path: []string{"color", "palette"},
|
||
|
preventOverride: []string{"color", "defaultPalette"},
|
||
|
useDefaultNames: false,
|
||
|
valueKey: "color",
|
||
|
valueFunc: nil,
|
||
|
cssVars: "--wp--preset--color--$slug",
|
||
|
classes: map[string]string{
|
||
|
".has-$slug-color": "color",
|
||
|
".has-$slug-background-color": "background-color",
|
||
|
".has-$slug-border-color": "border-color",
|
||
|
},
|
||
|
properties: []string{"color", "background-color", "border-color"},
|
||
|
}, {
|
||
|
path: []string{"color", "gradients"},
|
||
|
preventOverride: []string{"color", "defaultGradients"},
|
||
|
useDefaultNames: false,
|
||
|
valueKey: "gradient",
|
||
|
valueFunc: nil,
|
||
|
cssVars: "--wp--preset--gradient--$slug",
|
||
|
classes: map[string]string{
|
||
|
".has-$slug-gradient-background": "background",
|
||
|
},
|
||
|
properties: []string{"background"},
|
||
|
}, {
|
||
|
path: []string{"color", "duotone"},
|
||
|
preventOverride: []string{"color", "defaultDuotone"},
|
||
|
useDefaultNames: false,
|
||
|
valueKey: "",
|
||
|
valueFunc: wpGetDuotoneFilterProperty,
|
||
|
cssVars: "--wp--preset--duotone--$slug",
|
||
|
classes: map[string]string{},
|
||
|
properties: []string{"filter"},
|
||
|
}, {
|
||
|
path: []string{"typography", "fontSizes"},
|
||
|
preventOverride: []string{},
|
||
|
useDefaultNames: true,
|
||
|
valueKey: "",
|
||
|
valueFunc: wpGetTypographyFontSizeValue,
|
||
|
cssVars: "--wp--preset--font-size--$slug",
|
||
|
classes: map[string]string{
|
||
|
".has-$slug-font-size": "font-size",
|
||
|
},
|
||
|
properties: []string{"font-size"},
|
||
|
}, {
|
||
|
path: []string{"typography", "fontFamilies"},
|
||
|
preventOverride: []string{},
|
||
|
useDefaultNames: false,
|
||
|
valueKey: "fontFamily",
|
||
|
valueFunc: nil,
|
||
|
cssVars: "--wp--preset--font-family--$slug",
|
||
|
classes: map[string]string{
|
||
|
".has-$slug-font-family": "font-family",
|
||
|
},
|
||
|
properties: []string{"font-family"},
|
||
|
}, {
|
||
|
path: []string{"spacing", "spacingSizes"},
|
||
|
preventOverride: []string{},
|
||
|
useDefaultNames: true,
|
||
|
valueKey: "size",
|
||
|
valueFunc: nil,
|
||
|
cssVars: "--wp--preset--spacing--$slug",
|
||
|
classes: map[string]string{},
|
||
|
properties: []string{"padding", "margin"},
|
||
|
}, {
|
||
|
path: []string{"shadow", "presets"},
|
||
|
preventOverride: []string{"shadow", "defaultPresets"},
|
||
|
useDefaultNames: false,
|
||
|
valueKey: "shadow",
|
||
|
valueFunc: nil,
|
||
|
cssVars: "--wp--preset--shadow--$slug",
|
||
|
classes: map[string]string{},
|
||
|
properties: []string{"box-shadow"},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
type presetMeta struct {
|
||
|
path []string
|
||
|
preventOverride []string
|
||
|
useDefaultNames bool
|
||
|
valueFunc func(map[string]string, map[string]any) string
|
||
|
valueKey string
|
||
|
cssVars string
|
||
|
classes map[string]string
|
||
|
properties []string
|
||
|
}
|
||
|
|
||
|
type declaration struct {
|
||
|
name string
|
||
|
value string
|
||
|
}
|
||
|
|
||
|
func wpGetDuotoneFilterProperty(preset map[string]string, _ map[string]any) string {
|
||
|
v, ok := preset["colors"]
|
||
|
if ok && "unset" == v {
|
||
|
return "none"
|
||
|
}
|
||
|
id, ok := preset["slug"]
|
||
|
if ok {
|
||
|
id = str.Join("wp-duotone-", id)
|
||
|
}
|
||
|
return str.Join(`url('#`, id, "')")
|
||
|
}
|
||
|
|
||
|
func wpGetTypographyFontSizeValue(preset map[string]string, m map[string]any) string {
|
||
|
size, ok := preset["size"]
|
||
|
if !ok {
|
||
|
return ""
|
||
|
}
|
||
|
if size == "" || size == "0" {
|
||
|
return size
|
||
|
}
|
||
|
origin := "custom"
|
||
|
if !wpconfig.HasThemeJson() {
|
||
|
origin = "theme"
|
||
|
}
|
||
|
typographySettings, ok := maps.GetStrAnyVal[map[string]any](m, "typography")
|
||
|
if !ok {
|
||
|
return size
|
||
|
}
|
||
|
fluidSettings, ok := maps.GetStrAnyVal[map[string]any](typographySettings, "fluid")
|
||
|
|
||
|
//todo so complex dying 👻
|
||
|
_ = fluidSettings
|
||
|
_ = origin
|
||
|
return size
|
||
|
}
|
||
|
|
||
|
var __themeJson *safety.Var[ThemeJson]
|
||
|
|
||
|
func GetThemeJson() ThemeJson {
|
||
|
return __themeJson.Load()
|
||
|
}
|
||
|
|
||
|
func wpGetTypographyValueAndUnit(value string, options map[string]any) {
|
||
|
/*options := maps.Merge(options, map[string]any{
|
||
|
"coerce_to": "",
|
||
|
"root_size_value": 16,
|
||
|
"acceptable_units": []string{"rem", "px", "em"},
|
||
|
})
|
||
|
u, _ := maps.GetStrAnyVal[[]string](options, "acceptable_units")
|
||
|
acceptableUnitsGroup := strings.Join(u, "|")*/
|
||
|
|
||
|
}
|
||
|
|
||
|
func computeThemeVars(m map[string]any) []declaration {
|
||
|
//todo ......
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func computePresetVars(m map[string]any, origins []string) []declaration {
|
||
|
var declarations []declaration
|
||
|
for _, metadatum := range presetsMetadata {
|
||
|
slug := getSettingsValuesBySlug(m, metadatum, origins)
|
||
|
for k, v := range slug {
|
||
|
declarations = append(declarations, declaration{
|
||
|
name: strings.Replace(metadatum.cssVars, "$slug", k, -1),
|
||
|
value: v,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
return declarations
|
||
|
}
|
||
|
|
||
|
func getSettingsValuesBySlug(m map[string]any, meta presetMeta, origins []string) map[string]string {
|
||
|
perOrigin := maps.GetStrAnyValWithDefaults[map[string]any](m, strings.Join(meta.path, "."), nil)
|
||
|
r := map[string]string{}
|
||
|
for _, origin := range origins {
|
||
|
if vv, ok := maps.GetStrAnyVal[[]map[string]string](perOrigin, origin); ok {
|
||
|
for _, preset := range vv {
|
||
|
slug := preset["slug"]
|
||
|
value := ""
|
||
|
if vv, ok := preset[meta.valueKey]; ok && vv != "" {
|
||
|
value = vv
|
||
|
} else if meta.valueFunc != nil {
|
||
|
value = meta.valueFunc(preset, m)
|
||
|
}
|
||
|
r[slug] = value
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func setSpacingSizes(t ThemeJson) {
|
||
|
m, _ := maps.GetStrAnyVal[map[string]any](t.themeJson, "settings.spacing.spacingScale")
|
||
|
unit, _ := maps.GetStrAnyVal[string](m, "unit")
|
||
|
currentStep, _ := maps.GetStrAnyVal[float64](m, "mediumStep")
|
||
|
mediumStep := currentStep
|
||
|
steps, _ := maps.GetStrAnyVal[float64](m, "steps")
|
||
|
operator, _ := maps.GetStrAnyVal[string](m, "operator")
|
||
|
increment, _ := maps.GetStrAnyVal[float64](m, "increment")
|
||
|
stepsMidPoint := math.Round(steps / 2)
|
||
|
reminder := float64(0)
|
||
|
xSmallCount := ""
|
||
|
var sizes []map[string]string
|
||
|
slug := 40
|
||
|
for i := stepsMidPoint - 1; i > 0 && slug > 0 && steps > 1; i-- {
|
||
|
if "+" == operator {
|
||
|
currentStep -= increment
|
||
|
} else if increment > 1 {
|
||
|
currentStep /= increment
|
||
|
} else {
|
||
|
currentStep *= increment
|
||
|
}
|
||
|
if currentStep <= 0 {
|
||
|
reminder = i
|
||
|
break
|
||
|
}
|
||
|
name := "small"
|
||
|
if i != stepsMidPoint-1 {
|
||
|
name = str.Join(xSmallCount, "X-Small")
|
||
|
}
|
||
|
sizes = append(sizes, map[string]string{
|
||
|
"name": name,
|
||
|
"slug": number.IntToString(slug),
|
||
|
"size": fmt.Sprintf("%v%s", number.Round(currentStep, 2), unit),
|
||
|
})
|
||
|
if i == stepsMidPoint-2 {
|
||
|
xSmallCount = strconv.Itoa(2)
|
||
|
}
|
||
|
if i < stepsMidPoint-2 {
|
||
|
n := str.ToInt[int](xSmallCount)
|
||
|
n++
|
||
|
xSmallCount = strconv.Itoa(n)
|
||
|
}
|
||
|
slug -= 10
|
||
|
}
|
||
|
slice.ReverseSelf(sizes)
|
||
|
sizes = append(sizes, map[string]string{
|
||
|
"name": "Medium",
|
||
|
"slug": "50",
|
||
|
"size": str.Join(number.ToString(mediumStep), unit),
|
||
|
})
|
||
|
currentStep = mediumStep
|
||
|
slug = 60
|
||
|
xLargeCount := ""
|
||
|
stepsAbove := steps - stepsMidPoint + reminder
|
||
|
for aboveMidpointCount := float64(0); aboveMidpointCount < stepsAbove; aboveMidpointCount++ {
|
||
|
if "+" == operator {
|
||
|
currentStep += increment
|
||
|
} else if increment >= 1 {
|
||
|
currentStep *= increment
|
||
|
} else {
|
||
|
currentStep /= increment
|
||
|
}
|
||
|
name := "Large"
|
||
|
if 0 != aboveMidpointCount {
|
||
|
name = str.Join(xLargeCount, "X-Large")
|
||
|
}
|
||
|
sizes = append(sizes, map[string]string{
|
||
|
"name": name,
|
||
|
"slug": strconv.Itoa(slug),
|
||
|
"size": fmt.Sprintf("%v%s", number.Round(currentStep, 2), unit),
|
||
|
})
|
||
|
if aboveMidpointCount == 1 {
|
||
|
xLargeCount = strconv.Itoa(2)
|
||
|
}
|
||
|
if aboveMidpointCount > 1 {
|
||
|
x := str.ToInt[int](xLargeCount)
|
||
|
x++
|
||
|
xLargeCount = strconv.Itoa(x)
|
||
|
}
|
||
|
slug += 10
|
||
|
}
|
||
|
if steps <= 7 {
|
||
|
for i := 0; i < len(sizes); i++ {
|
||
|
sizes[i]["name"] = strconv.Itoa(i + 1)
|
||
|
}
|
||
|
}
|
||
|
maps.SetStrAnyVal(t.themeJson, "settings.spacing.spacingSizes.default", sizes)
|
||
|
}
|
||
|
|
||
|
func (j ThemeJson) getCssVariables(settingNodes []node, origins []string) string {
|
||
|
var s strings.Builder
|
||
|
for _, settingNode := range settingNodes {
|
||
|
if "" == settingNode.Selector {
|
||
|
continue
|
||
|
}
|
||
|
n := maps.GetStrAnyValWithDefaults[map[string]any](j.themeJson, strings.Join(settingNode.Path, "."), nil)
|
||
|
declarations := computePresetVars(n, origins)
|
||
|
declarations = append(declarations, computeThemeVars(j.themeJson)...)
|
||
|
s.WriteString(toRuleset(settingNode.Selector, declarations))
|
||
|
}
|
||
|
return s.String()
|
||
|
}
|
||
|
|
||
|
func toRuleset(selector string, declarations []declaration) string {
|
||
|
if len(declarations) < 1 {
|
||
|
return ""
|
||
|
}
|
||
|
s := slice.Reduce(declarations, func(t declaration, r string) string {
|
||
|
return str.Join(r, t.name, ":", t.value, ";")
|
||
|
}, "")
|
||
|
return str.Join(selector, "{", s, "}")
|
||
|
}
|
||
|
|
||
|
func getStyleNodes(t ThemeJson) []node {
|
||
|
var styleNodes = []node{
|
||
|
{[]string{"styles"}, "body"},
|
||
|
}
|
||
|
m := maps.GetStrAnyValWithDefaults[map[string]any](t.themeJson, "styles.elements", nil)
|
||
|
if len(m) < 1 {
|
||
|
return nil
|
||
|
}
|
||
|
for e, s := range __elements {
|
||
|
_, ok := m[e]
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
styleNodes = append(styleNodes, node{[]string{"styles", "elements", e}, s})
|
||
|
ss, ok := __validElementPseudoSelectors[e]
|
||
|
if ok {
|
||
|
for _, sel := range ss {
|
||
|
if maps.IsExists(__elements, sel) {
|
||
|
styleNodes = append(styleNodes, node{
|
||
|
Path: []string{"styles", "elements", e},
|
||
|
Selector: appendToSelector(s, sel, ""),
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
blocks, _ := maps.GetStrAnyVal[map[string]any](t.blocksMetaData, "theme_json.styles.blocks")
|
||
|
maps.SetStrAnyVal(t.themeJson, "styles.blocks", blocks)
|
||
|
blockNodes := getBlockNodes(t.blocksMetaData)
|
||
|
for _, blockNode := range blockNodes {
|
||
|
p, ok := maps.GetStrAnyVal[[]string](blockNode, "path")
|
||
|
s, oo := maps.GetStrAnyVal[string](blockNode, "selector")
|
||
|
if ok && oo {
|
||
|
styleNodes = append(styleNodes, node{Path: p, Selector: s})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return styleNodes
|
||
|
}
|
||
|
|
||
|
var validOrigins = []string{"default", "theme", "custom"}
|
||
|
|
||
|
func GetStyletSheet(t ThemeJson, types, origins []string, options map[string]string) string {
|
||
|
styleNodes := getStyleNodes(t)
|
||
|
settingsNodes := getSettingNodes(t.blocksMetaData, t.themeJson)
|
||
|
if types == nil && !wpconfig.HasThemeJson() {
|
||
|
types = []string{"variables", "presets", "base-layout-styles"}
|
||
|
} else if types == nil {
|
||
|
types = []string{"variables", "styles", "presets"}
|
||
|
}
|
||
|
if origins == nil {
|
||
|
origins = validOrigins
|
||
|
}
|
||
|
rootStyleKey, _ := slice.SearchFirst(styleNodes, func(n node) bool {
|
||
|
return n.Selector == RootBlockSelector
|
||
|
})
|
||
|
rootSettingsKey, _ := slice.SearchFirst(settingsNodes, func(n node) bool {
|
||
|
return n.Selector == RootBlockSelector
|
||
|
})
|
||
|
if os, ok := options["scope"]; ok {
|
||
|
for i := range settingsNodes {
|
||
|
settingsNodes[i].Selector = scopeSelector(os, settingsNodes[i].Selector)
|
||
|
}
|
||
|
for i := range styleNodes {
|
||
|
styleNodes[i].Selector = scopeSelector(os, styleNodes[i].Selector)
|
||
|
}
|
||
|
}
|
||
|
if or, ok := options["root_selector"]; ok && or != "" {
|
||
|
if rootSettingsKey > -1 {
|
||
|
settingsNodes[rootSettingsKey].Selector = or
|
||
|
}
|
||
|
if rootStyleKey > -1 && rootStyleKey < len(settingsNodes) {
|
||
|
settingsNodes[rootStyleKey].Selector = or
|
||
|
}
|
||
|
}
|
||
|
var s string
|
||
|
if slice.IsContained(types, "variables") {
|
||
|
s = t.getCssVariables(settingsNodes, origins)
|
||
|
slice.Delete(&types, slice.IndexOf(types, "variables"))
|
||
|
}
|
||
|
if slice.IsContained(types, "styles") {
|
||
|
s = t.getCssVariables(settingsNodes, origins)
|
||
|
}
|
||
|
|
||
|
return s
|
||
|
}
|