Newer
Older
solitude / src / js / src / main / app.js
@sylow-castle sylow-castle on 16 Nov 2023 9 KB [updaate]spilit
function main(document) {
    webconfig(window);
    if ((typeof solitude.style) === 'undefined') {
        solitude = readyWeb();
    }
    //アプリケーション毎に初期化操作
    initializeSolitudeApps(solitude.apps())

    query("li.tab").forEach(function (val, index, list) {
        val.addEventListener("click", function () {
            selectTab(index);
        });
    })
    append(location.href);

    const leftMenu = query("#left-menu")[0];
    const menuToggle = query("#menu-toggle")[0]
    menuToggle.addEventListener("click", function () {
        leftMenu.classList.remove("initial")
        toggleMenuItem(leftMenu);
        query("#left-menu li span").forEach(function (val) {
            toggleMenuItem(val);
        })
    })

    window.addEventListener("message", (event) => {
        const appFrame = query("#main-pane .app-container iframe")[0]
        expectedOrigin = appFrame.contentWindow.location.origin
        if (event.origin != expectedOrigin) {
            append("failed!")
            append("eventorigin:")
            append(event.origin)
            append("expectedOrigin:");
            append(expectedOrigin);
            return;
        }
        append("event.data : ")
        append(event.data)
        try {
            const data = JSON.parse(event.data);
            solitude.write.local(data.path, data.content);
        } catch (error) {
            append(error);
        }
        append("success !")
    });

    // 以下、宣言
    function toggleMenuItem(element) {
        if (element.classList.contains("expanded")) {
            element.classList.add("shrinked");
            element.classList.remove("expanded");
        } else {
            element.classList.add("expanded");
            element.classList.remove("shrinked");
        }
    }

    function selectTab(index) {
        query("li.tab.selected").forEach(function (val) {
            val.classList.remove("selected");
        });
        query("li.tab")[index].classList.add("selected");

        query("div.main-article.selected").forEach(function (val) {
            val.classList.remove("selected");
        });
        query("div.main-article")[index].classList.add("selected");
    }

    function query(selector) {
        return document.querySelectorAll(selector)
    }

    function append(kontent) {
        let logs = query("#logarea")[0].value
        logs += kontent + "\n";
        query("#logarea")[0].value = logs;
    }

    /**
     * solitude web版でのsolitudeオブジェクトの組み立てを行う
     */
    function readyWeb() {
        const solitude = buildWebSolitude();
        const apps = window.tmp.solitudeapps;
        solitude.apps = () => apps;
        addProperty(solitude);
        return solitude;

        function buildWebSolitude(global) {
            const solitude = {};
            solitude.write = {}
            solitude.write.local = (path, contents) => { append(contents) };
            return solitude;
        }

        function addProperty(app) {
            //solitude本体を設定しているような表現をしたいための回りくどい書き方
            const solitude = {
                get style() { return "web" },
                "write": {
                    "local": writeLocal,
                },

                "read": {
                    "local": readLocal
                }


            }

            //ここからsolitudeに設定したプロパティをappへうつす
            app.write = solitude.write;
            app.read = solitude.read;

            for (prop in solitude) {
                Object.defineProperty(app, prop, {
                    get() { return solitude[prop] }
                })
            }

            return;

            function writeLocal(path, contents) {
                solitude.io.fs.download(path, cotents, "text/plain");
            }

            function readLocal(path) {
                // stringで解決するPromiseを返したい。
                return fetch(path)
                    .then((response) => {
                        if (response.ok) {
                            return response.text();
                        } else {
                            throw new Error(`HTTP error, status = ${response.status}`);
                        }
                    },
                        (cause) => {
                            const error = new Error('ファイルのオープンに失敗しました。causeプロパティで原因となったオブジェクトを返します。');
                            error.cause = cause;
                            throw error
                        });
            }
        }
    }




    function initializeSolitudeApps(apps) {
        for (const [name, conf] of Object.entries(apps)) {
            const appType = conf.type || "undef";
            switch (appType) {
                case "main":
                case "undef":
                    //do nothing                            
                    break;
                default:
                    //something wrong;
                    break;

                case "staticpage":
                    loadStaticPageApps(name, conf)
                    break;
                case "iframe":
                    loadIframeApps(name, conf);
                    break;
            }
        }
    }

    function loadIframeApps(name, conf) {
        addNewMenu(name, conf);
        const mount = query("#left-menu ol")[0];
        mount.querySelector("li.init").addEventListener("click", function () {
            bootIframeApps(name, conf);
        });
        mount.querySelector("li.init").classList.remove("init");
    }

    function loadStaticPageApps(name, conf) {
        addNewMenu(name, conf);
        const mount = query("#left-menu ol")[0];
        mount.querySelector("li.init").addEventListener("click", function () {
            bootStaticPageApps(name, conf);
        });
        mount.querySelector("li.init").classList.remove("init");
    }

    function bootIframeApps(name, conf) {
        addNewTab(name);
        addNewContent(name, conf);
    }

    function bootStaticPageApps(name, conf) {
        addNewTab(name);
        addNewStaticPageContent(name, conf);
    }


    function addNewMenu(name, conf) {
        const mount = query("#left-menu ol")[0];
        let menu = query("#app-menu")[0];
        menu = menu.content.cloneNode(true);

        const span = menu.querySelector("span");
        // template では初期状態はexpanded
        if (query("#left-menu.shrinked").length > 0) {
            const cls = span.classList;
            cls.remove("expanded");
            cls.add("shrinked");

        }
        span.textContent = name;
        mount.appendChild(menu);
    }

    function addNewTab(label) {
        /*
         タブに対するイベント設定のあたり
            val.addEventListener("click", function () {
            selectTab(index);
        */
        const mount = query("#main-tabs")[0];
        let tab = document.querySelector("#app-tab")
        tab = tab.content.cloneNode(true);
        tab.querySelector("li").textContent = label;
        const index = query("li.tab").length
        mount.appendChild(tab);

        /*
         * ・追加したタブのindexの推定のやり方がよくない
         * ・イベントの設定コードが重複が気持ち悪い
         */
        query("li.tab")[index].addEventListener("click", function () {
            selectTab(index);
        })
    }

    function addNewContent(name, conf) {
        const mount = query("#main-pane")[0];
        let app = query("#app-type-iframe")[0];
        app = app.content.cloneNode(true)
        const base = app.querySelector("div.main-article");
        base.classList.remove("undefined")

        const iframe = app.querySelector("div.app-container > iframe");
        iframe.setAttribute("id", name);
        iframe.setAttribute("title", name);
        iframe.setAttribute("src", conf.src);

        mount.appendChild(base)
    }

    function addNewStaticPageContent(name, conf) {
        const mount = query("#main-pane")[0];
        let app = query("#app-type-staticpage")[0];
        app = app.content.cloneNode(true)
        const base = app.querySelector("div.main-article");
        base.classList.remove("undefined");

        /*
        const staticpage = fetch(conf.src)
            .then((res) => {
                if(res.ok) {
                    return res.text();
                } else {
                    throw new Error(`HTTP error, status = ${res.status}`);
                }
            }).then((text) => {
                const parser = new DOMParser()
                const doc = parser.parseFromString(text, "text/html");
                const content = doc.querySelector("div.app-body").cloneNode(true);
                base.querySelector("div.app-container").appendChild(content);
                mount.appendChild(base)
            });
        */

        solitude.read.local(conf.src).then((text) => {
            const parser = new DOMParser()
            const doc = parser.parseFromString(text, "text/html");
            const content = doc.querySelector("div.app-body").cloneNode(true);
            base.querySelector("div.app-container").appendChild(content);
            mount.appendChild(base)
        })
    }
}