From b133aa5ac4ee9e70cef9f861156b1f6c81a1f3cc Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 7 Jun 2019 12:43:16 +0800 Subject: [PATCH] opt wiki.js --- etc/exit.shy | 2 + etc/init.shy | 2 + src/examples/wiki/wiki.go | 19 +++- usr/librarys/chat.js | 2 + usr/librarys/example.js | 67 ++++++++--- usr/librarys/toolkit.js | 58 +++++++++- usr/librarys/wiki.css | 40 +++---- usr/librarys/wiki.js | 232 ++++++++++++++++++-------------------- 8 files changed, 256 insertions(+), 166 deletions(-) diff --git a/etc/exit.shy b/etc/exit.shy index 45dff81f..0c4bd5d9 100644 --- a/etc/exit.shy +++ b/etc/exit.shy @@ -1,3 +1,5 @@ +~wiki + config save tmp/wiki.json wiki_visit ~ssh config save tmp/cert.json work flow trust ~aaa diff --git a/etc/init.shy b/etc/init.shy index 12f631e9..1f427453 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -4,6 +4,8 @@ config load tmp/auth.json auth ~ssh config load tmp/cert.json work flow trust +~wiki + config load tmp/wiki.json wiki_visit source etc/common.shy ~ssh diff --git a/src/examples/wiki/wiki.go b/src/examples/wiki/wiki.go index adcae0b3..ed2f5780 100644 --- a/src/examples/wiki/wiki.go +++ b/src/examples/wiki/wiki.go @@ -1,26 +1,30 @@ package wiki import ( - "bufio" - "bytes" + "github.com/gomarkdown/markdown" + "contexts/ctx" "contexts/web" + "toolkit" + + "bufio" + "bytes" "encoding/xml" "fmt" - "github.com/gomarkdown/markdown" "html/template" "io/ioutil" "net/http" "os" "path" "strings" - "toolkit" ) var Index = &ctx.Context{Name: "wiki", Help: "文档中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ "login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "默认组件"}, + + "componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"}, "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{ "index": []interface{}{ map[string]interface{}{"componet_name": "wiki", "componet_tmpl": "head", "metas": []interface{}{ @@ -49,10 +53,10 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心", }, }, }, Help: "组件列表"}, - "componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"}, "wiki_level": &ctx.Config{Name: "wiki_level", Value: "wiki/自然/编程", Help: "路由数量"}, "wiki_favor": &ctx.Config{Name: "wiki_favor", Value: "index.md", Help: "路由数量"}, + "wiki_visit": &ctx.Config{Name: "wiki_visit", Value: map[string]interface{}{}, Help: "路由数量"}, "wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "wiki", Help: "路由数量"}, "wiki_list": &ctx.Config{Name: "wiki_list", Value: []interface{}{}, Help: "路由数量"}, @@ -69,6 +73,11 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心", which := m.Cmdx("nfs.path", path.Join(m.Confx("wiki_level"), m.Option("wiki_class"), m.Confx("wiki_favor", arg, 0))) if ls, e := ioutil.ReadFile(which); e == nil { + m.Confi("wiki_visit", []string{which, m.Option("remote_ip")}, + m.Confi("wiki_visit", []string{which, m.Option("remote_ip")})+1) + m.Append("visit_count", m.Confi("wiki_visit", []string{which, m.Option("remote_ip")})) + m.Append("visit_total", len(m.Confm("wiki_visit", []string{which}))) + buffer := bytes.NewBuffer([]byte{}) temp, e := template.New("temp").Funcs(ctx.CGI).Parse(string(ls)) if e != nil { diff --git a/usr/librarys/chat.js b/usr/librarys/chat.js index 21ae2f68..adabf3d2 100644 --- a/usr/librarys/chat.js +++ b/usr/librarys/chat.js @@ -515,8 +515,10 @@ var page = Page({ }) page.onlayout(null, page.conf.layout) + page.footer.State("text", "") page.footer.State("action", "") page.footer.Order(["action", "text"]) + page.header.State("user", "") page.header.Order(["user"], function(event, item, value) { page.confirm("logout?") && page.login.Exit() diff --git a/usr/librarys/example.js b/usr/librarys/example.js index 6691a3b0..67abf59f 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -1,7 +1,24 @@ function Page(page) { + var id = 1 + var conf = {} + var conf_cb = {} page.__proto__ = { - _id: 1, ID: function() { - return this._id++ + ID: function() { + return id++ + }, + Conf: function(key, value, cb) { + if (value != undefined) { + var old = conf[key] + conf[key] = value + conf_cb[key] && conf_cb[key](value, old) + } + if (cb != undefined) { + conf_cb[key] = cb + } + if (key != undefined) { + return conf[key] + } + return conf }, Sync: function(m) { var meta = m, data = "", list = [] @@ -195,11 +212,8 @@ function Page(page) { initHeader: function(page, pane, form, output) { var state = {}, list = [], cb = function(event, item, value) { } - pane.State = function(name, value) { - state[name] = value, pane.Show() - } - pane.Order = function(value, cbs) { - list = value, cb = cbs || cb, pane.Show() + pane.Order = function(value, order, cbs) { + state = value, list = order, cb = cbs || cb, pane.Show() } pane.Show = function() { output.innerHTML = "", kit.AppendChild(output, [ @@ -209,6 +223,9 @@ function Page(page) { }}})}, ]) } + pane.State = function(name, value) { + state[name] = value, pane.Show() + } return }, initBanner: function(page, field, option, output) { @@ -223,12 +240,19 @@ function Page(page) { return [{"text": ["shylinux", "div", "title"]}] }, initFooter: function(page, pane, form, output) { - var state = {}, list = [] - pane.State = function(name, value) { - state[name] = value, pane.Show() + var state = {}, list = [], cb = function(event, item, value) { } - pane.Order = function(value) { - list = value, pane.Show() + pane.Order = function(value, order, cbs) { + state = value, list = order, cb = cbs || cb, pane.Show() + } + pane.State = function(name, value) { + if (value != undefined) { + state[name] = value, pane.Show() + } + if (name != undefined) { + return state[name] + } + return state } pane.Show = function() { @@ -263,6 +287,23 @@ function Page(page) { pane.style.height = height+"px" } + var conf = {} + var conf_cb = {} + pane.Conf = function(key, value, cb) { + if (value != undefined) { + var old = conf[key] + conf[key] = value + conf_cb[key] && conf_cb[key](value, old) + } + if (cb != undefined) { + conf_cb[key] = cb + } + if (key != undefined) { + return conf[key] + } + return conf + } + // form init pane.Run = form.Run = function(cmds, cb) { ctx.Run(page, form.dataset, cmds, cb) @@ -278,7 +319,7 @@ function Page(page) { event.preventDefault() } - var conf = cb(page[pane.dataset.init], pane, form) + cb(page[pane.dataset.init], pane, form) }) document.querySelectorAll("body>fieldset").forEach(function(pane) { diff --git a/usr/librarys/toolkit.js b/usr/librarys/toolkit.js index ffab9dc4..65935738 100644 --- a/usr/librarys/toolkit.js +++ b/usr/librarys/toolkit.js @@ -25,6 +25,9 @@ kit = toolkit = { return args }, + Position: function(which) { + return (parseInt((which.scrollTop + which.clientHeight) / which.scrollHeight * 100)||0)+"%" + }, ScrollPage: function(event, conf) { switch (event.key) { case "h": @@ -171,6 +174,9 @@ kit = toolkit = { subs = subs || {} children.forEach(function(child, i) { + if (!child) { + return + } child.data = child.data || {} child.type = child.type || "div" @@ -494,6 +500,55 @@ kit = toolkit = { kit.CopyText() } }, + OrderText: function(pane, text) { + text.querySelectorAll("a").forEach(function(value, index, array) { + kit.OrderLink(value, pane) + }) + text.querySelectorAll("table").forEach(function(value, index, array) { + kit.OrderTable(value) + }) + + var i = 0, j = 0, k = 0 + var h0 = [], h2 = [], h3 = [] + text.querySelectorAll("h2,h3,h4").forEach(function(value, index, array) { + var id = "" + var text = value.innerText + var ratio = parseInt(value.offsetTop/pane.scrollHeight*100) + if (value.tagName == "H2") { + j=k=0 + h2 = [] + id = ++i+"." + text = id+" "+text + h0.push({"fork": [text+" ("+ratio+"%)", h2, function(event) { + location.hash = id + }]}) + } else if (value.tagName == "H3") { + k=0 + h3 = [] + id = i+"."+(++j) + text = id+" "+text + h2.push({"fork": [text+" ("+ratio+"%)", h3, function(event) { + location.hash = id + }]}) + } else if (value.tagName == "H4") { + id = i+"."+j+"."+(++k) + text = id+" "+text + h3.push({"leaf": [text+" ("+ratio+"%)", function(event) { + location.hash = id + }]}) + } + value.innerText = text + value.id = id + }) + return h0 + + text.querySelectorAll("table.wiki_list").forEach(function(value, index, array) { + kit.OrderTable(value, "path", function(event) { + var text = event.target.innerText + ctx.Search({"wiki_class": text}) + }) + }) + }, OrderLink: function(link) { link.target = "_blank" }, @@ -518,9 +573,6 @@ kit = toolkit = { } return true }, - Selector(target, name) { - return target.Selector(name) - } } function right(arg) { diff --git a/usr/librarys/wiki.css b/usr/librarys/wiki.css index b86a24a2..1d089a5e 100644 --- a/usr/librarys/wiki.css +++ b/usr/librarys/wiki.css @@ -1,37 +1,32 @@ -fieldset.Tree>div.output li>div:hover { - background-color:green; -} -fieldset.Tree>div.output>div.tree li { - display:inline; -} -fieldset.Tree>div.output>div.tree li div { - float:left; - padding:5px; - border:solid 2px green; -} -fieldset.Tree>div.output>div.list { +fieldset.Tree>div.output>div.gap { + height:6px; clear:both; - padding-top:5px; } -fieldset.Tree>div.output>div.list li { - display:inline; -} -fieldset.Tree>div.output>div.list li div { +fieldset.Tree>div.output>div.tree>div { + border:solid 2px green; + padding:4px; float:left; - padding:5px; +} +fieldset.Tree>div.output>div.list>div { border:solid 1px green; + padding:4px; + float:left; } -fieldset.Text { - padding:0; +fieldset.Text>div.output>div.menu { + border-right:solid 1px black; + padding-right:10px; + overflow:auto; +} +fieldset.Text>div.output>div.menu.left { + float:left; } fieldset.Text>div.output>div.menu li>div:hover { background-color:red; } fieldset.Text>div.output>div.text { - position:relative; - overflow:auto; padding:10px; + overflow:auto; } fieldset.Text>div.output>div.text strong { background-color:yellow; @@ -39,3 +34,4 @@ fieldset.Text>div.output>div.text strong { border-top:solid 2px green; color:red; } + diff --git a/usr/librarys/wiki.js b/usr/librarys/wiki.js index 947aa2ea..3ff4d904 100644 --- a/usr/librarys/wiki.js +++ b/usr/librarys/wiki.js @@ -5,7 +5,6 @@ var page = Page({ scroll_y: 50, }, onlayout: function(event, sizes) { - return var height = document.body.clientHeight-page.conf.border var width = document.body.clientWidth-page.conf.border page.conf.height = height @@ -18,146 +17,119 @@ var page = Page({ page.footer.Size(width, sizes.footer) sizes.tree == undefined && (sizes.tree = page.tree.clientHeight) - page.tree.Size(width, sizes.tree) + // page.tree.Size(width, sizes.tree) - sizes.text = height - sizes.tree - sizes.header - sizes.footer + sizes.text = height - sizes.tree - sizes.header - sizes.footer - page.conf.border * 3 page.text.Size(width, sizes.text) }, - initList: function(page, pane, form, output) { - ctx.Runs(page, form, function(msg) { - output.innerHTML = "" - kit.AppendChild(output, [{"tree": ctx.Table(msg, function(value, index) { - return {"leaf": [value.file, function(event, target) { - ctx.Search("wiki_favor", value.file) - }]} - })}]) - }) - return + oncontrol: function(event) { + if (event.ctrlKey) { + switch (event.key) { + case "t": + page.tree.Tree() + break + case "m": + page.text.Menu() + break + case "n": + page.tree.Tree("none") + page.text.Menu("none") + break + } + } }, initTree: function(page, pane, form, output) { - // if (!ctx.isMobile) { - // pane.style.float = "left" - // } + var ui = kit.AppendChild(output, [ + {"view": ["back"], "name": "back"}, {"view": ["gap"]}, + {"view": ["tree"], "name": "tree"}, {"view": ["gap"]}, + {"view": ["list"], "name": "list"}, {"view": ["gap"]}, + ]) + + pane.Conf("tree.display", "", function(value, old) { + pane.style.display = value + page.onlayout() + }) + pane.Tree = function(value) { + pane.Conf("tree.display", value || (pane.Conf("tree.display")? "": "none")) + } ctx.Runs(page, form, function(msg) { - output.innerHTML = "" - var back = [{"button": ["知识", function(event) { - ctx.Search({"wiki_level": "", "wiki_class": "", "wiki_favor": ""}) - }]}] - ctx.Search("wiki_class").split("/").forEach(function(value, index, array) { - if (value) { - var favor = [] - for (var i = 0; i <= index; i++) { - favor.push(array[i]) - } - favor.push("") - back.push({"button": [value, function(event) { - ctx.Search({"wiki_class": favor.join("/"), "wiki_favor":""}) - }]}) - } - }) + ui.back.innerHTML = "", kit.AppendChild(ui.back, [ + {"button": ["知识", function(event) { + ctx.Search({"wiki_level": "", "wiki_class": "", "wiki_favor": ""}) + }]}, + ].concat(ctx.Search("wiki_class").split("/").map(function(value, index, array) { + return value && {"button": [value, function(event) { + location.hash = "", ctx.Search({"wiki_class": array.slice(0, index+1).join("/")+"/", "wiki_favor":""}) + }]} + }))) - var ui = kit.AppendChild(output, [ - {"view": ["back"], "list": back}, - {"view": ["tree"], "list": [{"tree": ctx.Table(msg, function(value, index) { - if (value.filename.endsWith("/")) { - return {"leaf": [value.filename, function(event, target) { - ctx.Search({"wiki_class": ctx.Search("wiki_class")+value.filename, "wiki_favor": ""}) - }]} - } - })}]}, - {"view": ["list"], "list": [{"tree": ctx.Table(msg, function(value, index) { - if (!value.filename.endsWith("/")) { - return {"leaf": [value.time.substr(5, 5)+" "+value.filename, function(event, target) { - ctx.Search("wiki_favor", value.filename) - }]} - } - })}]}, - ]) + ui.tree.innerHTML = "", kit.AppendChild(ui.tree, ctx.Table(msg, function(value, index) { + return value.filename.endsWith("/") && {"text": [value.filename, "div"], click: function(event, target) { + location.hash = "", ctx.Search({"wiki_class": ctx.Search("wiki_class")+value.filename, "wiki_favor": ""}) + }} + })) + ui.list.innerHTML = "", kit.AppendChild(ui.list, ctx.Table(msg, function(value, index) { + return !value.filename.endsWith("/") && {"text": [value.time.substr(5, 5)+" "+value.filename, "div"], click: function(event, target) { + location.hash = "", ctx.Search("wiki_favor", value.filename) + }} + })) }) return }, initText: function(page, pane, form, output) { - ctx.Runs(page, form, function(msg) { - if (!msg.result) { - return + var ui = kit.AppendChild(output, [ + {"view": ["menu", "div", "", "menu"]}, + {"view": ["text", "div", "", "text"]}, + ]) + ui.text.onscroll = function(event) { + page.footer.State("text", kit.Position(ui.text)) + } + ui.menu.onscroll = function(event) { + page.footer.State("menu", kit.Position(ui.menu)) + } + + pane.Conf("menu.display", "", function(value, old) { + ui.menu.style.display = value + }) + pane.Conf("menu.float", !kit.isMobile, function(value, old) { + page.onlayout() + }) + pane.Conf("menu.scroll", true, function(value, old) { + page.onlayout() + }) + pane.Menu = function(value) { + pane.Conf("menu.display", value || (pane.Conf("menu.display")? "": "none")) + } + pane.Size = function(width, height) { + if (pane.Conf("menu.float")) { + ui.menu.className = "menu left" + } else { + ui.menu.className = "menu" } - output.innerHTML = "" - var ui = kit.AppendChild(output, [ - {"view": ["menu", "div", "", "menu"]}, - {"view": ["text", "div", msg.result.join(""), "text"]}, - ]) - - ui.text.querySelectorAll("table").forEach(function(value, index, array) { - kit.OrderTable(value) - }) - ui.text.querySelectorAll("table.wiki_list").forEach(function(value, index, array) { - kit.OrderTable(value, "path", function(event) { - var text = event.target.innerText - ctx.Search({"wiki_class": text}) - }) - }) - - ui.text.querySelectorAll("a").forEach(function(value, index, array) { - kit.OrderLink(value, pane) - }) - - - var i = 0, j = 0, k = 0 - var h0 = [], h2 = [], h3 = [] - ui.text.querySelectorAll("h2,h3,h4").forEach(function(value, index, array) { - var id = "" - var level = 0 - var text = value.innerText - var ratio = parseInt(value.offsetTop/pane.scrollHeight*100) - - if (value.tagName == "H2") { - j=k=0 - h2 = [] - id = ++i+"." - text = id+" "+text - h0.push({"fork": [text+" ("+ratio+"%)", h2, function(event) { - console.log(text) - location.hash = id - }]}) - } else if (value.tagName == "H3") { - k=0 - h3 = [] - id = i+"."+(++j) - text = id+" "+text - h2.push({"fork": [text+" ("+ratio+"%)", h3, function(event) { - console.log(text) - location.hash = id - }]}) - } else if (value.tagName == "H4") { - id = i+"."+j+"."+(++k) - text = id+" "+text - h3.push({"leaf": [text+" ("+ratio+"%)", function(event) { - console.log(text) - location.hash = id - }]}) - } - value.innerText = text - value.id = id - }) - kit.AppendChild(ui.menu, [{"tree": h0}]) - - - ui.text.style.width = document.body.offsetWidth-30+"px" - if (i > 0 && !ctx.isMobile) { - ui.menu.style.position = "absolute" - var width = ui.menu.offsetWidth - var height = ui.menu.offsetHeight>400?ui.menu.offsetHeight:600 - - pane.style.marginLeft = width+10+"px" - ui.menu.style.marginLeft = -width-20+"px" - ui.text.style.height = height+"px" - ui.text.style.width = pane.offsetWidth-30+"px" + if (pane.Conf("menu.float") && pane.Conf("menu.scroll")) { + ui.menu.style.height = (height-8)+"px" + ui.text.style.height = ((ui.menu.clientHeight||height)-8-20)+"px" + } else { + ui.menu.style.height = " " + ui.text.style.height = " " } + if (location.hash) { location.href = location.hash } + ui.text.onscroll() + ui.menu.onscroll() + } + + ctx.Runs(page, form, function(msg) { + ui.menu.innerHTML = "", ui.text.innerHTML = msg.result? msg.result.join(""): "" + kit.AppendChild(ui.menu, [{"tree": kit.OrderText(pane, ui.text)}]) + page.footer.State("count", msg.visit_count) + page.footer.State("visit", msg.visit_total) + page.onlayout() + return }) return }, @@ -172,5 +144,19 @@ var page = Page({ } } }) + + page.footer.Order({"text": "", "menu": "", "count": "0", "visit": "0"}, ["visit", "count", "menu", "text"]) + page.header.Order({"tree": "tree", "menu": "menu"}, ["tree", "menu"], function(event, item, value) { + switch (item) { + case "menu": + page.text.Menu() + break + case "tree": + page.tree.Tree() + break + default: + page.confirm("logout?") && page.login.Exit() + } + }) }, })