+
+
+
+
+
+
+
+
編集部分
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
-
+ }
+ */
+ }
+
+
\ No newline at end of file
diff --git a/src/js/src/bookmark/main.js b/src/js/src/bookmark/main.js
index e9e057e..2f7c1bd 100644
--- a/src/js/src/bookmark/main.js
+++ b/src/js/src/bookmark/main.js
@@ -1,362 +1,410 @@
import { Graphviz } from "/solitude/libs/@hpcc-js/wasm/dist/index.js";
-window.addEventListener("load", (event) => {
- let counter = 0;
- const lf = "\n";
- (async () => {
- const mime = "image/svg+xml;charset=UTF-8";
- try {
- const dotViewer = document.querySelector("#dot-src-viewer");
- const dot = dotViewer.value = card2dot();
- const svg = await dot2svg(dot);
- const dataUri = text2DataUriScheme(svg, mime);
+(function () {
+ window.addEventListener("load", boot);
- document.querySelector("#ref-map").setAttribute("data", dataUri);
- } catch (err) {
- console.log(err);
- }
- })();
+ function boot(event) {
+ let counter = 0;
+ const lf = "\n";
-
- const handle = handlers.call({});
- const menu = document.querySelector("#menuView");
-
- menu.addEventListener("click", handle.generate)
- menu.addEventListener("click", handle.loadCSV);
- menu.addEventListener("click", handle.open)
- menu.addEventListener("click", handle.save)
- menu.addEventListener("click", handle.export)
-
- const editor = document.querySelector("#editView");
- editor.addEventListener("click", handle.appendCard)
- editor.addEventListener("click", handle.deleteCard)
-
- const fileChooser = document.querySelector("#openReal");
- fileChooser.addEventListener('change', handle.openReal);
-
- function handlers() {
- const nameOf = {
- csv: "favorite.csv",
- svg: "result.svg"
- }
- this.appendCard = handleAppendCardButton;
- this.deleteCard = handleDeleteCardButton;
- this.export = handleExportButton;
- this.open = handleOpenButton;
- this.generate = handleGenerateButton;
- this.loadCSV = handleLoadCsvButton;
- this.save = handleSaveButton;
- this.openReal = handleOpenReal;
- return this;
-
- function handleGenerateButton(event) {
- if (event.target.id != "generate") {
- return;
- }
-
- document.querySelector("#dot-src-viewer").value = card2dot();
- dot2svg(document.querySelector("#dot-src-viewer").value)
- .then(xml => {
- const canvas = document.querySelector("#ref-map");
- const data = text2DataUriScheme(xml, "image/svg+xml");
- canvas.setAttribute("data", data);
- }).catch(err => {
- console.log(err)
- });
- }
-
- function handleOpenButton(event) {
- if (event.target.id != "open") {
- return;
- }
-
- document.querySelector("#openReal").click();
- }
-
- function handleLoadCsvButton(event) {
- if (event.target.id != "loadCsv") {
- return;
- }
-
- for (const elem of document.querySelectorAll("button.card-delete")) {
-
- setTimeout(() => {
- deleteCard(elem.closest("div.ref-card"));
- }, 50);
- };
-
- csv2card(document.querySelector("#csv-src-viewer").value);
- }
-
- async function handleSaveButton(event) {
- if (event.target.id != "save") {
- return;
- }
-
+ (async () => {
+ const mime = "image/svg+xml;charset=UTF-8";
try {
- const data = await dot2svg(card2dot());
- download(data, "image/svg+xml;charset=UTF-8", nameOf.svg);
+ const dotViewer = document.querySelector("#dot-src-viewer");
+ const dot = dotViewer.value = card2dot();
+ const svg = await dot2svg(dot);
+ const dataUri = text2DataUriScheme(svg, mime);
+
+ document.querySelector("#ref-map").setAttribute("data", dataUri);
} catch (err) {
console.log(err);
}
- }
+ })();
- function handleExportButton(event) {
- if (event.target.id != "export") {
- return;
+
+ const handle = buttonHandlers.call({});
+
+ function Control(elemental) {
+ if(elemental instanceof Element) {
+ this.element = elemental;
+ } else {
+ this.element = document.querySelector(elemental);
}
- download(card2csv(), "text/csv;charset=UTF-8", nameOf.csv,);
+ }
+ Control.prototype = {
+ set onClick(handler) {
+ if(Array.isArray(handler)) {
+ for(const listener of handler ) {
+ this.element.addEventListener("click", listener);
+ }
+ } else {
+ this.element.addEventListener("click", handler);
+ }
+ },
+
+ set onChange(handler) {
+ this.element.addEventListener("change", handler);
+ }
}
- function handleAppendCardButton(event) {
- if (event.target.classList.contains("card-append")) {
- const bigBrotherCard = event.target.closest("div.ref-card");
- appendCard(bigBrotherCard, {
- id: counter++ + "",
- parent: "root",
- type: "folder",
- label: "nonelabel",
- url: "https://www.exmple.com/"
+ const menu = new Control("#menuView");
+ menu.onClick = [
+ handle.generate,
+ handle.loadCSV,
+ handle.open,
+ handle.save,
+ handle.export,
+ ];
+
+ const editor = new Control("#editView");
+ editor.onClick = [handle.appendCard, handle.deleteCard]
+
+ const fileChooser = new Control("#openReal");
+ fileChooser.onChange = handle.openReal;
+
+ const bars = document.querySelectorAll("div.top-bar,div.bottom-bar");
+ bars.forEach((elem) => {
+ const bar = new Control(elem);
+ bar.onClick = toggle;
+ });
+
+ function buttonHandlers() {
+ const nameOf = {
+ csv: "favorite.csv",
+ svg: "result.svg"
+ }
+ this.appendCard = handleAppendCardButton;
+ this.deleteCard = handleDeleteCardButton;
+ this.export = handleExportButton;
+ this.open = handleOpenButton;
+ this.generate = handleGenerateButton;
+ this.loadCSV = handleLoadCsvButton;
+ this.save = handleSaveButton;
+ this.openReal = handleOpenReal;
+ return this;
+
+ function handleGenerateButton(event) {
+ if (event.target.id != "generate") {
+ return;
+ }
+
+ document.querySelector("#dot-src-viewer").value = card2dot();
+ dot2svg(document.querySelector("#dot-src-viewer").value)
+ .then(xml => {
+ const canvas = document.querySelector("#ref-map");
+ const data = text2DataUriScheme(xml, "image/svg+xml");
+ canvas.setAttribute("data", data);
+ }).catch(err => {
+ console.log(err)
+ });
+ }
+
+ function handleOpenButton(event) {
+ if (event.target.id != "open") {
+ return;
+ }
+
+ document.querySelector("#openReal").click();
+ }
+
+ function handleLoadCsvButton(event) {
+ if (event.target.id != "loadCsv") {
+ return;
+ }
+
+ for (const elem of document.querySelectorAll("button.card-delete")) {
+
+ setTimeout(() => {
+ deleteCard(elem.closest("div.ref-card"));
+ }, 50);
+ };
+
+ csv2card(document.querySelector("#csv-src-viewer").value);
+ }
+
+ async function handleSaveButton(event) {
+ if (event.target.id != "save") {
+ return;
+ }
+
+ try {
+ const data = await dot2svg(card2dot());
+ download(data, "image/svg+xml;charset=UTF-8", nameOf.svg);
+ } catch (err) {
+ console.log(err);
+ }
+ }
+
+ function handleExportButton(event) {
+ if (event.target.id != "export") {
+ return;
+ }
+ download(card2csv(), "text/csv;charset=UTF-8", nameOf.csv,);
+ }
+
+ function handleAppendCardButton(event) {
+ if (event.target.classList.contains("card-append")) {
+ const bigBrotherCard = event.target.closest("div.ref-card");
+ appendCard(bigBrotherCard, {
+ id: counter++ + "",
+ parent: "root",
+ type: "folder",
+ label: "nonelabel",
+ url: "https://www.exmple.com/"
+ })
+ }
+ }
+
+ function handleDeleteCardButton(event) {
+ if (event.target.classList.contains("card-delete")) {
+ setTimeout(() => {
+ deleteCard(event.target.closest("div.ref-card"));
+ }, 50);
+ }
+ }
+
+ function handleOpenReal(event) {
+ const files = document.querySelector("#openReal").files;
+ if (files.length == 0) {
+ return;
+ }
+
+ const reader = new FileReader();
+ const content = reader.readAsText(files[0]);
+
+ reader.addEventListener("load", () => {
+ document.querySelector("#csv-src-viewer").value = reader.result;
})
}
+
}
- function handleDeleteCardButton(event) {
- if (event.target.classList.contains("card-delete")) {
- setTimeout(() => {
- deleteCard(event.target.closest("div.ref-card"));
- }, 50);
+ function toggle(event) {
+ const editor = document.querySelector("div.editor");
+ if (document.querySelectorAll("div.editor.expanded").length > 0) {
+ editor.classList.remove("expanded");
+ editor.classList.add("shrinked");
+
+ } else if (document.querySelectorAll("div.editor.shrinked").length > 0) {
+ editor.classList.remove("shrinked");
+ editor.classList.add("expanded");
}
}
- function handleOpenReal(event) {
- const files = fileChooser.files;
- if (files.length == 0) {
- return;
- }
-
- const reader = new FileReader();
- const content = reader.readAsText(files[0]);
-
- reader.addEventListener("load", () => {
- document.querySelector("#csv-src-viewer").value = reader.result;
- })
- }
-
- }
- function appendCard(bigbrother, node = {}) {
- const newCard = document.querySelector("#tmpl-ref-card").content.cloneNode(true);
- bigbrother.parentNode.insertBefore(newCard, bigbrother.nextElementSibling);
+ function appendCard(bigbrother, node = {}) {
+ const newCard = document.querySelector("#tmpl-ref-card").content.cloneNode(true);
+ bigbrother.parentNode.insertBefore(newCard, bigbrother.nextElementSibling);
- const addedCard = bigbrother.nextElementSibling;
+ const addedCard = bigbrother.nextElementSibling;
- new nodeValues().write(addedCard, node)
- }
-
- function deleteCard(card) {
- card.parentNode.removeChild(card);
- }
-
- function csv2card(csv) {
- //改行をLFだけにしたい
-
- const text = csv.replaceAll("\r", "");
- const textRows = text.split(lf)
- const rows = [];
- //当該要素はrootの一つしか残っていない想定
- let bigBrother = document.querySelector("div.ref-card");
- for (const text of textRows) {
- //ヘッダは読み飛ばす
- if ("id,parent,type,label,url" == text || "" == text.trim()) {
- continue;
- }
-
- const row = text.split(",")
-
- if (row[0] == "root") {
- continue;
- }
-
- appendCard(bigBrother, {
- id: row[0],
- parent: row[1],
- type: row[2],
- label: row[3],
- url: row[4]
- })
-
- let cards = document.querySelectorAll("div.ref-card");
- bigBrother = cards[cards.length - 1]
- }
- }
-
- function card2csv() {
- const cards = document.querySelectorAll("div.ref-card");
- const header = ["id", "parent", "type", "label", "url"].join(",");
- const csvText = [header]
-
- for (const card of cards) {
- const refNode = new nodeValues().read(card);
- csvText.push([
- refNode.id,
- refNode.parent,
- refNode.type,
- refNode.label,
- refNode.url,
- ].join(","));
+ new nodeValues().write(addedCard, node)
}
- return csvText.join(lf)
- }
+ function deleteCard(card) {
+ card.parentNode.removeChild(card);
+ }
- function card2dot() {
- function digraph(nodeList, edgeList) {
- const dot = `digraph G {
+ function csv2card(csv) {
+ //改行をLFだけにしたい
+
+ const text = csv.replaceAll("\r", "");
+ const textRows = text.split(lf)
+ const rows = [];
+ //当該要素はrootの一つしか残っていない想定
+ let bigBrother = document.querySelector("div.ref-card");
+ for (const text of textRows) {
+ //ヘッダは読み飛ばす
+ if ("id,parent,type,label,url" == text || "" == text.trim()) {
+ continue;
+ }
+
+ const row = text.split(",")
+
+ if (row[0] == "root") {
+ continue;
+ }
+
+ appendCard(bigBrother, {
+ id: row[0],
+ parent: row[1],
+ type: row[2],
+ label: row[3],
+ url: row[4]
+ })
+
+ let cards = document.querySelectorAll("div.ref-card");
+ bigBrother = cards[cards.length - 1]
+ }
+ }
+
+ function card2csv() {
+ const cards = document.querySelectorAll("div.ref-card");
+ const header = ["id", "parent", "type", "label", "url"].join(",");
+ const csvText = [header]
+
+ for (const card of cards) {
+ const refNode = new nodeValues().read(card);
+ csvText.push([
+ refNode.id,
+ refNode.parent,
+ refNode.type,
+ refNode.label,
+ refNode.url,
+ ].join(","));
+ }
+
+ return csvText.join(lf)
+ }
+
+ function card2dot() {
+ function digraph(nodeList, edgeList) {
+ const dot = `digraph G {
graph [overlap="true", bgcolor="#ffffdd", mindist="0.01"];
node [fontname="BIZUDP Gothic" target="_blank", shape="tab", style="filled", color="#cc6666", fontcolor="#333333", fillcolor="#ffcc90"];
edge [fontname="meiryo", color="#cc6666"];
-
+
//nodeList
${nodeList}
-
+
//edgeList
${edgeList}
}
`;
- return dot;
+ return dot;
+ }
+
+ const id = 0, parent = 1, type = 2, label = 3, url = 4;
+
+ const [nodeList, edgeList] = [[], []];
+ const cards = document.querySelectorAll("div.ref-card");
+ for (const card of cards) {
+ const refNode = new nodeValues().read(card);
+
+ const id = refNode.id,
+ parent = refNode.parent,
+ type = refNode.type,
+ label = refNode.label,
+ url = refNode.url;
+
+ let shapeStmt;
+ if (type == "folder") {
+ shapeStmt = `, shape="ellipse"`;
+ } else {
+ shapeStmt = ""
+ }
+
+ let labelStmt;
+ if (label == "") {
+ labelStmt = `label="${id}"`;
+ } else {
+ labelStmt = `label="${label}"`;
+ }
+
+ let hrefStmt;
+ if (url == "") {
+ hrefStmt = "";
+ } else {
+ //label属性が必ずあるため区切りの, を決め打ちで入れて問題なし
+ hrefStmt = `, href="${url}"`;
+ }
+
+ const nodeStmt = `${id} [${labelStmt}${hrefStmt}${shapeStmt}];`;
+ nodeList.push(nodeStmt);
+
+ if (id == "root") {
+ continue;
+ } else {
+ const edgeStmt = `${parent} -> ${id};`;
+ edgeList.push(edgeStmt);
+ }
+ }
+
+ //改行してインデント
+ const indent = " ";
+ const delim = lf + indent
+ return digraph(nodeList.join(delim), edgeList.join(delim));
}
- const id = 0, parent = 1, type = 2, label = 3, url = 4;
+ async function dot2svg(dot = "") {
+ const graphviz = await Graphviz.load();
+ const src = dot == "" ? 'digraph G { Hello -> World }' : dot;
+ const svg = graphviz.circo(src);
+ return svg;
+ }
- const [nodeList, edgeList] = [[], []];
- const cards = document.querySelectorAll("div.ref-card");
- for (const card of cards) {
- const refNode = new nodeValues().read(card);
+ function nodeValues() {
+ this.read = readNodeValues;
+ this.write = writeNodeValues;
+ return this;
- const id = refNode.id,
- parent = refNode.parent,
- type = refNode.type,
- label = refNode.label,
- url = refNode.url;
+ /**
+ * ノードを表すカードからノードの情報を取り出す。
+ * カード内のinputについて知っている
+ * @param {*} card
+ * @returns
+ */
+ function readNodeValues(card) {
+ const values = card.querySelectorAll("input");
+ const refNode = {};
+ refNode.id = values[0].value;
+ refNode.parent = values[1].value;
+ refNode.tytpe = values[2].value;
+ refNode.label = values[3].value;
+ refNode.url = values[4].value;
- let shapeStmt;
- if (type == "folder") {
- shapeStmt = `, shape="ellipse"`;
- } else {
- shapeStmt = ""
+ return refNode;
}
- let labelStmt;
- if (label == "") {
- labelStmt = `label="${id}"`;
- } else {
- labelStmt = `label="${label}"`;
- }
+ /**
+ * ノードを表すカードに書き込む
+ * カード内のinputについて知っている
+ */
+ function writeNodeValues(card, values) {
+ const inputs = card.querySelectorAll("input");
+ const { id, parent, type, label, url } = values;
- let hrefStmt;
- if (url == "") {
- hrefStmt = "";
- } else {
- //label属性が必ずあるため区切りの, を決め打ちで入れて問題なし
- hrefStmt = `, href="${url}"`;
- }
+ if (id && id.length > 0) {
+ inputs[0].value = id
+ }
- const nodeStmt = `${id} [${labelStmt}${hrefStmt}${shapeStmt}];`;
- nodeList.push(nodeStmt);
+ if (parent && parent.length > 0) {
+ inputs[1].value = parent
+ }
- if (id == "root") {
- continue;
- } else {
- const edgeStmt = `${parent} -> ${id};`;
- edgeList.push(edgeStmt);
+ if (type && type.length > 0) {
+ inputs[2].value = type
+ }
+
+ if (label && label.length > 0) {
+ inputs[3].value = label
+ }
+
+ if (url && url.length > 0) {
+ inputs[4].value = url
+ }
+
}
}
- //改行してインデント
- const indent = " ";
- const delim = lf + indent
- return digraph(nodeList.join(delim), edgeList.join(delim));
- }
-
- async function dot2svg(dot = "") {
- const graphviz = await Graphviz.load();
- const src = dot == "" ? 'digraph G { Hello -> World }' : dot;
- const svg = graphviz.circo(src);
- return svg;
- }
-
- function nodeValues() {
- this.read = readNodeValues;
- this.write = writeNodeValues;
- return this;
-
- /**
- * ノードを表すカードからノードの情報を取り出す。
- * カード内のinputについて知っている
- * @param {*} card
- * @returns
- */
- function readNodeValues(card) {
- const values = card.querySelectorAll("input");
- const refNode = {};
- refNode.id = values[0].value;
- refNode.parent = values[1].value;
- refNode.tytpe = values[2].value;
- refNode.label = values[3].value;
- refNode.url = values[4].value;
-
- return refNode;
+ function text2DataUriScheme(text, mimeType) {
+ const binary = window.btoa(unescape(encodeURIComponent(text)))
+ const dataUri = `data:${mimeType};base64,${binary}`
+ return dataUri;
}
- /**
- * ノードを表すカードに書き込む
- * カード内のinputについて知っている
- */
- function writeNodeValues(card, values) {
- const inputs = card.querySelectorAll("input");
- const { id, parent, type, label, url } = values;
+ function download(text, mimeType, name,) {
+ const save = document.querySelector("#savelink");
+ const dataUri = text2DataUriScheme(text, mimeType);
- if (id && id.length > 0) {
- inputs[0].value = id
- }
-
- if (parent && parent.length > 0) {
- inputs[1].value = parent
- }
-
- if (type && type.length > 0) {
- inputs[2].value = type
- }
-
- if (label && label.length > 0) {
- inputs[3].value = label
- }
-
- if (url && url.length > 0) {
- inputs[4].value = url
- }
-
+ save.setAttribute("href", dataUri);
+ save.setAttribute("download", name);
+ setTimeout(() => {
+ save.click();
+ save.setAttribute("href", "");
+ save.setAttribute("download", "");
+ }, 50);
}
}
-
- function text2DataUriScheme(text, mimeType) {
- const binary = window.btoa(unescape(encodeURIComponent(text)))
- const dataUri = `data:${mimeType};base64,${binary}`
- return dataUri;
- }
-
- function download(text, mimeType, name,) {
- const save = document.querySelector("#savelink");
- const dataUri = text2DataUriScheme(text, mimeType);
-
- save.setAttribute("href", dataUri);
- save.setAttribute("download", name);
- setTimeout(() => {
- save.click();
- save.setAttribute("href", "");
- save.setAttribute("download", "");
- }, 50);
- }
-});
+})()