Commit dbbc5eb0 authored by Jan Koester's avatar Jan Koester
Browse files

test

parent f4658e29
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -2541,7 +2541,7 @@
    // Fetches the project list; shared by initial load and the project manager dialog
    // (loadConnectionList) so projectsCache stays in sync after add/edit/delete.
    function loadProjectSelectOptions(callback) {
        EditorApi.listConnections().then(function(resp) {
        return EditorApi.listConnections().then(function(resp) {
            projectsCache = resp.connections || [];
            if (callback) callback();
        });
@@ -2734,8 +2734,14 @@
                status.className = 'set-status success';
                var savedId = resp.id || conn.id;
                document.getElementById('conn-edit-id').value = savedId || '';
                loadConnectionList();
                // onProjectSelected() reads the newly saved project out of
                // projectsCache, so it must wait for loadConnectionList()'s
                // refetch to resolve -- calling it synchronously right after
                // loadConnectionList() ran against the still-stale cache and
                // blanked out the form the user just filled in/saved.
                loadConnectionList().then(function() {
                    if (savedId) onProjectSelected(savedId);
                });
                setTimeout(function() { status.textContent = ''; status.className = 'set-status'; }, 2000);
            }).catch(function(err) {
                status.textContent = I18n.t('I18N_SAVE_FAILED', 'Speichern fehlgeschlagen') + ': ' + (err.error || '');
@@ -2985,8 +2991,12 @@
    }

    function loadConnectionList() {
        loadProjectSelectOptions(function() {
        return loadProjectSelectOptions(function() {
            renderConnectionList(projectsCache);
            // renderConnectionList() rebuilds #conn-list from scratch, so the
            // selection highlight and settings-form fields need reapplying
            // every time this runs, not just on the very first load.
            syncProjectManagerModalUI();
        });
    }

+36 −0
Original line number Diff line number Diff line
@@ -124,6 +124,9 @@ extern "C" {
            std::string m_boxShadowColor  = "";
            std::string m_boxShadowCustom = "";

            // Hover effect: lifts the container upward on hover (desktop only)
            bool hoverLift = false;

            // Visibility
            bool hidden = false;
            bool m_hidden = false;
@@ -367,6 +370,11 @@ extern "C" {
                addField("box_shadow", "Box Shadow", "select", nullptr, "desktop", mkOpts({"none","sm","md","lg","card","float","inner"}));
                addField("box_shadow_color", "Box Shadow Color", "color_var", nullptr, "desktop");
                addField("box_shadow_custom", "Box Shadow Custom", "text", "e.g. 0 4px 20px rgba(0,0,0,0.5)", "desktop");
                addField("hover_lift", "Hover Lift", "checkbox", nullptr, "desktop", nullptr, "simple");
                {
                    json_object *hlf = json_object_array_get_idx(arr, json_object_array_length(arr) - 1);
                    json_object_object_add(hlf, "default", json_object_new_boolean(false));
                }
                addField("hidden", "Hidden", "checkbox", nullptr, "desktop", nullptr, "simple");
                {
                    json_object *hf = json_object_array_get_idx(arr, json_object_array_length(arr) - 1);
@@ -507,6 +515,8 @@ extern "C" {
                element->SetAttribute("m_box_shadow_color", m_boxShadowColor.c_str());
                element->SetAttribute("m_box_shadow_custom", m_boxShadowCustom.c_str());

                element->SetAttribute("hover_lift", hoverLift ? "true" : "false");

                // Visibility
                element->SetAttribute("hidden", hidden ? "true" : "false");
                element->SetAttribute("m_hidden", m_hidden ? "true" : "false");
@@ -705,6 +715,9 @@ extern "C" {
                const char* loaded_m_bsh_custom = xml_data->Attribute("m_box_shadow_custom");
                if (loaded_m_bsh_custom) m_boxShadowCustom = loaded_m_bsh_custom;

                const char* loaded_hover_lift = xml_data->Attribute("hover_lift");
                if (loaded_hover_lift) hoverLift = (strcmp(loaded_hover_lift, "true") == 0);

                // Visibility
                const char* loaded_hidden = xml_data->Attribute("hidden");
                if (loaded_hidden) hidden = (strcmp(loaded_hidden, "true") == 0);
@@ -792,6 +805,7 @@ extern "C" {
                json_object_object_add(obj, "m_box_shadow", json_object_new_string(m_boxShadow.c_str()));
                json_object_object_add(obj, "m_box_shadow_color", json_object_new_string(m_boxShadowColor.c_str()));
                json_object_object_add(obj, "m_box_shadow_custom", json_object_new_string(m_boxShadowCustom.c_str()));
                json_object_object_add(obj, "hover_lift", json_object_new_boolean(hoverLift));
                json_object_object_add(obj, "hidden", json_object_new_boolean(hidden));
                json_object_object_add(obj, "m_hidden", json_object_new_boolean(m_hidden));
                json_object_object_add(obj, "custom_css", json_object_new_string(customCss.c_str()));
@@ -1067,6 +1081,14 @@ extern "C" {
                    val = json_object_get_string(val_obj);
                    if (val) m_boxShadowCustom = val;
                }
                if (json_object_object_get_ex(obj, "hover_lift", &val_obj)) {
                    if (json_object_is_type(val_obj, json_type_string)) {
                        const char *s = json_object_get_string(val_obj);
                        hoverLift = (s && (strcmp(s, "true") == 0 || strcmp(s, "1") == 0));
                    } else {
                        hoverLift = json_object_get_boolean(val_obj);
                    }
                }
                if (json_object_object_get_ex(obj, "hidden", &val_obj)) {
                    if (json_object_is_type(val_obj, json_type_string)) {
                        const char *s = json_object_get_string(val_obj);
@@ -1184,6 +1206,9 @@ extern "C" {
                if (hasShapeDivider) {
                    style += " position: relative;";
                }
                if (hoverLift) {
                    style += " transition: transform 0.25s ease, box-shadow 0.25s ease;";
                }
                if (hidden) {
                    style += " display: none;";
                }
@@ -1355,6 +1380,17 @@ extern "C" {
                    el.appendChild(mobileLightStyle);
                }

                // Hover lift: nudges the container upward with a soft shadow on
                // hover. Desktop-only (matches the mobile breakpoint used above)
                // since :hover has no reliable touch equivalent.
                if (hoverLift) {
                    libhtmlpp::HtmlElement hoverStyle("style");
                    std::string hoverRule = "@media (min-width: 769px) { ." + responsiveClass +
                        ":hover { transform: translateY(-8px); box-shadow: 0 20px 45px rgba(0,0,0,0.15); } }";
                    hoverStyle.appendChild(libhtmlpp::TextElement(hoverRule.c_str()));
                    el.appendChild(hoverStyle);
                }

                if (!customCss.empty()) {
                    libhtmlpp::HtmlElement cssStyle("style");
                    // Emit raw — user writes full selectors, e.g. .we-xxx { color: red; }
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ namespace blogi { namespace webedit { namespace container_i18n {
            {"Gradient Custom", "Eigener Farbverlauf"},
            {"Height", "Höhe"},
            {"Hidden", "Ausgeblendet"},
            {"Hover Lift", "Hover-Anhebung"},
            {"Margin", "Außenabstand"},
            {"Mobile Background Color", "Hintergrundfarbe (Mobil)"},
            {"Mobile Background Color (Light)", "Hintergrundfarbe (Mobil Hell)"},
+35 −0
Original line number Diff line number Diff line
@@ -83,6 +83,10 @@ extern "C" {
            // Fullscreen
            bool fullscreen = false;

            // Hover zoom: "in" grows the image on hover, "out" starts the
            // image zoomed in and settles back to normal size on hover
            std::string hoverZoom = "none";

            // Custom CSS
            std::string customCss = "";

@@ -284,6 +288,7 @@ extern "C" {
                element->SetAttribute("object_fit", objectFit.c_str());
                element->SetAttribute("border_radius", borderRadius.c_str());
                element->SetAttribute("border_style", borderStyle.c_str());
                element->SetAttribute("hover_zoom", hoverZoom.c_str());
                element->SetAttribute("link_url", linkUrl.c_str());
                element->SetAttribute("media_id", mediaId.c_str());
                element->SetAttribute("media_ext", mediaExt.c_str());
@@ -339,6 +344,7 @@ extern "C" {
                val = xml_data->Attribute("object_fit");    if (val) objectFit = val;
                val = xml_data->Attribute("border_radius"); if (val) borderRadius = val;
                val = xml_data->Attribute("border_style");  if (val) borderStyle = val;
                val = xml_data->Attribute("hover_zoom");    if (val) hoverZoom = val;
                val = xml_data->Attribute("link_url");      if (val) linkUrl = val;
                val = xml_data->Attribute("media_id");      if (val) mediaId = val;
                val = xml_data->Attribute("media_ext");     if (val) mediaExt = val;
@@ -398,6 +404,7 @@ extern "C" {
                json_object_object_add(obj, "object_fit", json_object_new_string(objectFit.c_str()));
                json_object_object_add(obj, "border_radius", json_object_new_string(borderRadius.c_str()));
                json_object_object_add(obj, "border_style", json_object_new_string(borderStyle.c_str()));
                json_object_object_add(obj, "hover_zoom", json_object_new_string(hoverZoom.c_str()));
                json_object_object_add(obj, "link_url", json_object_new_string(linkUrl.c_str()));
                json_object_object_add(obj, "media_id", json_object_new_string(mediaId.c_str()));
                json_object_object_add(obj, "media_ext", json_object_new_string(mediaExt.c_str()));
@@ -459,6 +466,9 @@ extern "C" {
                if (json_object_object_get_ex(obj, "border_style", &val_obj)) {
                    val = json_object_get_string(val_obj); if (val) borderStyle = val;
                }
                if (json_object_object_get_ex(obj, "hover_zoom", &val_obj)) {
                    val = json_object_get_string(val_obj); if (val) hoverZoom = val;
                }
                if (json_object_object_get_ex(obj, "link_url", &val_obj)) {
                    val = json_object_get_string(val_obj); if (val) linkUrl = val;
                }
@@ -623,6 +633,7 @@ extern "C" {
                addField("border_radius", "Border Radius", "text", "0");
                addField("border_style", "Border", "text", "e.g. 1px solid #ccc", "desktop");
                addField("m_border_style", "Border (Mobile)", "text", "e.g. 1px solid #ccc", "mobile");
                addField("hover_zoom", "Hover Zoom", "select", nullptr, "desktop", mkOpts({"none","in","out"}), -1, nullptr, "simple");
                addSpacingBox("padding", "Padding", "desktop");
                addSpacingBox("margin", "Margin", "desktop");
                addSpacingBox("m_padding", "Mobile Padding", "mobile");
@@ -665,6 +676,14 @@ extern "C" {
                // Unique CSS class for responsive targeting
                std::string responsiveClass = std::string("we-") + getInstanceId().c_str();

                bool hasHoverZoom = (hoverZoom == "in" || hoverZoom == "out");
                if (hasHoverZoom) {
                    // Shrink-wraps the <img> so overflow:hidden clips the
                    // scaled image at its own visual edges instead of the
                    // (otherwise block-level, full-width) wrapper's edges.
                    wrapper.setAttribute("style", "overflow: hidden; display: inline-block; line-height: 0;");
                }

                std::string renderSrc = src;
                const std::string &pfx = getPrefix();
                if (!renderSrc.empty() && renderSrc[0] == '/' && !pfx.empty() && pfx != "/") {
@@ -789,6 +808,22 @@ extern "C" {
                    el.appendChild(styleTag);
                }

                if (hasHoverZoom) {
                    // The scale transform has to live entirely in this <style>
                    // block rather than the <img>'s own inline style attribute:
                    // an inline style always wins over a class selector's rules
                    // regardless of specificity, so a :hover rule could never
                    // override an inline transform.
                    libhtmlpp::HtmlElement zoomStyle("style");
                    std::string baseScale = (hoverZoom == "out") ? "1.15" : "1";
                    std::string hoverScale = (hoverZoom == "out") ? "1" : "1.1";
                    std::string zoomRule = "." + responsiveClass + " { transition: transform 0.3s ease; transform: scale(" +
                        baseScale + "); } @media (min-width: 769px) { ." + responsiveClass + ":hover { transform: scale(" +
                        hoverScale + "); } }";
                    zoomStyle.appendChild(libhtmlpp::TextElement(zoomRule.c_str()));
                    el.appendChild(zoomStyle);
                }

                if (!customCss.empty()) {
                    libhtmlpp::HtmlElement cssStyle("style");
                    cssStyle.appendChild(libhtmlpp::TextElement(customCss.c_str()));
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ namespace blogi { namespace webedit { namespace image_i18n {
            {"Height (Mobile)", "Höhe (Mobil)"},
            {"Hidden", "Ausgeblendet"},
            {"Hidden (Mobile)", "Ausgeblendet (Mobil)"},
            {"Hover Zoom", "Hover-Zoom"},
            {"Image Path (manual)", "Bildpfad (manuell)"},
            {"Link URL", "Link-URL"},
            {"Margin", "Außenabstand"},