diff --git a/src/js/src/main/app.js b/src/js/src/main/app.js index 6c612dc..7abfd6d 100644 --- a/src/js/src/main/app.js +++ b/src/js/src/main/app.js @@ -1,363 +1,368 @@ window.addEventListener('load', main(document)); function main(document) { - graftSolitude(window); - webconfig(window); - var mysolitude; - if (true || (typeof solitude.style) === 'undefined') { - mysolitude = readyWeb(); + graftSolitude(window); + webconfig(window); + var mysolitude; + if (true || (typeof solitude.style) === 'undefined') { + mysolitude = readyWeb(); + } + + let Que; + const mainOrgan = solitude.newOrgan; + initializeQue(); + + //アプリケーション毎に初期化操作 + initializeSolitudeApps(mysolitude.apps) + + Que("li.tab").list().forEach(function (val, index, _list) { + val.addEventListener("click", function () { + selectTab(index); + }); + }) + append(location.href); + + const leftMenu = Que("#left-menu").get(); + const menuToggle = Que("#menu-toggle").get(); + menuToggle.addEventListener("click", function () { + leftMenu.classList.remove("initial") + toggleMenuItem(leftMenu); + Que("#left-menu li span").list().forEach(function (val) { + toggleMenuItem(val); + }) + toggleMenuItem(Que("#main").get()); + + }) + + window.addEventListener("message", (event) => { + const appFrame = Que("#main-pane .app-container iframe").get() + 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 !") + }); - let Que; - const mainOrgan = solitude.newOrgan; - initializeQue(); + // 以下、宣言 + 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"); + } + } - //アプリケーション毎に初期化操作 - initializeSolitudeApps(mysolitude.apps) - - Que("li.tab").list().forEach(function (val, index, _list) { - val.addEventListener("click", function () { - selectTab(index); - }); - }) - append(location.href); - - const leftMenu = Que("#left-menu").get(); - const menuToggle = Que("#menu-toggle").get(); - menuToggle.addEventListener("click", function () { - leftMenu.classList.remove("initial") - toggleMenuItem(leftMenu); - Que("#left-menu li span").list().forEach(function (val) { - toggleMenuItem(val); - }) - toggleMenuItem(Que("#main").get()); - - }) - - window.addEventListener("message", (event) => { - const appFrame = Que("#main-pane .app-container iframe").get() - 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 selectTab(index) { + let tab, content; + Que("#main-pane li.tab").list().forEach(function (val) { + val.classList.remove("selected"); + if (val.dataset.soloAppId == index) { + tab = val; + } }); - // 以下、宣言 - 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"); - } + Que("#main-pane div.main-article").list().forEach(function (val) { + val.classList.remove("selected"); + if (val.dataset.soloAppId == index) { + content = val; + } + }); + + tab.classList.add("selected"); + content.classList.add("selected"); + } + + function initializeQue() { + //Queはglobalではない。親スコープで宣言済み。 + Que = newQue; + Query.prototype.list = asList + Query.prototype.get = asNode + Query.prototype.que = reQue + + function Query(selector, base) { + if (base instanceof Query) { + this.origin = base.get(); + } else { + this.origin = base || document; + } + this.raw = this.origin.querySelectorAll(selector); + /* + this.list = asList; + this.get = asNode; + this.que = reQue; + */ } - function selectTab(index) { - let tab, content; - Que("#main-pane li.tab").list().forEach(function (val) { - val.classList.remove("selected"); - if(val.dataset.soloAppId == index) { - tab = val; - } - }); - - Que("#main-pane div.main-article").list().forEach(function (val) { - val.classList.remove("selected"); - if(val.dataset.soloAppId == index) { - content = val; - } - }); - - tab.classList.add("selected"); - content.classList.add("selected"); + function asList() { + return this.raw; } - function initializeQue() { - //Queはglobalではない。親スコープで宣言済み。 - Que = newQue; - - function Query(selector, base) { - if (base instanceof Query) { - this.origin = base.get(); - } else { - this.origin = base || document; - } - this.raw = this.origin.querySelectorAll(selector); - this.list = asList; - this.get = asNode; - this.que = reQue; - } - - function asList() { - return this.raw; - } - - function asNode() { - if (this.raw.length > 0) { - return this.raw[0]; - } - } - - function newQue(selector, base) { - return new Query(selector, base); - } - - function reQue(selector) { - return new Query(selector, this.get()) - } - + function asNode() { + if (this.raw.length > 0) { + return this.raw[0]; + } } - function append(kontent) { - let logs = Que("#logarea").get().value - logs += kontent + "\n"; - Que("#logarea").get().value = logs; + function newQue(selector, base) { + return new Query(selector, base); } - /** - * solitude web版でのsolitudeオブジェクトの組み立てを行う - */ - function readyWeb() { - //先にwebconfigを起動している前提 - const solitude = window.solitude; - solitude.apps = {}; - Object.assign(solitude.apps, window.tmp.solitudeapps); - addProperty(solitude); + function reQue(selector) { + return new Query(selector, this.get()) + } + + } + + function append(kontent) { + let logs = Que("#logarea").get().value + logs += kontent + "\n"; + Que("#logarea").get().value = logs; + } + + /** + * solitude web版でのsolitudeオブジェクトの組み立てを行う + */ + function readyWeb() { + //先にwebconfigを起動している前提 + const solitude = window.solitude; + solitude.apps = {}; + Object.assign(solitude.apps, window.tmp.solitudeapps); + addProperty(solitude); + return solitude; + + /* + function buildWebSolitude(_global) { + const solitude = {}; + solitude.write = {} + solitude.write.local = (_path, contents) => { append(contents) }; return solitude; + } + */ + function addProperty(app) { + //solitude本体を設定しているような表現をしたいための回りくどい書き方 + Object.defineProperty(app, 'style', { + get() { return 'web' } + }); - /* - function buildWebSolitude(_global) { - const solitude = {}; - solitude.write = {} - solitude.write.local = (_path, contents) => { append(contents) }; - return solitude; - } - */ - function addProperty(app) { - //solitude本体を設定しているような表現をしたいための回りくどい書き方 - Object.defineProperty(app, 'style', { - get() { return 'web' } - }); + app.write = {} + app.write.local = writeLocal; + app.read = {}; + app.read.local = readLocal; - app.write = {} - app.write.local = writeLocal; - app.read = {}; - app.read.local = readLocal; + return app; - return app; + function writeLocal(path, _contents) { + solitude.io.fs.download(path, cotents, "text/plain"); + } - 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 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) { + appsProto = { + useMenu: true, + useTab: true, + autorun: false, + }; + + const appFuncs = [IframeApp, StaticPageApp, BatchApp]; + appFuncs.forEach(appFunc => { + appFunc.prototype = appsProto; + }); + + let app; + let appInstanceID = 0; + 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": + app = new StaticPageApp(name, conf); + app.instanceID = ++appInstanceID; + app.load(); + break; + case "iframe": + app = new IframeApp(name, conf); + app.instanceID = ++appInstanceID; + app.load(); + break; + case "batch": + app = new BatchApp(name, conf); + app.instanceID = ++appInstanceID; + app.load(); + break; + } } - function initializeSolitudeApps(apps) { - appsProto = { - useMenu: true, - useTab: true, - autorun: false, - }; - const appFuncs = [IframeApp, StaticPageApp, BatchApp]; - appFuncs.forEach(appFunc => { - appFunc.prototype = appsProto; + //巻き上げを期待しているためclass構文ではない。 + + function IframeApp(name, conf) { + this.name = name; + this.conf = conf; + this.load = loadApp; + this.template = "#app-type-iframe"; + this.callback = iframeCallback; + } + + function StaticPageApp(name, conf) { + this.name = name; + this.conf = conf; + this.load = loadApp; + this.template = "#app-type-staticpage"; + this.callback = staticpageCallback; + } + + function BatchApp(name, conf) { + this.name = name; + this.conf = conf; + this.load = loadBatchApp; + this.template = "#app-type-batch"; + this.callback = batchCallback; + } + + function loadApp() { + addNewMenu(this.name); + const mount = Que("#left-menu ol"); + const app = this; + + mount.que("li.init").get().addEventListener("click", function () { + addNewTab(app); + addNewContent(app); + }); + mount.que("li.init").get().classList.remove("init"); + } + + function loadBatchApp() { + addNewContent(this); + } + + function addNewMenu(name) { + const mount = Que("#left-menu ol").get(); + let menu = Que("#app-menu").get(); + menu = menu.content.cloneNode(true); + + const span = Que("span", menu).get(); + // template では初期状態はexpanded + if (Que("#left-menu.shrinked").list().length > 0) { + const cls = span.classList; + cls.remove("expanded"); + cls.add("shrinked"); + } + span.textContent = name; + mount.appendChild(menu); + } + + function addNewTab(app) { + /* + タブに対するイベント設定のあたり + val.addEventListener("click", function () { + selectTab(index); + */ + const mount = Que("#main-tabs").get(); + let tab = Que("#app-tab").get() + tab = tab.content.cloneNode(true); + const li = Que("li", tab).get(); + li.textContent = app.name; + li.dataset.soloAppId = app.instanceID; + const index = app.instanceID; + mount.appendChild(tab); + + li.addEventListener("click", () => { + selectTab(index); + //mainOrgan.fire("log", "open appID:" + app.instanceID + ", appID:" + app.name, solitude.nerve); + }); + } + + function addNewContent(app) { + const appNode = (Que(app.template).get()).content.cloneNode(true); + const base = Que("div.main-article", appNode); + base.get().classList.remove("undefined"); + base.get().dataset.soloAppId = app.instanceID; + base.que("div.app-container").get().classList.add(app.name); + app.callback(app, base); + + const mount = Que("#app-pane").get(); + mount.appendChild(base.get()); + + } + + function iframeCallback(app, base) { + const iframe = Que("div.app-container > iframe", base).get(); + iframe.setAttribute("id", app.name); + iframe.setAttribute("title", app.name); + iframe.setAttribute("src", app.conf.src); + } + + function staticpageCallback(app, base) { + mysolitude.read.local(app.conf.src).then((text) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(text, "text/html"); + const content = Que("div.app-body", doc).get().cloneNode(true); + Que("div.app-container", base).get().appendChild(content); + + //文書内のJavascriptコードを実行する。簡単な実装。 + //これだとon.loadイベントとかがキックされなくなってしまう気がする。 + const removes = []; + Que("script", content).list().forEach(element => { + const script = document.createElement("script") + script.innerHTML = element.innerHTML; + for (const attr of element.attributes) { + script.setAttribute(attr.name, attr.value); + } + element.before(script) + removes.push(element); }); - let app; - let appInstanceID = 0; - 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": - app = new StaticPageApp(name, conf); - app.instanceID = ++appInstanceID; - app.load(); - break; - case "iframe": - app = new IframeApp(name, conf); - app.instanceID = ++appInstanceID; - app.load(); - break; - case "batch": - app = new BatchApp(name, conf); - app.instanceID = ++appInstanceID; - app.load(); - break; - } + for (const script of removes) { + script.remove(); } - - //巻き上げを期待しているためclass構文ではない。 - - function IframeApp(name, conf) { - this.name = name; - this.conf = conf; - this.load = loadApp; - this.template = "#app-type-iframe"; - this.callback = iframeCallback; - } - - function StaticPageApp(name, conf) { - this.name = name; - this.conf = conf; - this.load = loadApp; - this.template = "#app-type-staticpage"; - this.callback = staticpageCallback; - } - - function BatchApp(name, conf) { - this.name = name; - this.conf = conf; - this.load = loadBatchApp; - this.template = "#app-type-batch"; - this.callback = batchCallback; - } - - function loadApp() { - addNewMenu(this.name); - const mount = Que("#left-menu ol"); - const app = this; - - mount.que("li.init").get().addEventListener("click", function () { - addNewTab(app); - addNewContent(app); - }); - mount.que("li.init").get().classList.remove("init"); - } - - function loadBatchApp() { - addNewContent(this); - } - - function addNewMenu(name) { - const mount = Que("#left-menu ol").get(); - let menu = Que("#app-menu").get(); - menu = menu.content.cloneNode(true); - - const span = Que("span", menu).get(); - // template では初期状態はexpanded - if (Que("#left-menu.shrinked").list().length > 0) { - const cls = span.classList; - cls.remove("expanded"); - cls.add("shrinked"); - } - span.textContent = name; - mount.appendChild(menu); - } - - function addNewTab(app) { - /* - タブに対するイベント設定のあたり - val.addEventListener("click", function () { - selectTab(index); - */ - const mount = Que("#main-tabs").get(); - let tab = Que("#app-tab").get() - tab = tab.content.cloneNode(true); - const li = Que("li", tab).get(); - li.textContent = app.name; - li.dataset.soloAppId = app.instanceID; - const index = app.instanceID; - mount.appendChild(tab); - - li.addEventListener("click", () => { - selectTab(index); - //mainOrgan.fire("log", "open appID:" + app.instanceID + ", appID:" + app.name, solitude.nerve); - }); - } - - function addNewContent(app) { - const appNode = (Que(app.template).get()).content.cloneNode(true); - const base = Que("div.main-article", appNode); - base.get().classList.remove("undefined"); - base.get().dataset.soloAppId = app.instanceID; - base.que("div.app-container").get().classList.add(app.name); - app.callback(app, base); - - const mount = Que("#app-pane").get(); - mount.appendChild(base.get()); - - } - - function iframeCallback(app, base) { - const iframe = Que("div.app-container > iframe", base).get(); - iframe.setAttribute("id", app.name); - iframe.setAttribute("title", app.name); - iframe.setAttribute("src", app.conf.src); - } - - function staticpageCallback(app, base) { - mysolitude.read.local(app.conf.src).then((text) => { - const parser = new DOMParser(); - const doc = parser.parseFromString(text, "text/html"); - const content = Que("div.app-body", doc).get().cloneNode(true); - Que("div.app-container", base).get().appendChild(content); - - //文書内のJavascriptコードを実行する。簡単な実装。 - //これだとon.loadイベントとかがキックされなくなってしまう気がする。 - const removes = []; - Que("script", content).list().forEach(element => { - const script = document.createElement("script") - script.innerHTML = element.innerHTML; - for (const attr of element.attributes) { - script.setAttribute(attr.name, attr.value); - } - element.before(script) - removes.push(element); - }); - - for (const script of removes) { - script.remove(); - } - - }); - } - - function batchCallback(app, base) { - const content = document.createElement("script") - content.setAttribute("src", app.conf.src); - Que("div.app-container", base).get().appendChild(content); - } + }); } + + function batchCallback(app, base) { + const content = document.createElement("script") + content.setAttribute("src", app.conf.src); + Que("div.app-container", base).get().appendChild(content); + } + } } \ No newline at end of file