yuuji@889: // 愛 yuuji@586: (function (){ yuuji@667: function collectElementsByAttr(elm, attr, val) { yuuji@586: var e = document.getElementsByTagName(elm); yuuji@586: if (!e) return null; yuuji@586: var list = []; yuuji@586: for (var i of e) { yuuji@667: if (i.getAttribute(attr) == val) yuuji@586: list.push(i) yuuji@586: } yuuji@586: return list; yuuji@586: } yuuji@675: function nthChildOf(parent, n, elem) { // Return Nth child of type ELEM yuuji@675: // N begins with 1 yuuji@675: var i=0; yuuji@675: var le = elem.toLowerCase(); yuuji@675: for (var c of parent.childNodes) { yuuji@675: if (!c.tagName) continue; yuuji@675: if (c.tagName.toLowerCase() == le) { yuuji@675: if (++i >= n) return c; yuuji@675: } yuuji@675: } yuuji@675: return null; yuuji@675: } yuuji@586: function insertRedirect(e) { yuuji@586: var articleId, textarea = document.getElementById("text"); yuuji@586: var p = e.target, checked = p.checked; yuuji@586: while (p = p.parentNode) yuuji@586: if (p.nodeName.match(/^td$/i)) break; yuuji@586: if (!p) return; yuuji@586: while (p = p.nextSibling) yuuji@586: if (p.nodeName.match(/^td$/i)) break; yuuji@586: if (!p) return; yuuji@586: articleId = p.getAttribute("id"); yuuji@586: if (textarea && articleId) { yuuji@586: var tv = textarea.value, lines; yuuji@586: if (tv) yuuji@586: lines = tv.split("\n"); yuuji@586: else yuuji@586: lines = [""]; yuuji@586: var re = new RegExp("[, ]*#"+articleId+"(?![0-9])"); yuuji@590: checked = (p.nodeName.match(/^input$/) yuuji@590: ? p.checked // checkbox obeys its status yuuji@590: : !lines[0].match(re)) // a-elment toggles redirection yuuji@586: if (checked) { yuuji@586: if (!lines[0].match(re)) { yuuji@586: var re2 = new RegExp(/>#[#0-9, ]+[0-9]/); yuuji@586: if (lines[0].match(re2)) yuuji@586: lines[0] = lines[0].replace( yuuji@586: re2, '$&, '+'#'+articleId); yuuji@586: else { yuuji@586: if (lines[0] > "") lines[0] = " "+lines[0]; yuuji@586: lines[0] = ">#"+articleId+lines[0]; yuuji@586: } yuuji@586: } yuuji@586: } else { // Remove #xxxxx yuuji@586: if (lines[0].match(/^>#[0-9 ,]+#/)) // 2 or more #id's yuuji@586: lines[0] = lines[0].replace( yuuji@586: new RegExp("^>#"+articleId+"[ ,]*"), ">").replace( yuuji@586: new RegExp("[ ,]*#"+articleId), ""); yuuji@586: else { yuuji@586: lines[0] = lines[0].replace( yuuji@586: new RegExp(">#"+articleId+"[ ,]*"), ""); yuuji@586: } yuuji@586: } yuuji@586: lines[0] = lines[0].replace(/^> *$/, ''); yuuji@586: textarea.value = lines.join("\n"); yuuji@586: } yuuji@586: } yuuji@659: function reverseChecks() { yuuji@667: var names = collectElementsByAttr("input", "name", "usel"); yuuji@659: for (let u of names) { yuuji@659: u.checked = !u.checked; yuuji@659: } yuuji@659: } yuuji@852: function renumberOL(str, start) { yuuji@852: var stra = str.split("\n"); yuuji@852: yuuji@852: for (var i=1; i")+1); yuuji@837: i.insertAdjacentHTML("afterend", newi) yuuji@837: // alert(newi); yuuji@837: } yuuji@837: } yuuji@837: } yuuji@837: function initFileInput() { // Multiplies "input type=file" yuuji@837: var el, morefile = document.getElementById("morefile"); yuuji@837: if (morefile) { yuuji@837: for (el of collectElementsByAttr("input", "name", "image")) { yuuji@837: el.addEventListener("change", function(ev) { yuuji@837: if (ev.target.value > "" && ev.target.files.length == 1) yuuji@837: morefile.style.visibility = "visible"; yuuji@837: // No need to hide again, sure? yuuji@837: }); yuuji@837: } yuuji@837: morefile.addEventListener("click", addFileInput, null); yuuji@837: } yuuji@837: // When renaming, select basename part yuuji@837: for (el of collectElementsByAttr("input", "class", "mv")) { yuuji@837: el.addEventListener("focus", function(ev) { yuuji@837: var i = ev.target; yuuji@837: if (i) { yuuji@837: i.setSelectionRange(0, i.value.lastIndexOf(".")); yuuji@837: } yuuji@837: }); yuuji@837: } yuuji@837: } yuuji@846: function initTextarea() { yuuji@846: var te = collectElementsByAttr("textarea", "name", "text"); yuuji@846: if (!te || !te[0]) return; yuuji@846: te[0].addEventListener("keydown", helpMarkdown, false); yuuji@846: } yuuji@659: function initBlogs() { yuuji@837: // Auto-complete #xxxx yuuji@837: var check = collectElementsByAttr("input", "name", "notifyto"); yuuji@586: if (check) yuuji@590: for (let i of check) { yuuji@586: i.addEventListener("click", insertRedirect, null); yuuji@586: } yuuji@590: for (let i of document.getElementsByTagName("a")) yuuji@590: if (i.getAttribute("href").match(/^#[0-9]+$/)) yuuji@590: if (RegExp.lastMatch == i.innerHTML) yuuji@590: i.addEventListener("click", insertRedirect, null) yuuji@586: } yuuji@659: function initGrpAction() { yuuji@659: var rev = document.getElementById("reverse"); yuuji@667: if (!rev) return; // Is not grpAction page yuuji@667: if (rev.tagName.match(/span/i)) { yuuji@659: rev.textContent = " 反転 "; yuuji@659: rev.addEventListener("click", reverseChecks, null); yuuji@659: } yuuji@667: var emailbtn = document.getElementById("email"); yuuji@667: emailbtn.addEventListener("click", function(ev){ yuuji@675: // Enlarge box and Select user's checkbox yuuji@667: if (!ev.target.checked) return; yuuji@673: var x = collectElementsByAttr("div", "class", "foldtabs"); yuuji@673: if (x && x[0] && x[0].style) { yuuji@673: x[0].style.height = "10em"; yuuji@673: } yuuji@667: let myuid = document.getElementById("myuid"); yuuji@667: if (myuid) { yuuji@667: let usel = collectElementsByAttr("input", "name", "usel"); yuuji@667: if (usel) { yuuji@667: for (u of usel) { yuuji@667: if (u.value == myuid.value) yuuji@667: u.checked = true; yuuji@667: } yuuji@667: } yuuji@667: } yuuji@667: }, null); yuuji@675: var teamsel = document.getElementById("selteam"); yuuji@675: if (teamsel) { yuuji@675: var usel, p, team; yuuji@675: // Select all members of the team yuuji@675: teamsel.addEventListener("change", function(ev) { yuuji@675: var teamname = teamsel.value, yuuji@676: selected = new RegExp('(^| )'+teamname+"($|,)"); yuuji@675: usel = collectElementsByAttr("input", "name", "usel"); yuuji@675: if (!usel) return; yuuji@675: for (u of usel) { yuuji@675: p = u.parentNode; // should be label yuuji@675: if (!p) continue; yuuji@675: if (teamname == "TEAM") { // Reset all checks yuuji@675: u.checked = false; // when "TEAM" is selected yuuji@675: } else { yuuji@675: p = p.parentNode.parentNode;// should be tr yuuji@675: team = nthChildOf(p, 3, "td") yuuji@675: if (team && team.textContent yuuji@675: && team.textContent.match(selected)) { yuuji@675: u.checked = true; yuuji@675: } yuuji@675: } yuuji@675: } yuuji@675: }, null); yuuji@675: } yuuji@659: } yuuji@893: function dispInfoMomentary(msg, elem) { yuuji@893: // Momentarily display MSG in tooltip-baloon relative to ELEM element. yuuji@893: let help = document.createElement("p"); yuuji@893: elem.style.position = 'relative'; yuuji@893: elem.style.overflow = 'visible'; yuuji@893: help.setAttribute("class", "info-tooltip"); yuuji@893: help.innerHTML = msg; yuuji@893: elem.appendChild(help); yuuji@893: setTimeout(() => { yuuji@893: help.classList.add("dissolving"); yuuji@893: setTimeout(() => help.remove(), 3000); yuuji@893: }, 1000); yuuji@893: } yuuji@889: function initGrphome() { yuuji@889: console.log("initGrphome"); yuuji@889: let btn = document.querySelectorAll("button.toggle-frozen"); yuuji@889: if (!btn) return; yuuji@889: let url = document.URL, yuuji@889: mypath = url.substring(url.lastIndexOf("/")); yuuji@889: if (mypath.match(/(.*)\/(.*)/)) { yuuji@889: mypath = RegExp.$2; yuuji@889: mypath = mypath.substring(0, mypath.lastIndexOf("?")); yuuji@889: //alert("mypath="+mypath); yuuji@889: } else return; yuuji@893: var ja = navigator.language.match(/ja/i); yuuji@889: yuuji@889: function toggleFrozen(e, rowid) { yuuji@889: let tgt = mypath+"?blog_setfrozen+"+rowid; yuuji@893: let td = e.target.parentNode; yuuji@893: let tr = td.parentNode; yuuji@889: fetch(tgt, { yuuji@889: method: "POST", yuuji@889: headers: {'Content-Type': 'text/html; charset=utf-8'}, yuuji@889: }).then(function(resp) { yuuji@889: return resp.text(); yuuji@889: }).then(function(tbody) { yuuji@889: try { yuuji@889: var json = JSON.parse(tbody); yuuji@889: } catch (e) { yuuji@889: return; yuuji@889: } yuuji@893: let state = json.state, newstate, info; yuuji@889: if (json.alert) { yuuji@889: alert(json.alert) yuuji@889: } yuuji@889: if (state.match(/frozen/i)) { yuuji@889: newstate = "凍結"; yuuji@893: info = ja ? newstate+"に設定しました" : 'Set Frozen'; yuuji@889: } else { yuuji@889: newstate = null; yuuji@893: info = ja ? '稼動に設定しました' : 'Set Running'; yuuji@889: } yuuji@889: tr.setAttribute("class", newstate); yuuji@893: dispInfoMomentary(info, td); yuuji@889: }); yuuji@889: } yuuji@889: for (let b of btn) { yuuji@889: let rowid = null; yuuji@893: let td=b.parentNode, tr = td.parentNode, fr, ru; yuuji@893: ru = ja ? "動" : "Running"; yuuji@893: fr = ja ? "凍" : "Frozen"; yuuji@893: b.setAttribute('frozen-marker', fr); yuuji@893: b.setAttribute('running-marker', ru); yuuji@889: for (let a of tr.querySelectorAll("a[href]")) { yuuji@889: if (a.getAttribute("href").match(/\?replyblog\+([0-9]+)/)) { yuuji@889: rowid = parseInt(RegExp.$1); yuuji@889: break; yuuji@889: } yuuji@889: } yuuji@889: if (rowid && rowid>0) { yuuji@889: b.addEventListener("click", function(e) { yuuji@889: if (!btn) return; yuuji@889: toggleFrozen(e, rowid); yuuji@889: }, false); yuuji@889: b.setAttribute("title", "稼動/凍結をその場で切り替えます\n\ yuuji@889: Toggle Running/Frozen ("+rowid+")"); yuuji@889: } yuuji@889: } yuuji@889: } yuuji@659: function init() { yuuji@659: initGrpAction(); yuuji@659: initBlogs(); yuuji@837: initFileInput(); yuuji@846: initTextarea(); yuuji@889: initGrphome(); yuuji@659: } yuuji@586: document.addEventListener('DOMContentLoaded', init, null); yuuji@586: })();