Commit 261e2e58 authored by Jan Köster's avatar Jan Köster
Browse files

test

parent d80b1f5d
Loading
Loading
Loading
Loading
+143 −0
Changes for editor/html/css/editor.css: 143 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1162,3 +1162,146 @@ dialog label {
.media-browse-field button {
    white-space: nowrap;
}

/* Color Var / Custom Picker */
.color-mode-toggle {
    display: flex;
    border: 1px solid var(--border);
    border-radius: 3px;
    overflow: hidden;
    margin-bottom: 4px;
}

.color-mode-btn {
    flex: 1;
    padding: 3px 6px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    border: none;
    cursor: pointer;
    font-size: 11px;
    font-weight: 500;
    font-family: inherit;
    transition: background 0.15s, color 0.15s;
}

.color-mode-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.color-mode-btn.active {
    background: var(--accent);
    color: var(--bg-primary);
}

.color-var-panel {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.color-var-select {
    width: 100%;
    padding: 5px 8px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: 3px;
    font-size: 12px;
    font-family: inherit;
}

.color-var-manual {
    width: 100%;
    padding: 5px 8px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: 3px;
    font-size: 11px;
    font-family: monospace;
    box-sizing: border-box;
}

.color-var-manual:focus,
.color-var-select:focus {
    outline: none;
    border-color: var(--accent);
}

.color-custom-panel {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.color-custom-row {
    display: flex;
    gap: 6px;
    align-items: center;
}

.color-hex-input {
    width: 36px;
    height: 28px;
    padding: 1px 2px;
    border: 1px solid var(--border);
    border-radius: 3px;
    cursor: pointer;
    background: none;
    flex-shrink: 0;
}

.color-alpha-wrap {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 5px;
}

.color-alpha-input {
    flex: 1;
    cursor: pointer;
    accent-color: var(--accent);
    height: 4px;
}

.color-alpha-label {
    font-size: 11px;
    color: var(--text-muted);
    min-width: 32px;
    text-align: right;
}

.color-preview-swatch {
    width: 28px;
    height: 28px;
    border-radius: 3px;
    border: 1px solid var(--border);
    flex-shrink: 0;
    position: relative;
    overflow: hidden;
    background-color: #fff;
    background-image:
        linear-gradient(45deg, #bbb 25%, transparent 25%),
        linear-gradient(-45deg, #bbb 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #bbb 75%),
        linear-gradient(-45deg, transparent 75%, #bbb 75%);
    background-size: 8px 8px;
    background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
}

.color-preview-swatch-inner {
    position: absolute;
    inset: 0;
    border-radius: 2px;
}

.color-preview-value {
    font-size: 10px;
    color: var(--text-muted);
    font-family: monospace;
    word-break: break-all;
    line-height: 1.3;
}
+170 −5
Changes for editor/html/js/properties.js: 170 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -157,6 +157,173 @@ var PropertiesPanel = (function() {
        container.appendChild(form);
    }

    var BLOGI_THEME_VARS = [
        { label: '-- Theme-Variable wählen --', value: '' },
        { label: '--blogi-accent',       value: 'var(--blogi-accent)' },
        { label: '--blogi-accent-dark',  value: 'var(--blogi-accent-dark)' },
        { label: '--blogi-text',         value: 'var(--blogi-text)' },
        { label: '--blogi-text-muted',   value: 'var(--blogi-text-muted)' },
        { label: '--blogi-bg',           value: 'var(--blogi-bg)' },
        { label: '--blogi-bg-alt',       value: 'var(--blogi-bg-alt)' },
        { label: '--blogi-surface',      value: 'var(--blogi-surface)' },
        { label: '--blogi-border',       value: 'var(--blogi-border)' },
        { label: '--blogi-error',        value: 'var(--blogi-error)' },
        { label: '--blogi-nav-active',   value: 'var(--blogi-nav-active)' },
        { label: 'transparent',          value: 'transparent' }
    ];

    function _parseRgba(v) {
        if (!v) return { hex: '#000000', alpha: 100 };
        var m = v.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)/);
        if (m) {
            var r = parseInt(m[1]), g = parseInt(m[2]), b = parseInt(m[3]);
            var a = m[4] !== undefined ? Math.round(parseFloat(m[4]) * 100) : 100;
            return {
                hex: '#' + ('0'+r.toString(16)).slice(-2) + ('0'+g.toString(16)).slice(-2) + ('0'+b.toString(16)).slice(-2),
                alpha: Math.max(0, Math.min(100, a))
            };
        }
        if (/^#[0-9a-fA-F]{6}/.test(v)) return { hex: v.slice(0, 7), alpha: 100 };
        if (/^#[0-9a-fA-F]{3}$/.test(v)) {
            var c = v.slice(1);
            return { hex: '#'+c[0]+c[0]+c[1]+c[1]+c[2]+c[2], alpha: 100 };
        }
        return { hex: '#000000', alpha: 100 };
    }

    function _hexAlphaToString(hex, alpha) {
        var r = parseInt(hex.slice(1,3), 16), g = parseInt(hex.slice(3,5), 16), b = parseInt(hex.slice(5,7), 16);
        if (alpha >= 100) return 'rgb(' + r + ', ' + g + ', ' + b + ')';
        return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + (alpha / 100).toFixed(2) + ')';
    }

    function _renderColorField(group, field, value) {
        var isVarMode = !value || value.indexOf('var(') === 0 || value.slice(0,2) === '--' || value === 'transparent';
        var mode = isVarMode ? 'var' : 'custom';
        var parsed = _parseRgba(value);

        var hiddenInput = document.createElement('input');
        hiddenInput.type = 'hidden';
        hiddenInput.name = field.key;
        hiddenInput.value = value || '';

        var toggle = document.createElement('div');
        toggle.className = 'color-mode-toggle';
        var varBtn = document.createElement('button');
        varBtn.type = 'button';
        varBtn.className = 'color-mode-btn' + (mode === 'var' ? ' active' : '');
        varBtn.textContent = 'Theme Var';
        var customBtn = document.createElement('button');
        customBtn.type = 'button';
        customBtn.className = 'color-mode-btn' + (mode === 'custom' ? ' active' : '');
        customBtn.textContent = 'Custom';
        toggle.appendChild(varBtn);
        toggle.appendChild(customBtn);

        // --- Var panel ---
        var varPanel = document.createElement('div');
        varPanel.className = 'color-var-panel';
        varPanel.style.display = mode === 'var' ? '' : 'none';

        var varSelect = document.createElement('select');
        varSelect.className = 'color-var-select';
        var inPredefined = false;
        for (var vi = 0; vi < BLOGI_THEME_VARS.length; vi++) {
            var tvOpt = document.createElement('option');
            tvOpt.value = BLOGI_THEME_VARS[vi].value;
            tvOpt.textContent = BLOGI_THEME_VARS[vi].label;
            if (value && value === BLOGI_THEME_VARS[vi].value) { tvOpt.selected = true; inPredefined = true; }
            varSelect.appendChild(tvOpt);
        }
        varPanel.appendChild(varSelect);

        var varManual = document.createElement('input');
        varManual.type = 'text';
        varManual.className = 'color-var-manual';
        varManual.placeholder = 'var(--eigene-variable)';
        if (isVarMode && !inPredefined && value) varManual.value = value;
        varPanel.appendChild(varManual);

        // --- Custom panel ---
        var customPanel = document.createElement('div');
        customPanel.className = 'color-custom-panel';
        customPanel.style.display = mode === 'custom' ? '' : 'none';

        var customRow = document.createElement('div');
        customRow.className = 'color-custom-row';

        var hexInput = document.createElement('input');
        hexInput.type = 'color';
        hexInput.className = 'color-hex-input';
        hexInput.value = parsed.hex;

        var alphaWrap = document.createElement('div');
        alphaWrap.className = 'color-alpha-wrap';
        var alphaInput = document.createElement('input');
        alphaInput.type = 'range';
        alphaInput.className = 'color-alpha-input';
        alphaInput.min = '0'; alphaInput.max = '100';
        alphaInput.value = String(parsed.alpha);
        var alphaLabel = document.createElement('span');
        alphaLabel.className = 'color-alpha-label';
        alphaLabel.textContent = parsed.alpha + '%';
        alphaWrap.appendChild(alphaInput);
        alphaWrap.appendChild(alphaLabel);

        var swatch = document.createElement('div');
        swatch.className = 'color-preview-swatch';

        var swatchInner = document.createElement('div');
        swatchInner.className = 'color-preview-swatch-inner';
        swatchInner.style.background = (!isVarMode && value) ? value : _hexAlphaToString(parsed.hex, parsed.alpha);
        swatch.appendChild(swatchInner);

        customRow.appendChild(hexInput);
        customRow.appendChild(alphaWrap);
        customRow.appendChild(swatch);
        customPanel.appendChild(customRow);

        var previewVal = document.createElement('div');
        previewVal.className = 'color-preview-value';
        previewVal.textContent = value || '';
        customPanel.appendChild(previewVal);

        function updateValue() {
            var newVal;
            if (mode === 'var') {
                newVal = varSelect.value || varManual.value.trim() || '';
            } else {
                newVal = _hexAlphaToString(hexInput.value, parseInt(alphaInput.value, 10));
            }
            hiddenInput.value = newVal;
            previewVal.textContent = newVal;
            alphaLabel.textContent = alphaInput.value + '%';
            try { swatchInner.style.background = newVal; } catch(e) {}
            hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
        }

        function switchMode(newMode) {
            mode = newMode;
            varBtn.classList.toggle('active', mode === 'var');
            customBtn.classList.toggle('active', mode === 'custom');
            varPanel.style.display = mode === 'var' ? '' : 'none';
            customPanel.style.display = mode === 'custom' ? '' : 'none';
            updateValue();
        }

        varBtn.addEventListener('click', function() { switchMode('var'); });
        customBtn.addEventListener('click', function() { switchMode('custom'); });
        varSelect.addEventListener('change', function() { varManual.value = ''; updateValue(); });
        varManual.addEventListener('input', function() { if (varManual.value.trim()) varSelect.value = ''; updateValue(); });
        hexInput.addEventListener('input', updateValue);
        alphaInput.addEventListener('input', updateValue);

        group.appendChild(hiddenInput);
        group.appendChild(toggle);
        group.appendChild(varPanel);
        group.appendChild(customPanel);
    }

    function _renderFieldsInto(panel, fields, properties, form) {
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
@@ -196,11 +363,9 @@ var PropertiesPanel = (function() {
                        input.appendChild(opt);
                    }
                } else if (field.type === 'color' || field.type === 'color_var') {
                    input = document.createElement('input');
                    input.type = 'text';
                    input.name = field.key;
                    input.value = value;
                    input.placeholder = field.placeholder || '#000000 oder var(--name)';
                    _renderColorField(group, field, value);
                    panel.appendChild(group);
                    continue;
                } else if (field.type === 'html' || field.type === 'richtext') {
                    var rteWrap = document.createElement('div');
                    rteWrap.className = 'rte-wrap';
+18 −0
Changes for editor/widgets/popup/popup.cpp: 18 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -625,6 +625,24 @@ extern "C" {
                    mediaCSS += " }";
                }

                // Mobile + Light mode overrides
                std::string mobileLightBtnCSS;
                if (validCss(ml_buttonBgColor))   mobileLightBtnCSS += " background-color: " + ml_buttonBgColor + " !important;";
                if (validCss(ml_buttonTextColor)) mobileLightBtnCSS += " color: " + ml_buttonTextColor + " !important;";

                std::string mobileLightPopupCSS;
                if (validCss(ml_popupBgColor))   mobileLightPopupCSS += " background: " + ml_popupBgColor + " !important;";
                if (validCss(ml_popupTextColor)) mobileLightPopupCSS += " color: " + ml_popupTextColor + " !important;";

                if (!mobileLightBtnCSS.empty() || !mobileLightPopupCSS.empty()) {
                    mediaCSS += "@media (max-width: 768px) and (prefers-color-scheme: light) {";
                    if (!mobileLightBtnCSS.empty())
                        mediaCSS += " ." + responsiveClass + "-btn {" + mobileLightBtnCSS + " }";
                    if (!mobileLightPopupCSS.empty())
                        mediaCSS += " ." + responsiveClass + "-dialog {" + mobileLightPopupCSS + " }";
                    mediaCSS += " }";
                }

                // Escape key listener
                mediaCSS += " "; // spacer before script