From 1590112fba4d810481f85062d0b53898c128baa5 Mon Sep 17 00:00:00 2001 From: shylinux Date: Wed, 28 Jun 2023 21:55:01 +0800 Subject: [PATCH] add portal --- base/ctx/config.go | 1 + base/lex/split.go | 2 +- base/ssh/script.go | 2 +- base/tcp/host.go | 4 +++ base/web/render.go | 2 +- base/web/serve.go | 11 +++++-- base/web/space.go | 2 +- conf.go | 1 + core/chat/cmd.go | 4 +-- core/chat/portal.go | 21 ++++++++++++++ core/chat/river.go | 6 ++-- core/chat/storm.go | 4 +-- core/code/autogen.go | 2 +- core/code/compile.go | 4 ++- core/code/portal.go | 12 ++++++++ core/code/webpack.go | 3 +- core/wiki/portal.css | 40 ++++++++++++++++++++++++++ core/wiki/portal.go | 34 ++++++++++++++++++++++ core/wiki/portal.js | 68 ++++++++++++++++++++++++++++++++++++++++++++ core/wiki/spark.go | 15 ++++++++-- core/wiki/title.go | 16 +++++++++-- info.go | 3 ++ meta.go | 2 +- misc/alpha/alpha.go | 9 ++++-- misc/chrome/page.go | 2 +- misc/chrome/style.go | 7 +++++ misc/chrome/sync.go | 2 +- misc/git/repos.go | 3 ++ 28 files changed, 256 insertions(+), 26 deletions(-) create mode 100644 core/chat/portal.go create mode 100644 core/code/portal.go create mode 100644 core/wiki/portal.css create mode 100644 core/wiki/portal.go create mode 100644 core/wiki/portal.js diff --git a/base/ctx/config.go b/base/ctx/config.go index c5c16030..eedd095a 100644 --- a/base/ctx/config.go +++ b/base/ctx/config.go @@ -184,6 +184,7 @@ func init() { nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(mdb.EXPORT, arg[0], "", mdb.HASH, path.Join(ice.VAR_TRASH, kit.Keys(arg[0]))) nfs.Trash(m, path.Join(ice.VAR_DATA, arg[0])) + mdb.Config(m, arg[0], nil, nil) m.Go(func() { m.Cmd(ice.EXIT, 1) }) }}, mdb.LIST: {Hand: func(m *ice.Message, arg ...string) { diff --git a/base/lex/split.go b/base/lex/split.go index 3777aeba..fe1bed8a 100644 --- a/base/lex/split.go +++ b/base/lex/split.go @@ -17,7 +17,7 @@ func _split_tab(text string) (tab int) { case ' ': tab++ default: - break + return } } return diff --git a/base/ssh/script.go b/base/ssh/script.go index 27434c49..a1b8d173 100644 --- a/base/ssh/script.go +++ b/base/ssh/script.go @@ -44,7 +44,7 @@ func (f *Frame) prompt(m *ice.Message, arg ...string) *Frame { case mdb.COUNT: fmt.Fprintf(f.stdout, "%d", f.count) case tcp.HOSTNAME: - fmt.Fprintf(f.stdout, "%s", kit.Slice(kit.Split(ice.Info.Hostname, " -/."), -1)[0]) + fmt.Fprintf(f.stdout, ice.Info.NodeName) case mdb.TIME: fmt.Fprintf(f.stdout, kit.Slice(kit.Split(time.Now().Format(ice.MOD_TIME)), -1)[0]) case TARGET: diff --git a/base/tcp/host.go b/base/tcp/host.go index e082dfdd..336a0296 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -1,6 +1,7 @@ package tcp import ( + "fmt" "net" "strings" @@ -87,3 +88,6 @@ func init() { func IsLocalHost(m *ice.Message, ip string) bool { return m.Cmdx(HOST, ISLOCAL, ip) == ice.OK } func PublishLocalhost(m *ice.Message, url string) string { return m.Cmdx(HOST, PUBLISH, url) } +func Address(host, port string) string { + return fmt.Sprintf("%s:%s", host, port) +} diff --git a/base/web/render.go b/base/web/render.go index ecdbc8f3..0e536a81 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -129,7 +129,7 @@ func RenderCmds(m *ice.Message, list ...ice.Any) { RenderTemplate(m.Options(nfs.VERSION, renderVersion(m), mdb.LIST, kit.Format(list)), "cmds.html") } func RenderPodCmd(m *ice.Message, pod, cmd string, arg ...ice.Any) { - msg := m.Cmd(Space(m, pod), ctx.COMMAND, kit.Select("web.wiki.word", cmd)) + msg := m.Cmd(Space(m, pod), ctx.COMMAND, kit.Select(m.PrefixKey(), cmd)) RenderCmds(m, kit.Dict(msg.AppendSimple(mdb.NAME, mdb.HELP), ctx.INDEX, msg.Append(ctx.INDEX), ctx.ARGS, kit.Simple(arg), ctx.DISPLAY, m.Option(ice.MSG_DISPLAY), mdb.LIST, kit.UnMarshal(msg.Append(mdb.LIST)), mdb.META, kit.UnMarshal(msg.Append(mdb.META)), diff --git a/base/web/serve.go b/base/web/serve.go index 224b9b73..89d04233 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -53,14 +53,19 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { } else { r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, nfs.DF)[0]) } - // kit.For(r.Header, func(k string, v []string) { m.Debug("what %v %v", k, v) }) - kit.If(path.Join(r.URL.Path) == nfs.PS, func() { r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")) }) if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet { if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS { + if !msg.IsCliUA() { + if r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")); path.Join(r.URL.Path) != nfs.PS { + return true + } + } return !Render(RenderMain(msg), msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...) } else if p := path.Join(kit.Select(ice.USR_VOLCANOS, ice.USR_INTSHELL, msg.IsCliUA()), r.URL.Path); nfs.Exists(msg, p) { return !Render(msg, ice.RENDER_DOWNLOAD, p) } + } else if r.Method == http.MethodPost && path.Join(r.URL.Path) == nfs.PS { + r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")) } return true } @@ -185,7 +190,7 @@ func init() { if strings.HasPrefix(sub, nfs.PS) { kit.If(action.Hand == nil, func() { action.Hand = cmd.Hand }) sub = kit.Select(P(key, sub), PP(key, sub), strings.HasSuffix(sub, nfs.PS)) - c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ctx.CmdAction(), Hand: func(m *ice.Message, arg ...string) { + c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ice.MergeActions(cmd.Actions, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { msg := m.Spawn(c, key, cmd) defer m.Copy(msg) action.Hand(msg, arg...) diff --git a/base/web/space.go b/base/web/space.go index 98659d9c..ed970bf2 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -49,7 +49,7 @@ func _space_fork(m *ice.Message) { addr := kit.Select(m.R.RemoteAddr, m.R.Header.Get(ice.MSG_USERADDR)) name := kit.ReplaceAll(kit.Select(addr, m.Option(mdb.NAME)), "[", "_", "]", "_", nfs.DF, "_", nfs.PT, "_") text := kit.Select(addr, m.Option(mdb.TEXT)) - if kit.IsIn(m.Option(mdb.TYPE), CHROME) || !(ice.Info.Localhost && tcp.IsLocalHost(m, m.R.RemoteAddr) || + if kit.IsIn(m.Option(mdb.TYPE), CHROME) && m.Option(mdb.NAME) != "chrome" || !(ice.Info.Localhost && tcp.IsLocalHost(m, m.R.RemoteAddr) || m.Option(TOKEN) != "" && m.Cmdv(TOKEN, m.Option(TOKEN), mdb.TIME) > m.Time()) { name = kit.ReplaceAll(addr, "[", "_", "]", "_", nfs.DF, "_", nfs.PT, "_") text = kit.Select(addr, m.Option(mdb.NAME), m.Option(mdb.TEXT)) diff --git a/conf.go b/conf.go index d81817d0..3a517304 100644 --- a/conf.go +++ b/conf.go @@ -156,6 +156,7 @@ const ( // DIR SRC_WEBVIEW_GO = "src/webview.go" SRC_VERSION_GO = "src/version.go" SRC_BINPACK_GO = "src/binpack.go" + SRC_DOCUMENT = "src/document/" SRC_TEMPLATE = "src/template/" SRC_SCRIPT = "src/script/" README_MD = "README.md" diff --git a/core/chat/cmd.go b/core/chat/cmd.go index de05d867..8c2ee586 100644 --- a/core/chat/cmd.go +++ b/core/chat/cmd.go @@ -15,8 +15,8 @@ import ( func _cmd_file(m *ice.Message, arg ...string) bool { switch p := path.Join(arg...); kit.Ext(p) { - case nfs.SHY: - web.RenderCmd(m, "web.wiki.word", p) + // case nfs.SHY: + // web.RenderCmd(m, "web.wiki.word", p) case nfs.GO: web.RenderCmd(m, ctx.GetFileCmd(p)) case nfs.JS: diff --git a/core/chat/portal.go b/core/chat/portal.go new file mode 100644 index 00000000..117f95cc --- /dev/null +++ b/core/chat/portal.go @@ -0,0 +1,21 @@ +package chat + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" +) + +const PORTAL = "portal" + +func init() { + Index.MergeCommands(ice.Commands{ + PORTAL: {Name: "portal path auto", Help: "门户", Actions: ice.MergeActions(ice.Actions{ + mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { + mdb.IsSearchForEach(m, arg, func() []string { return []string{web.LINK, PORTAL, m.MergePodCmd("", "") + nfs.PS} }) + }}, + nfs.PS: {Hand: func(m *ice.Message, arg ...string) { web.RenderMain(m) }}, + }), Hand: func(m *ice.Message, arg ...string) {}}, + }) +} diff --git a/core/chat/river.go b/core/chat/river.go index 9d3e9637..68d497dd 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -28,8 +28,8 @@ func _river_list(m *ice.Message) { return } } - m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.HASH, ice.OptionFields(mdb.HASH, mdb.NAME), func(value ice.Maps) { - kit.If(_river_right(m, value[mdb.HASH]), func() { m.PushRecord(value, mdb.HASH, mdb.NAME) }) + m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.HASH, ice.OptionFields(mdb.HASH, mdb.NAME, mdb.ICON), func(value ice.Maps) { + kit.If(_river_right(m, value[mdb.HASH]), func() { m.PushRecord(value, mdb.HASH, mdb.NAME, mdb.ICON) }) }) m.Sort(mdb.NAME) } @@ -70,7 +70,7 @@ func init() { } gdb.Event(m, RIVER_CREATE, RIVER, m.Option(ice.MSG_RIVER, h), arg) }}, - }, aaa.WhiteAction(), mdb.ImportantHashAction(mdb.FIELD, "time,hash,type,name,text,template")), Hand: func(m *ice.Message, arg ...string) { + }, aaa.WhiteAction(), mdb.ImportantHashAction(mdb.FIELD, "time,hash,type,icon,name,text,template")), Hand: func(m *ice.Message, arg ...string) { if m.Warn(m.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin) || !aaa.Right(m, RIVER, arg) { return } else if len(arg) == 0 { diff --git a/core/chat/storm.go b/core/chat/storm.go index bef0a2ce..899e245d 100644 --- a/core/chat/storm.go +++ b/core/chat/storm.go @@ -39,9 +39,9 @@ func init() { }}, }, Hand: func(m *ice.Message, arg ...string) { if m.Option(ice.MSG_STORM) == "" { - m.Cmdy(mdb.SELECT, RIVER, _river_key(m), mdb.HASH, ice.OptionFields("time,hash,name,text,count")) + m.Cmdy(mdb.SELECT, RIVER, _river_key(m), mdb.HASH, ice.OptionFields("time,hash,icon,name,text,count")) } else if len(arg) == 0 || kit.Int(arg[0]) > 0 { - m.Cmdy(mdb.SELECT, RIVER, _storm_key(m), mdb.LIST, mdb.ID, arg, ice.OptionFields("time,id,space,index,args,style,display,deleted")).SortInt(mdb.ID) + m.Cmdy(mdb.SELECT, RIVER, _storm_key(m), mdb.LIST, mdb.ID, arg, ice.OptionFields("time,id,space,icon,index,args,style,display,deleted")).SortInt(mdb.ID) } else if aaa.Right(m, arg) { m.Push(ctx.INDEX, arg[0]) } diff --git a/core/code/autogen.go b/core/code/autogen.go index 773ba536..99424fe1 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -143,7 +143,7 @@ func init() { USR_RELEASE_CONF_GO = "usr/release/conf.go" USR_RELEASE_BINPACK_GO = "usr/release/binpack.go" ) - if m.Cmd(BINPACK, mdb.CREATE); nfs.Exists(m, ice.USR_RELEASE) && m.Option(ice.MSG_USERPOD) == "" { + if m.Cmd(BINPACK, mdb.CREATE); nfs.Exists(m, ice.USR_RELEASE) && m.Option(ice.MSG_USERPOD) == "" && ice.Info.Make.Remote == "https://shylinux.com/x/contexts" { nfs.CopyFile(m, USR_RELEASE_BINPACK_GO, ice.SRC_BINPACK_GO, func(buf []byte, offset int) []byte { kit.If(offset == 0, func() { buf = bytes.Replace(buf, []byte("package main"), []byte("package ice"), 1) }) return buf diff --git a/core/code/compile.go b/core/code/compile.go index af758bbf..189f2a80 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -87,7 +87,9 @@ func init() { } m.Logs(nfs.SAVE, nfs.TARGET, file, nfs.SOURCE, main) m.Cmdy(nfs.DIR, file, "time,path,size,hash,link") - kit.If(strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS) }) + if !m.IsCliUA() { + kit.If(strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS) }) + } }}, }) } diff --git a/core/code/portal.go b/core/code/portal.go new file mode 100644 index 00000000..6c5cf5e7 --- /dev/null +++ b/core/code/portal.go @@ -0,0 +1,12 @@ +package code + +import ice "shylinux.com/x/icebergs" + +const PORTAL = "portal" + +func init() { + Index.MergeCommands(ice.Commands{ + PORTAL: {Name: "portal path auto", Help: "门户", Hand: func(m *ice.Message, arg ...string) { + }}, + }) +} diff --git a/core/code/webpack.go b/core/code/webpack.go index 6359c6d0..9ea7d170 100644 --- a/core/code/webpack.go +++ b/core/code/webpack.go @@ -19,10 +19,11 @@ import ( func _volcanos(m *ice.Message, p ...string) string { return ice.USR_VOLCANOS + path.Join(p...) } func _publish(m *ice.Message, p ...string) string { return ice.USR_PUBLISH + path.Join(p...) } func _require(m *ice.Message, p string) string { + p = strings.Replace(p, ice.USR_MODULES, "/require/modules/", 1) if kit.HasPrefix(p, "src/", "usr/") { return path.Join("/require/", p) } - return path.Join(nfs.PS, strings.TrimPrefix(strings.Replace(p, ice.USR_MODULES, "/require/modules/", 1), ice.USR_VOLCANOS)) + return path.Join(nfs.PS, strings.TrimPrefix(p, ice.USR_VOLCANOS)) } func _webpack_css(m *ice.Message, css, js io.Writer, p string) { fmt.Fprintln(css, kit.Format("/* %s */", _require(m, p))) diff --git a/core/wiki/portal.css b/core/wiki/portal.css new file mode 100644 index 00000000..eb6e2c98 --- /dev/null +++ b/core/wiki/portal.css @@ -0,0 +1,40 @@ +fieldset.web.wiki.portal>div.output>div.header { background-color: rgb(22 31 49); color:white; text-align:center; display:flex; justify-content:center; height:64px; } +fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] { display:flex; justify-content:center; } +fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item { padding:20px; float:left; } +fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item.space { padding:0px; margin:0 40px; } +fieldset.web.wiki.portal>div.output>div.layout { display:flex; justify-content:center; } +fieldset.web.wiki.portal>div.output>div.layout>div.nav { padding:40px 40px; border-right:lightgray solid 1px; --hover-bg-color:var(--plugin-bg-color); } +fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu] div.item { padding:10px; } +fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu] div.list div.item { padding-left:20px; } +fieldset.web.wiki.portal>div.output>div.layout>div.main { white-space:pre-wrap; padding:40px; height:600px; min-width:200px; max-width:1000px; overflow:auto; --hover-bg-color:var(--plugin-bg-color); } +fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset:not(.hide) { display:flex; flex-wrap:wrap; } +fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset>div.output { width:100%; } +fieldset.web.wiki.portal>div.output>div.layout>div.aside { padding:40px 20px; width:200px; --hover-bg-color:var(--plugin-bg-color); } +fieldset.web.wiki.portal>div.output>div.layout>div.aside div.item { padding:5px; } +fieldset.web.wiki.portal>div.output>div.layout>div.aside div.item.section { padding-left:20px; } +body.dark fieldset.web.wiki.portal>div.output { background-color:black; } +body.dark fieldset.web.wiki.portal>div.output>div.header { color:silver; } +body.dark fieldset.web.wiki.portal>div.output>div.layout>div.nav { border-right:gray solid 1px; } + +fieldset.web.wiki.portal>div.output>div.layout>div.main>* { margin:auto; } +fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.flex { display:flex; justify-content:center; } +fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.flex>* { padding:40px 40px; } +fieldset.web.wiki.portal>div.output>div.layout>div.main h1 { margin:10px 0; } +fieldset.web.wiki.portal>div.output>div.layout>div.main h2 { text-align:center; max-width:1000px; margin:0 auto;} +fieldset.web.wiki.portal>div.output>div.layout>div.main ul>li { white-space:pre-wrap; } +fieldset.web.wiki.portal>div.output>div.layout>div.main p { white-space:pre-wrap; } +fieldset.web.wiki.portal>div.output>div.layout>div.main p { text-align:center; max-width:1000px; } +fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { background-color:black; color:white; } +fieldset.web.wiki.portal>div.output>div.layout>div.main input.story[type=button] { background-color:blue; color:white; font-family:system-ui; font-weight:bold; padding:20px 40px; margin:10px; height:60px; border-radius:0; } +fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.inner.output div.content { padding:20px; border-radius:10px; } +body.light fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.inner.output div.content { background-color:black; color:white; } +fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.inner.output { + --code-comment:white; + --code-keyword:orange; + --code-package:white; + --code-datatype:white; + --code-function:cyan; + --code-constant:white; + --code-string:white; + --code-object:white; +} diff --git a/core/wiki/portal.go b/core/wiki/portal.go new file mode 100644 index 00000000..29c0ab91 --- /dev/null +++ b/core/wiki/portal.go @@ -0,0 +1,34 @@ +package wiki + +import ( + "path" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" +) + +const PORTAL = "portal" + +func init() { + const ( + HEADER = "header" + NAV = "nav" + INDEX_SHY = "index.shy" + ) + Index.MergeCommands(ice.Commands{ + PORTAL: {Name: "portal path auto", Help: "门户", Actions: ice.MergeActions(ice.Actions{ + mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { + mdb.IsSearchForEach(m, arg, func() []string { return []string{web.LINK, PORTAL, m.MergePodCmd("", "") + nfs.PS} }) + }}, + nfs.PS: {Hand: func(m *ice.Message, arg ...string) { web.RenderCmd(m, "", arg) }}, + }, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { + if m.Push(HEADER, m.Cmdx(WORD, path.Join(ice.SRC_DOCUMENT, INDEX_SHY))); len(arg) > 0 { + m.Push(NAV, m.Cmdx(WORD, path.Join(ice.SRC_DOCUMENT, path.Join(arg...), INDEX_SHY))) + } + m.Display("") + }}, + }) +} diff --git a/core/wiki/portal.js b/core/wiki/portal.js new file mode 100644 index 00000000..1934e184 --- /dev/null +++ b/core/wiki/portal.js @@ -0,0 +1,68 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { can.db = {nav: {}}, can.require(["/plugin/local/wiki/word.js"]), can.Conf(html.PADDING, 0) + can.ui = can.onappend.layout(can, ["header", ["nav", "main", "aside"]], html.FLOW) + can.ui.header.innerHTML = msg.Append("header"), can.ui.nav.innerHTML = msg.Append("nav") + can.db.prefix = location.pathname.indexOf("/wiki/portal/") == 0? "/wiki/portal/": "/chat/cmd/web.wiki.portal/" + can.db.current = can.isCmdMode()? can.base.trimPrefix(location.pathname, can.db.prefix): can.Option(nfs.PATH) + if (msg.Append("nav") == "") { + can.db.current == "" && can.page.style(can, can.ui.main, "padding", "0px", "max-width", "2000px") + can.onmotion.hidden(can, can.ui.nav), can.onmotion.hidden(can, can.ui.aside) + can.onimport.content(can, "content.shy") + } + if (can.isCmdMode()) { can.onappend.style(can, html.OUTPUT), can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width()) } + can.onappend.style(can, {height: can.ConfHeight()-can.ui.header.offsetHeight, width: can.ConfWidth()-can.ui.nav.offsetWidth-can.ui.aside.offsetWidth}, can.ui.main) + can.ConfHeight(can.ui.main.offsetHeight), can.ConfWidth(can.ui.main.offsetWidth) + can.page.Select(can, can._output, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{} + can.core.CallFunc([can.onimport, can.onimport[meta.name]? meta.name: meta.type||target.tagName.toLowerCase()], [can, meta, target, can.ConfWidth()]) + meta.style && can.page.style(can, target, can.base.Obj(meta.style)) + }) + var file = nfs.SRC_DOCUMENT+can.db.current+(can.isCmdMode()? can.base.trimPrefix(location.hash, "#"): can.Option(nfs.FILE)) + var nav = can.db.nav[file]; nav && nav.click() + }, + navmenu: function(can, meta, target) { + can.onimport.list(can, can.base.Obj(meta.data), function(event, item) { + can.page.Select(can, target, html.DIV_ITEM, function(target) { target != event.target && can.page.ClassList.del(can, target, html.SELECT) }) + if (item.list && item.list.length > 0) { return } + can.onaction.route(event, can, item.meta.link) + }, target, can.page.ClassList.has(can, target.parentNode, "header")? function(target, item) { + if (item.meta.name == "_") { target.innerHTML = "", can.onappend.style(can, html.SPACE, target) } + }: function(target, item) { can.db.nav[item.meta.link] = target + location.hash || item.list && item.list.length > 0 || can.onaction.route({}, can, item.meta.link, true) + }) + }, + button: function(can, meta, target) { var item = can.base.Obj(meta.meta) + target.onclick = function(event) { can.onaction.route(event, can, item.route) } + }, + field: function(can, meta, target, width) { var item = can.base.Obj(meta.meta); item.inputs = item.list, item.feature = item.meta + can.onappend._init(can, item, [chat.PLUGIN_STATE_JS], function(sub) { + sub.run = function(event, cmds, cb, silent) { can.runActionCommand(event, item.index, cmds, cb, true) } + sub.onimport.size(sub, parseInt(item.height)||can.base.Min(can.ConfHeight()/2, 300, 600), can.base.Max(parseInt(item.width)||width||can.ConfWidth(), 1000)) + }, can.ui.main, target) + }, + image: function(can, meta, target) { + can.page.style(can, target, html.WIDTH, can.ConfWidth()) + }, + content: function(can, file) { + can.runActionCommand(event, web.WIKI_WORD, [nfs.SRC_DOCUMENT+can.db.current+file], function(msg) { can.ui.main.innerHTML = msg.Result(), can.onmotion.clear(can, can.ui.aside) + can.page.Select(can, can.ui.main, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{} + meta.type == wiki.TITLE && can.onappend.style(can, meta.name, can.onimport.item(can, {name: meta.text}, function(event) { target.scrollIntoView() }, function() {}, can.ui.aside)) + can.core.CallFunc([can.onimport, can.onimport[meta.name]? meta.name: meta.type||target.tagName.toLowerCase()], [can, meta, target, can.ui.main.offsetWidth-80]) + var _meta = can.base.Obj(meta.meta); _meta && _meta.style && can.page.style(can, target, can.base.Obj(_meta.style)) + meta.style && can.page.style(can, target, can.base.Obj(meta.style)) + }) + }) + }, +}, [""]) +Volcanos(chat.ONACTION, { + route: function(event, can, route, internal) { + var link = can.base.trimPrefix(route||"", nfs.SRC_DOCUMENT); if (!link || link == can.db.current) { return } + if (!internal) { + if (link == nfs.PS) { return can.user.jumps(can.db.prefix) } + if (can.base.beginWith(link, web.HTTP, nfs.PS)) { return can.user.opens(link) } + if (link.indexOf(can.db.current) < 0 || link.endsWith(nfs.PS)) { return can.user.jumps(can.db.prefix+link) } + } + var file = can.base.trimPrefix(link, can.db.current); can.user.jumps("#"+file) + if (can.onmotion.cache(can, function() { return file }, can.ui.main, can.ui.aside)) { return } + can.onimport.content(can, file) + }, +}) diff --git a/core/wiki/spark.go b/core/wiki/spark.go index b322f068..c6b33359 100644 --- a/core/wiki/spark.go +++ b/core/wiki/spark.go @@ -73,11 +73,22 @@ func init() { }), Hand: func(m *ice.Message, arg ...string) { if kit.Ext(arg[0]) == "md" { _spark_md(m, arg...) - } else if arg[0] == SHELL && kit.IsIn(kit.Select("", arg, 1), cli.LINUX, cli.MACOS, cli.DARWIN, cli.WINDOWS) { + } else if arg[0] == SHELL && kit.IsIn(kit.Select("", arg, 1), cli.ALPINE, cli.CENTOS, cli.LINUX, cli.MACOS, cli.DARWIN, cli.WINDOWS) { _spark_tabs(m, arg...) } else { arg = _name(m, arg) - _spark_show(m, arg[0], strings.TrimSpace(arg[1]), arg[2:]...) + meta := kit.Dict() + kit.For(arg[2:], func(k, v string) { kit.Value(meta, k, v) }) + m.Option(mdb.META, kit.Format(meta)) + _spark_show(m, arg[0], strings.TrimSpace(arg[1])) + } + }}, + "style": {Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case "end": + m.Echo("") + default: + m.Echo(`
`, "story", arg[0]) } }}, }) diff --git a/core/wiki/title.go b/core/wiki/title.go index bc456031..413a8b0b 100644 --- a/core/wiki/title.go +++ b/core/wiki/title.go @@ -2,6 +2,7 @@ package wiki import ( "path" + "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/lex" @@ -12,8 +13,19 @@ import ( ) func _title_parse(m *ice.Message, text string) string { - return m.Cmdx(lex.SPLIT, "", "name,link", kit.Dict(nfs.CAT_CONTENT, text), func(ls []string) []string { - kit.If(!kit.HasPrefix(ls[1], nfs.PS, web.HTTP), func() { ls[1] = path.Join(path.Dir(m.Option(ice.MSG_SCRIPT)), ls[1]) }) + deep, list := []int{}, []string{} + return m.Cmdx(lex.SPLIT, "", "name,link", kit.Dict(nfs.CAT_CONTENT, text), func(indent int, ls []string) []string { + for len(deep) > 0 && indent <= deep[len(deep)-1] { + deep = deep[:len(deep)-1] + list = list[:len(list)-1] + } + if len(ls) > 1 { + kit.If(!kit.HasPrefix(ls[1], nfs.PS, web.HTTP), func() { + ls[1] = path.Join(kit.Select(path.Dir(m.Option(ice.MSG_SCRIPT)), list, -1), ls[1]) + kit.Select("", nfs.PS, strings.HasSuffix(ls[1], nfs.PS)) + }) + } + deep = append(deep, indent) + list = append(list, kit.Select("", ls, 1)) return ls }) } diff --git a/info.go b/info.go index 3cbe6d8f..47dffcf5 100644 --- a/info.go +++ b/info.go @@ -88,6 +88,9 @@ func MergeActions(arg ...Any) Actions { return nil } list := arg[0].(Actions) + if list == nil { + list = Actions{} + } for _, from := range arg[1:] { switch from := from.(type) { case Actions: diff --git a/meta.go b/meta.go index 46c52f82..e33937c6 100644 --- a/meta.go +++ b/meta.go @@ -145,7 +145,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { m.Add(MSG_APPEND, KEY, key).Add(MSG_APPEND, VALUE, kit.Format(value)) } else { if m.ActionKey() == INPUTS && kit.IndexOf(m.meta[key], v) > -1 { - return + // return } m.Add(MSG_APPEND, key, v) } diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index d8f6681a..475c24c8 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -11,6 +11,7 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/core/wiki" + "shylinux.com/x/icebergs/misc/git" kit "shylinux.com/x/toolkits" ) @@ -22,15 +23,19 @@ const ( type alpha struct { ice.Zone field string `data:"word,phonetic,translation,definition"` - store string `data:"usr/local/export/"` + repos string `data:"https://shylinux.com/x/word-dict"` + store string `data:"usr/local/alpha/"` fsize string `data:"300000"` limit string `data:"50000"` least string `data:"1000"` - load string `name:"load file=usr/word-dict/ecdict zone=ecdict"` + load string `name:"load file*=usr/word-dict/ecdict zone*=ecdict"` list string `name:"list method=word,line word auto load" help:"词典"` } func (s alpha) Load(m *ice.Message, arg ...string) { + if !nfs.Exists(m, path.Dir(m.Option(nfs.FILE))) { + git.ReposClone(m.Message, mdb.Config(m, "repos")) + } lib := kit.Select(path.Base(m.Option(nfs.FILE)), m.Option(mdb.ZONE)) m.Assert(nfs.RemoveAll(m, path.Join(mdb.Config(m, mdb.STORE), lib))) s.Zone.Remove(m, mdb.ZONE, lib) diff --git a/misc/chrome/page.go b/misc/chrome/page.go index 43fdcdb9..61221e09 100644 --- a/misc/chrome/page.go +++ b/misc/chrome/page.go @@ -9,7 +9,7 @@ type page struct { daemon style field - list string `name:"list domain auto" help:"网页" http:"/page"` + list string `name:"list domain auto" help:"网页" http:""` } func (s page) Command(m *ice.Message, arg ...string) { diff --git a/misc/chrome/style.go b/misc/chrome/style.go index 59beea4c..17fcf813 100644 --- a/misc/chrome/style.go +++ b/misc/chrome/style.go @@ -1,7 +1,10 @@ package chrome import ( + "path" + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" ) @@ -26,6 +29,10 @@ func (s style) Command(m *ice.Message, arg ...string) { s.Zone.List(m, m.Option(web.DOMAIN)).Table(func(value ice.Maps) { s.send(m, "1", m.Option(TID), m.CommandKey(), value[SELECTOR], value[PROPERTY]) }) + style := m.Cmdx(nfs.CAT, path.Join("src/website", m.Option(web.DOMAIN), "dark.css")) + if style != "" { + s.send(m, "1", m.Option(TID), m.CommandKey(), "style", style) + } } func (s style) List(m *ice.Message, arg ...string) { s.Zone.List(m, arg...) diff --git a/misc/chrome/sync.go b/misc/chrome/sync.go index ac404a1b..31df8249 100644 --- a/misc/chrome/sync.go +++ b/misc/chrome/sync.go @@ -7,7 +7,7 @@ import ( type sync struct { field string `data:"time,id,type,name,link"` - insert string `name:"insert type name link" http:"/sync"` + insert string `name:"insert type name link" http:"sync"` list string `name:"list id auto" help:"同步流"` } diff --git a/misc/git/repos.go b/misc/git/repos.go index c36608a3..ea6141a8 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -600,3 +600,6 @@ func init() { }) } func ReposList(m *ice.Message) *ice.Message { return m.Cmd(REPOS, ice.OptionFields("repos,path")) } +func ReposClone(m *ice.Message, arg ...string) *ice.Message { + return m.Cmdy("web.code.git.repos", "clone", arg) +}