diff --git a/src/js/src/main/app.html b/src/js/src/main/app.html index 5bfea9d..ba73e37 100644 --- a/src/js/src/main/app.html +++ b/src/js/src/main/app.html @@ -60,296 +60,9 @@ + diff --git a/src/js/src/main/app.js b/src/js/src/main/app.js new file mode 100644 index 0000000..4658228 --- /dev/null +++ b/src/js/src/main/app.js @@ -0,0 +1,288 @@ +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) + }) + } +} \ No newline at end of file