Commit ae54992d authored by jan.koester's avatar jan.koester
Browse files

test

parent 1c6955d5
Loading
Loading
Loading
Loading
+68 −10
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <unordered_map>
#include <regex>
#include <cctype>
#include <mutex>

#include <htmlpp/html.h>
#include <httppp/exception.h>
@@ -135,8 +136,11 @@ bool queryNodeWidgetDescriptor(const std::string &scriptPath, NodeWidgetDescript
    return ok;
}

std::vector<NodeWidgetDescriptor> nodeWidgetCatalog() {
    std::vector<NodeWidgetDescriptor> catalog;
const std::vector<NodeWidgetDescriptor> &nodeWidgetCatalog() {
    static std::vector<NodeWidgetDescriptor> catalog;
    static std::once_flag initialized;

    std::call_once(initialized, []() {
    std::vector<std::string> widgetDirs;

    const std::string dirsEnv = getEnvOrDefault("BLOGI_WEBEDIT_NODE_WIDGET_DIRS", "");
@@ -183,6 +187,16 @@ std::vector<NodeWidgetDescriptor> nodeWidgetCatalog() {
                desc.version = "1.0";
                desc.canHaveChildren = false;

                // Prefer metadata from the widget itself (incl. hardcoded UUID/type_id).
                NodeWidgetDescriptor meta = desc;
                if (queryNodeWidgetDescriptor(desc.scriptPath, meta)) {
                    if (!meta.name.empty()) desc.name = meta.name;
                    if (!meta.typeId.empty()) desc.typeId = meta.typeId;
                    if (!meta.author.empty()) desc.author = meta.author;
                    if (!meta.version.empty()) desc.version = meta.version;
                    desc.canHaveChildren = meta.canHaveChildren;
                }

                if (desc.name.empty())
                    continue;

@@ -205,6 +219,8 @@ std::vector<NodeWidgetDescriptor> nodeWidgetCatalog() {
        return a.name < b.name;
    });

    });

    return catalog;
}

@@ -215,7 +231,7 @@ bool findNodeWidgetByName(const std::string &name, NodeWidgetDescriptor &out) {
        return value;
    };

    const auto catalog = nodeWidgetCatalog();
    const auto &catalog = nodeWidgetCatalog();

    // Fast path: exact match.
    auto it = std::find_if(catalog.begin(), catalog.end(), [&](const NodeWidgetDescriptor &d) {
@@ -239,6 +255,31 @@ bool findNodeWidgetByName(const std::string &name, NodeWidgetDescriptor &out) {
    return true;
}

bool findNodeWidgetByTypeId(const std::string &typeId, NodeWidgetDescriptor &out) {
    if (typeId.empty()) {
        return false;
    }

    auto lower = [](std::string value) {
        std::transform(value.begin(), value.end(), value.begin(),
                       [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
        return value;
    };

    const std::string wanted = lower(typeId);
    const auto &catalog = nodeWidgetCatalog();
    auto it = std::find_if(catalog.begin(), catalog.end(), [&](const NodeWidgetDescriptor &d) {
        return lower(d.typeId) == wanted;
    });

    if (it == catalog.end()) {
        return false;
    }

    out = *it;
    return true;
}

bool isNodeWidgetPluginName(const std::string &name) {
    return name == "NodeWidget" || name == "Nodewidget";
}
@@ -376,7 +417,10 @@ void webedit::Api::loadDocumentTreeFromXml(DocumentState &doc, const std::string
            continue;

        const char *typeName = child->Name();
        auto *el = createPluginByName(typeName, doc);
        const char *typeIdAttr = child->Attribute("type_id");
        auto *el = createPluginByName(typeName,
                                      doc,
                                      typeIdAttr ? std::string(typeIdAttr) : std::string());
        if (!el)
            continue;

@@ -665,7 +709,7 @@ void webedit::Api::handleGetPlugins(libhttppp::HttpRequest &curreq) {
    json_object *arr = json_object_new_array();

    try {
        const auto catalog = nodeWidgetCatalog();
        const auto &catalog = nodeWidgetCatalog();
        for (const auto &desc : catalog) {
            json_object *obj = json_object_new_object();
            json_object_object_add(obj, "name", json_object_new_string(desc.name.c_str()));
@@ -1321,7 +1365,10 @@ void webedit::Api::handleImportXml(libhttppp::HttpRequest &curreq,
    blogi::webedit::EditPlugin *lastTop = nullptr;
    for (auto *child = rootEl->FirstChildElement(); child; child = child->NextSiblingElement()) {
        const char *typeName = child->Name();
        auto *el = createPluginByName(typeName, doc);
        const char *typeIdAttr = child->Attribute("type_id");
        auto *el = createPluginByName(typeName,
                          doc,
                          typeIdAttr ? std::string(typeIdAttr) : std::string());
        if (!el) continue;

        el->fromXmlObject(child);
@@ -1440,7 +1487,10 @@ void webedit::Api::handlePasteElement(libhttppp::HttpRequest &curreq,
         child = child->NextSiblingElement()) {
        if (strcmp(child->Name(), "property") == 0) continue;
        const char *typeName = child->Name();
        auto *el = createPluginByName(typeName, doc);
        const char *typeIdAttr = child->Attribute("type_id");
        auto *el = createPluginByName(typeName,
                          doc,
                          typeIdAttr ? std::string(typeIdAttr) : std::string());
        if (!el) continue;

        el->fromXmlObject(child);
@@ -3185,10 +3235,15 @@ webedit::Api::NodeContext webedit::Api::findNodeContext(
}

blogi::webedit::EditPlugin *webedit::Api::createPluginByName(
        const std::string &name, DocumentState &doc) {
        const std::string &name, DocumentState &doc, const std::string &typeIdHint) {
    NodeWidgetDescriptor desc;
    if (!findNodeWidgetByName(name, desc))

    // Preferred mapping for persisted templates: unique hardcoded type_id.
    if (!typeIdHint.empty() && findNodeWidgetByTypeId(typeIdHint, desc)) {
        // resolved by UUID
    } else if (!findNodeWidgetByName(name, desc)) {
        return nullptr;
    }

    auto *newEl = new EmbeddedNodeWidget(desc);
    if (!newEl)
@@ -3211,7 +3266,10 @@ void webedit::Api::loadChildrenFromXml(tinyxml2::XMLElement *parentXml,
            continue;

        const char *typeName = childXml->Name();
        auto *childEl = createPluginByName(typeName, doc);
        const char *typeIdAttr = childXml->Attribute("type_id");
        auto *childEl = createPluginByName(typeName,
                           doc,
                           typeIdAttr ? std::string(typeIdAttr) : std::string());
        if (!childEl) continue;

        childEl->fromXmlObject(childXml);
+2 −1
Original line number Diff line number Diff line
@@ -169,7 +169,8 @@ namespace webedit {
        NodeContext findNodeContext(blogi::webedit::EditPlugin *root, const std::string &uuid);

        blogi::webedit::EditPlugin *createPluginByName(const std::string &name,
                                                        DocumentState &doc);
                                DocumentState &doc,
                                const std::string &typeIdHint = "");

        void loadChildrenFromXml(tinyxml2::XMLElement *parentXml,
                                 blogi::webedit::EditPlugin *parentEl,