From 0fea1451635d3f9c3391a1f5bbb920307565f3a3 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Sat, 28 Jan 2023 23:18:02 +0800 Subject: [PATCH] opt panel --- frame.js | 31 +++---- index.css | 6 +- lib/base.js | 3 + lib/core.js | 4 +- lib/misc.js | 27 ++++-- lib/page.js | 3 + lib/user.js | 11 ++- panel/action.css | 5 +- panel/action.js | 72 +++++++-------- panel/footer.css | 9 +- panel/footer.js | 44 ++++----- panel/header.css | 24 ++--- panel/header.js | 177 ++++++++++++++++++------------------ panel/river.js | 4 +- plugin/local/code/inner.css | 3 +- plugin/local/code/inner.js | 1 + plugin/local/wiki/draw.js | 2 +- plugin/state.js | 2 +- proto.js | 2 + 19 files changed, 210 insertions(+), 220 deletions(-) diff --git a/frame.js b/frame.js index 17c17924..5a49257d 100644 --- a/frame.js +++ b/frame.js @@ -1,6 +1,6 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.require([can.volcano], null, function(can, key, sub) { can[key] = sub }) if (!can.user.isMailMaster) { if (can.misc.Search(can, ice.MSG_SESSID)) { can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID)); return can.misc.Search(can, ice.MSG_SESSID, "") } } - can.user.title(can.misc.Search(can, chat.TITLE)||can.misc.Search(can, ice.POD)||location.host) + can.user.title(can.misc.SearchOrConf(can, chat.TITLE)||can.misc.Search(can, ice.POD)||location.host) can.onappend.theme(can, html.DARK), can.onappend.theme(can, html.LIGHT, {panel: cli.WHITE, plugin: cli.ALICEBLUE, legend: "lightsteelblue", input: cli.WHITE, output: cli.WHITE, table: cli.ALICEBLUE, hover: cli.ALICEBLUE, border: cli.TRANSPARENT, label: cli.BLACK, text: cli.BLACK, info: cli.BLUE, warn: cli.RED}) can.run = function(event, cmds, cb) { var msg = can.request(event); cmds = cmds||[]; return (can.onengine[cmds[0]]||can.onengine._remote)(event, can, msg, can, cmds, cb) } @@ -13,7 +13,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.requ }, target) }, function() { can.onlayout._init(can, target), can.onmotion._init(can, target), can.onkeymap._init(can, target) can.onengine.signal(can, chat.ONMAIN, can.request()), can.base.isFunc(cb) && cb(can) - }) + }), can._path = location.href }, _search: function(event, can, msg, panel, cmds, cb) { var sub, mod = can, fun = can, key = ""; can.core.List(cmds[1].split(ice.PT), function(value) { fun && (sub = mod, mod = fun, fun = mod[value], key = value) }) @@ -50,7 +50,9 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.requ n = 3, func = p.meta[cmds[2]], _can = msg._can } else if (p.meta && p.meta[cmds[1]]) { n = 2, func = p.meta[cmds[2]], _can = msg._can - } return can.core.CallFunc(func, {sup: _sup, can: _can, sub: msg._can, msg: msg, arg: cmds.slice(n), cmds: cmds.slice(n), cb: cb}), true + } + if (cmds[n] == ctx.ACTION && cmds[n+1] == mdb.INPUTS) { return true } + return can.core.CallFunc(func, {sup: _sup, can: _can, sub: msg._can, msg: msg, arg: cmds.slice(n), cmds: cmds.slice(n), cb: cb}), true }, plugin: shy(function(can, name, command) { var _name = can.base.trimPrefix(name, "can.") if (can.base.isUndefined(name) || !can.base.isString(name) || name == _name) { return } @@ -188,10 +190,10 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }, _output0: function(can, meta, event, cmds, cb, silent) { var msg = can.request(event); if (msg.RunAction(event, can, cmds)) { return } if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { var msg = can.request(event, {action: cmds[1]}) - var action = meta.feature[cmds[1]]; if (can.base.isFunc(action)) { + var action = meta.feature[cmds[1]]; if (can.base.isFunc(action)) { cb = cb||function() { can.Update() } return action.list && action.list.length > 0? can.user.input(event, can, action.list, function(data) { - can.core.CallFunc(action, {can: can, msg: can.request(event, data), arg: cmds.slice(2)}) - }): can.core.CallFunc(action, {can: can, msg: can.request(event), arg: cmds.slice(2)}) + can.core.CallFunc(action, {can: can, msg: can.request(event, data), arg: cmds.slice(2), cb: cb}) + }): can.core.CallFunc(action, {can: can, msg: can.request(event), arg: cmds.slice(2), cb: cb}) } return can.user.input(event, can, meta.feature[cmds[1]], function(args) { can.Update(can.request(event, {_handle: ice.TRUE}, can.Option()), cmds.slice(0, 2).concat(args), cb) }) } @@ -404,13 +406,11 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { can.runAction(can.request()._caller(), ctx.COMMAND, [meta.index], function(msg) { msg.Table(function(value) { can.onappend._plugin(can, value, meta, _cb, target, field) })}); return res }, _plugin: function(can, value, meta, cb, target, field) { can.base.Copy(meta, value, true) - meta.type = meta.type||chat.STORY, meta.name = meta.name||value.meta&&value.meta.name||"", meta.height = meta.height||can.ConfHeight()-2*html.ACTION_HEIGHT, meta.width = meta.width||can.ConfWidth() + meta.type = meta.type||chat.STORY, meta.name = meta.name||value.meta&&value.meta.name||"", meta.help = meta.help||value.help||"", meta.height = meta.height||can.ConfHeight()-2*html.ACTION_HEIGHT, meta.width = meta.width||can.ConfWidth() meta.inputs = can.base.getValid(meta.inputs, can.base.Obj(value.list))||[], meta.feature = can.base.getValid(meta.feature, can.base.Obj(value.meta))||{} meta.args = can.base.getValid(can.base.Obj(meta.args), can.base.Obj(meta.arg), can.base.Obj(value.args), can.base.Obj(value.arg))||[] can.onappend._init(can, meta, [chat.PLUGIN_STATE_JS], function(sub, skip) { - sub.run = function(event, cmds, cb) { - can.runActionCommand(sub.request(event), sub._index, cmds, cb) - } + sub.run = function(event, cmds, cb) { can.runActionCommand(sub.request(event), sub._index, cmds, cb) } sub._index = value.index||meta.index, can.base.isFunc(cb) && cb(sub, meta, skip) }, target||can._output, field) }, @@ -619,17 +619,10 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { Volcanos(chat.ONKEYMAP, {_init: function(can, target) { target = target||document.body can.onkeymap._build(can), target.onkeydown = function(event) { can.misc.Event(event, can, function(msg) { if (can.page.tagis(event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } - var msg = can.request(event, {"model": "normal"}); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - if (can.user.isWebview && event.metaKey) { msg.Option("model", "webview"); if (event.key >= "0" && event.key <= "9") { - can.onengine.signal(can, chat.ONKEYDOWN, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - } } - can.onengine.signal(can, chat.ONKEYDOWN, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - can._keylist = can.onkeymap._parse(event, can, msg.Option("model"), can._keylist, can._output) + can.onengine.signal(can, chat.ONKEYDOWN, can.request(event, {"model": can.user.isWebview && event.metaKey? "webview": "normal"})) }) }, target.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { if (can.page.tagis(event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } - var msg = can.request(event, {"model": "normal"}); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - can.onengine.signal(can, chat.ONKEYUP, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - can._keylist = can.onkeymap._parse(event, can, msg.Option("model"), can._keylist, can._output) + can.onengine.signal(can, chat.ONKEYUP, can.request(event, {"model": "normal"})) }) } }, _build: function(can) { can.core.Item(can.onkeymap._mode, function(item, value) { var engine = {list: {}} diff --git a/index.css b/index.css index 75325a98..9a903d65 100644 --- a/index.css +++ b/index.css @@ -34,8 +34,6 @@ div.project div.zone>div.list>div.zone>div.item:hover { margin-left:10px; transi div.project div.zone>div.list { min-width:200px; overflow:auto; } div.project div.zone>div.action>div.item { float:right; clear:none; } div.project div.zone>div.action>div.item input[type=text] { margin-right:-10px; } -div.project div.zone>div.action>div.item>span.icon { font-size:18px; margin-left:-5px; visibility:hidden; } -div.project div.zone>div.action>div.item:hover>span.icon { visibility:visible; } table.content thead { position:sticky; top:2px; } table.content th { background-color:steelblue; padding:2px 5px; } table.content td { padding:2px 5px; } @@ -118,7 +116,6 @@ div.action>div.tabs { padding:5px; height:31px; } div.status>div.item { padding:5px; height:30px; } div.status>div.item>label { font-size:0.6rem; } /* display */ -// div.action { display:contents; } form.option.hide, div.action.hide { display:none; } form.option, div.action { display:contents; } form.option.hide, div.action.hide { display:none; } form.option>div.item>label, div.action>div.item>label, .hidden, .hide { display:none; } form.option>div.cmd, form.option>div.textarea { width:100%; } textarea { resize:vertical; } @@ -140,7 +137,7 @@ div.tabs>div.select span.icon { visibility:visible; } div.code { position:sticky; left:0; } div.plug { font-style:italic; } div.item.text { position:relative; } -div.item.text>span.icon.delete { font-size:20px; position:absolute; top:2px; right:10px; visibility:hidden; } +div.item.text>span.icon.delete { font-size:20px; line-height:28px; position:absolute; top:2px; right:10px; visibility:hidden; } div.item.text:hover>span.icon.delete { visibility:visible; } form.option>div.icon { font-size:26px; margin-right:5px; display:none; } form.option>div.icon:hover { background-color:white; } @@ -276,6 +273,7 @@ fieldset.draw.spide div.output div.toggle { display:none; } fieldset.draw.trend div.output div.toggle { display:none; } fieldset.web.code.git.status div.output table.content { width:100%; } fieldset.can.view { font-size:14px; } +fieldset.can.data { font-size:14px; } body.mobile fieldset.plugin>legend { border:none; } /* layout */ table.layout { border-spacing:0; } diff --git a/lib/base.js b/lib/base.js index edccc945..b29281cd 100644 --- a/lib/base.js +++ b/lib/base.js @@ -134,6 +134,9 @@ Volcanos("base", { if (arguments[i] && str.replace) { while (str.indexOf(arguments[i]) > -1) { str = str.replace(arguments[i], arguments[i+1]) } } } return str }, + contains: function(str) { var arg = arguments + for (var i = 1; i < arg.length; i++) { if (!arg[i] || str.indexOf(arg[i]) > -1) { return true } } + }, beginWith: function(str) { for (var i = 1; i < arguments.length; i++) { if (typeof str == lang.STRING && str.trim().indexOf(arguments[i]) == 0) { return true } } }, endWith: function(str) { for (var i = 1; i < arguments.length; i++) { if (typeof str == lang.STRING && str.lastIndexOf(arguments[i]) + arguments[i].length == str.length) { return true } } }, trimPrefix: function(str, pre) { if (typeof str != lang.STRING) { return str } var callee = arguments.callee diff --git a/lib/core.js b/lib/core.js index 03f7b895..2ede56d8 100644 --- a/lib/core.js +++ b/lib/core.js @@ -63,7 +63,9 @@ Volcanos("core", { if (typeof func != lang.FUNCTION) { if (typeof args["cb"] == lang.FUNCTION) { args["cb"]() } return } var list = [], echo = false, cb = args["cb"]; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(ice.FS), function(item, index) { item = item.trim(); if (item == "") { return } list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || null); if (item == "cb") { echo = true } - }); var res = func.apply(mod||can, list); if (!echo && typeof cb == lang.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res + }); var res = func.apply(mod||can, list); + if (msg && msg.Defer) { msg.Defer() } + if (!echo && typeof cb == lang.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res }, List: function(list, cb, interval, cbs) { if (typeof list == lang.STRING) { list = [list] } else if (typeof list == lang.NUMBER) { // [end cb interval]|[begin end interval] diff --git a/lib/misc.js b/lib/misc.js index 3c2117a6..eaa2118b 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -72,6 +72,9 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} msg[key].push(can.base.isString(value)||can.base.isFunc(value)? value: JSON.stringify(value)) return msg }, + PushAction: function(button) { can.core.List(msg.Length(), function() { + msg.Push(ctx.ACTION, can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))) + }); return msg }, Echo: function(res) { msg.result = msg.result||[] for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) } return msg._hand = true, msg @@ -90,6 +93,9 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} msg.Option("log.caller") || msg.Option("log.caller", can.misc._fileLine((skip||2)+1).link) return msg }, + Defer: function(cb) { msg._defer = msg._defer||[] + if (arguments.length == 0) { msg._defer = can.core.List(msg._defer.reverse(), function(cb) { can.base.isFunc(cb) && cb() }) } else { msg._defer.push(cb) } + }, _defer: [], }; return kit.proto(msg, proto) }, concat: function(can, to, from) { to = to||[], from = from||[] @@ -188,7 +194,9 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} for (var i = 0; i < _ls.length; i += 2) { _url[_ls[i]] = _ls[i+1] } return _url }, - SearchOrConf: function(can, key, def) { return can.base.getValid(can.misc.Search(can, key), can.Conf(key), def) }, + SearchOrConf: function(can, key, def) { + return can.misc.Search(can, key)||Volcanos.meta.args[key]||can.misc.localStorage(can, "can."+key)||can.Conf(key)||def + }, SearchHash: function(can) { if (!can.isCmdMode()) { return [] } if (arguments.length > 1) { location.hash = encodeURIComponent(can.core.List(arguments).slice(1).join(ice.FS)) } return can.core.Split(decodeURIComponent(location.hash.slice(1)), ":,")||[] @@ -207,23 +215,22 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} CookieSessid: function(can, value, path) { return can.misc.Cookie(can, ice.MSG_SESSID+"_"+(location.port||(location.protocol == "https:"? "443": "80")), value, path) }, - Cookie: function(can, key, value, path) { - function set(k, v) { document.cookie = k+ice.EQ+v+";path="+(path||ice.PS) } + Cookie: function(can, key, value, path) { function set(k, v) { document.cookie = k+ice.EQ+v+";path="+(path||ice.PS) } if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined } - if (can.base.isUndefined(key)) { var cs = {} - return document.cookie.split("; ").forEach(function(item) { var ls = item.split(ice.EQ); cs[ls[0]] = ls[1] }), cs + if (can.base.isUndefined(key)) { var cs = {}; if (!document.cookie) { return } return document.cookie.split("; ").forEach(function(item) { var ls = item.split(ice.EQ); cs[ls[0]] = ls[1] }), cs } + if (value === "") { var expires = new Date(); expires.setTime(expires.getTime() - 10); + return document.cookie = key+ice.EQ+value+";path="+(path||ice.PS)+";expires=" + expires.toGMTString(); } can.base.isUndefined(value) || set(key, value) var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie) return val && val.length > 1? val[1]: "" }, localStorage: function(can, key, value) { - if (value != undefined) { localStorage.setItem(key, value) } - if (value === "") { localStorage.removeItem(key) } - return localStorage.getItem(key) + if (can.base.isUndefined(key)) { var res = {}; can.core.Item(localStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res } + if (!can.base.isUndefined(value)) { if (value === "") { return localStorage.removeItem(key) } localStorage.setItem(key, value) } return localStorage.getItem(key) }, sessionStorage: function(can, key, value) { - if (value != undefined) { sessionStorage.setItem(key, value) } - return sessionStorage.getItem(key) + if (can.base.isUndefined(key)) { var res = {}; can.core.Item(sessionStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res } + if (!can.base.isUndefined(value)) { if (value === "") { return sessionStorage.removeItem(key) } sessionStorage.setItem(key, value) } return sessionStorage.getItem(key) }, _signal: function(args) { this._list.push(args) diff --git a/lib/page.js b/lib/page.js index 2c3074b8..84e7b237 100644 --- a/lib/page.js +++ b/lib/page.js @@ -188,6 +188,9 @@ Volcanos("page", {ClassList: { case html.A: return ""+(args[2]||args[1])+"" case html.IMG: return args[2]? "": "" case html.SPAN: return args[2]? ""+args[1]+"": args[1] + default: /* type inner arg... */ + var list = ["<"+type]; for (var i = 2; i < args.length; i += 2) { list.push(ice.SP+args[i]+ice.EQ+args[i+1]) } + return list.concat(">", args[1], "").join("") } }, Color: function(text) { if (typeof text != lang.STRING) { return "" } text = text.replace(/\\n/g, "
") if (text.indexOf(ice.HTTP) == 0 && text.length > 10) { var ls = text.split(ice.SP); text = ""+ls[0]+""+ls.slice(1).join(ice.SP) } diff --git a/lib/user.js b/lib/user.js index b618d68f..78178815 100644 --- a/lib/user.js +++ b/lib/user.js @@ -41,7 +41,7 @@ Volcanos("user", {info: {}, agent: { can.Conf(chat.DISPLAY) && name.push(can.Conf(chat.DISPLAY)), can.user.mod.isCmd && name.push(chat.SIMPLE) can.user.language(can) && name.push(can.user.language(can)), can.page.styleClass(can, document.body, name.join(ice.SP)) }, - language: function(can) { return can.misc.Search(can, aaa.LANGUAGE)||can.misc.localStorage(can, "can.language")||can.user.info.language||"zh" }, + language: function(can) { return can.misc.SearchOrConf(can, aaa.LANGUAGE)||can.user.info.language||"zh" }, trans: function(can, text, list) { if (can.user.language(can) == "en") { return text } if (can.base.isObject(text)) { return can.core.Item(text, function(k, v) { can.core.Value(can._trans, k, v) }) } if (can.base.isFunc(text)) { text = text.name||"" } if (can.base.isString(list)) { return list } @@ -101,13 +101,16 @@ Volcanos("user", {info: {}, agent: { meta = meta||can.ondetail||can.onaction||{}, list = can.base.getValid(list, meta.list, can.core.Item(meta)); if (!list || list.length == 0) { return } function click(event, button) { can.misc.Event(event, can, function(msg) { can.onkeymap.prevent(event) meta[button]? meta[button](event, can, button): can.base.isFunc(cb)? cb(event, button, meta, carte): - can.core.CallFunc([can.onaction, button], [event, can, button]) // , can.onmotion.delay(can, function() { carte._sub || can.page.Remove(can, ui._target) }) + can.onaction && can.onaction[button] && can.core.CallFunc([can.onaction, button], [event, can, button]) + // , can.onmotion.delay(can, function() { carte._sub || can.page.Remove(can, ui._target) }) }) } function remove_sub(carte) { carte._sub && can.page.Remove(can, carte._sub._target), delete(carte._sub) } var ui = can.page.Append(can, document.body, [{view: [[chat.CARTE, meta._style||"", chat.FLOAT]], list: can.core.List(list, function(item, index) { return item ==""? /* 0.space */ {type: html.HR}: can.base.isString(item)? /* 1.string */ {view: [html.ITEM, html.DIV, can.user.trans(can, item, trans)], onclick: function(event) { click(event, item) }, onmouseenter: function(event) { remove_sub(carte) } }: - can.base.isArray(item)? /* 2.array */ {view: html.ITEM, list: [{text: can.user.trans(can, item[0], trans)+" >"}], onmouseenter: function(event) { - var sub = can.user.carte(event, can, meta, item.slice(1), cb, carte, trans); can.onlayout.figure(event, can, sub._target, true), remove_sub(carte), carte._sub = sub + can.base.isArray(item)? /* 2.array */ {view: html.ITEM, list: [{text: can.user.trans(can, item[0], trans)+" "+can.page.unicode.gt}], onmouseenter: function(event) { + var sub = can.user.carte(event, can, meta, item.slice(1), cb||function(event, button) { + can.onimport && can.onimport[item[0]] && can.onimport[item[0]](can, button) + }, carte, trans); can.onlayout.figure(event, can, sub._target, true), remove_sub(carte), carte._sub = sub } }: /* 3.object */ item })}]); can.onkeymap.prevent(event), can.page.Select(can, ui._target, html.IMG, function(target) { target.onload = function() { can.onlayout.figure(event, can, ui._target) } }) var carte = {_target: ui._target, _parent: parent, layout: can.onlayout.figure(event, can, ui._target), close: function() { can.page.Remove(can, ui._target) }}; return carte diff --git a/panel/action.css b/panel/action.css index c0f1832a..9c63ddf3 100644 --- a/panel/action.css +++ b/panel/action.css @@ -6,9 +6,10 @@ fieldset.Action>div.action div.tabs:hover { background-color:#6495ed63; } fieldset.Action.tabs>div.action { display:block; } fieldset.Action.tabs>div.output>fieldset>legend { display:none; } fieldset.Action.tabs>div.output>fieldset.plugin:not(.select) { display:none; } -fieldset.Header div.Action>div.tabs { margin-left:20px; float:left; } +fieldset.Header div.Action { display:contents; } +fieldset.Header div.Action>div.tabs:not(.hide) { margin-left:20px; display:contents; float:left; } fieldset.Header div.Action>div.tabs:hover { background-color:none; } -fieldset.Header div.tabs>div.tabs { padding:5px 10px; height:31px; float:left; } +fieldset.Header div.tabs>div.tabs { background-color:unset; padding:5px 10px; height:31px; float:left; } fieldset.Header div.tabs>div.tabs:hover { background-color:#6495ed63; } fieldset.Action.tabview>div.output>fieldset.plugin:not(.select) { display:none; } fieldset.Action.vertical>div.output>fieldset.plugin { float:left; } diff --git a/panel/action.js b/panel/action.js index c4b4da6a..5c3241de 100644 --- a/panel/action.js +++ b/panel/action.js @@ -4,7 +4,6 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) can.onappend.plugin(can, item, function(sub, meta, skip) { sub.run = function(event, cmds, cb) { return can.run(event, can.misc.concat(can, river == web.SHARE? [ctx.ACTION]: [], [river, storm, meta.id||meta.index], cmds), cb) } can._plugins = can.misc.concat(can, can._plugins, [sub]), can.onimport._tabs(can, sub, meta), skip || next() - sub._scrollIntoView = function() { can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN } sub._target.onclick = function(event) { event.target == sub._target && sub._tabs.click() } }) }, function() { can.isCmdMode() || can.onmotion.delay(can, function() { can.onaction.layout(can) }) }) @@ -16,8 +15,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) _tabs: function(can, sub, meta) { var tabs = [{view: [html.TABS, html.DIV, meta.name], onclick: function(event) { can.onmotion.select(can, can._header_tabs, html.DIV_TABS, sub._header_tabs) can.onmotion.select(can, can._action, html.DIV_TABS, sub._tabs), can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, sub._target) - if (sub._delay_refresh) { sub._delay_refresh = false, sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), can.onexport.layout(can) == "") } - if (can.onexport.layout(can)) { return } sub._scrollIntoView() + if (sub._delay_refresh) { sub._delay_refresh = false, sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), can.onexport.isauto(can)) } + can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN }, oncontextmenu: sub._legend.onclick}]; sub._header_tabs = can.page.Append(can, can._header_tabs, tabs)._target, sub._tabs = can.page.Append(can, can._action, tabs)._target }, _menu: function(can, msg) { if (can.user.isMobile) { return } @@ -28,11 +27,10 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) Volcanos(chat.ONACTION, {_init: function(can, target) { can.Conf(html.MARGIN_Y, 4*html.PLUGIN_MARGIN+html.ACTION_MARGIN), can.Conf(html.MARGIN_X, (can.user.isMobile? 2: 4)*html.PLUGIN_MARGIN) can.onengine.listen(can, "ontouchstart", function(msg) { can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }, target) - can.onengine.listen(can, chat.ONSEARCH, function(msg, arg) { arg[0] == ctx.COMMAND && can.run(msg, ["can.command"]) }) }, onsize: function(can, msg, height, width) { can.Conf({height: height-can.Conf(html.MARGIN_Y), width: width-can.Conf(html.MARGIN_X)}) }, onmain: function(can, msg) { can.onimport._share(can, can.misc.Search(can, web.SHARE)) }, - onlogin: function(can, msg) { can.ondaemon._init(can), can.onimport._menu(can, msg) + onlogin: function(can, msg) { can.ondaemon._init(can), can.onimport._menu(can, msg), can.onkeymap._build(can) can._root.River && can.onmotion.delay(can, function() { var gt = can.page.unicode.gt, lt = can.page.unicode.lt, river = can._root.River._target var target = can.page.Append(can, can._target, [{view: [[html.TOGGLE, chat.PROJECT], html.DIV, can.page.isDisplay(river)? lt: gt], onclick: function(event) { can.page.Modify(can, target, (can._river_show = can.onmotion.toggle(can, river))? lt: gt), can.onaction.layout(can) @@ -44,7 +42,7 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { if (msg.Length() == 1) { can.onengine.signal(can, chat.ONACTION_CMD) } can.onimport._init(can, msg) }) }, - onstorm_select: function(can, msg, river, storm) { can.onkeymap._init(can) + onstorm_select: function(can, msg, river, storm) { if (can.onmotion.cache(can, function(cache, old) { var key = can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm)) return cache[old] = can._plugins, can._plugins = cache[key]||[], key }, can._output, can._action, can._header_tabs)) { return can.onaction.layout(can) } @@ -63,10 +61,9 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { can._keylist = can.onkeymap._parse(msg._event, can, model, can._keylist||[], can._output) }, onresize: function(can, height, width) { can.onaction.layout(can), window.setsize && window.setsize(can.page.width(), can.page.height()) }, - onprint: function(can, msg) { can.page.styleHeight(can, can._target, "") }, - layout: function(can, button) { can._layout && can.page.ClassList.del(can, can._target, can._layout), can._header_tabs && can.onmotion.hidden(can, can._header_tabs) - button = (can._layout = button)||can.misc.Search(can, html.LAYOUT)||can.misc.localStorage(can, "can.layout")||can.Conf(html.LAYOUT)||ice.AUTO, button == ice.AUTO? (button = ""): can.page.ClassList.add(can, can._target, button) - can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {"layout": button})), can._root.River && can._river_show === false && can.onmotion.hidden(can, can._root.River._target), can.onlayout._init(can) + layout: function(can, button) { can.page.ClassList.del(can, can._target, can._layout||can.misc.localStorage(can, "can.layout")), can._header_tabs && can.onmotion.hidden(can, can._header_tabs) + button = (can.misc.localStorage(can, "can.layout", can._layout = button == ice.AUTO? "": button))||can.misc.SearchOrConf(can, html.LAYOUT), can.page.ClassList.add(can, can._target, button) + can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {layout: button})), can._root.River && can._river_show === false && can.onmotion.hidden(can, can._root.River._target), can.onlayout._init(can) can.core.List(can._plugins, function(sub) { sub._delay_refresh = false, can.page.ClassList.set(can, sub._target, html.OUTPUT, [TABVIEW, HORIZON, VERTICAL].indexOf(button) > -1) }) var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can) || can.onlayout._plugin(can, button) }, @@ -80,40 +77,35 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { Volcanos(chat.ONLAYOUT, { tabs: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-can.Conf(html.MARGIN_Y)+html.ACTION_MARGIN), can.ConfWidth(width-can.Conf(html.MARGIN_X)) }) can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }) - can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }) - return true + can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }); return true }, tabview: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width) }) - can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }), can.onmotion.toggle(can, can._header_tabs, true), - can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }) - return true + can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }), can.onmotion.toggle(can, can._header_tabs, true) + can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }); return true }, horizon: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width/2) }) }, vertical: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height/2), can.ConfWidth(width) }) }, grid: function(can) { can.getActionSize(function(height, width) { var m = can.user.isMobile? 1: 2, n = 2 - var h = height/n-4*html.PLUGIN_MARGIN-html.ACTION_HEIGHT, w = width/m-can.Conf(html.MARGIN_X); can.ConfHeight(h), can.ConfWidth(w), can.onlayout._plugin(can, GRID) + var h = height/n-4*html.PLUGIN_MARGIN-html.ACTION_HEIGHT, w = width/m-can.Conf(html.MARGIN_X); can.ConfHeight(h), can.ConfWidth(w) + }) }, + free: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-can.Conf(html.MARGIN_Y)), can.ConfWidth(width-can.Conf(html.MARGIN_Y)) + can.core.List(can._plugins, function(sub, index, array) { can.onmotion.move(can, sub._target, {left: (width/array.length/8*5+20)*index, top: (height/array.length/8*5)*index}) }), can.onmotion.toggle(can, can._header_tabs, true) }) }, - free: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-2*can.Conf(html.MARGIN_Y)), can.ConfWidth(width-can.Conf(html.MARGIN_Y)) }) - can.onmotion.toggle(can, can._header_tabs, true), can.core.List(can._plugins, function(sub, index) { can.onmotion.move(can, sub._target, {left: 120*index, top: 80*index}) }) - }, page: function(can) { can.page.styleHeight(can, can._output, ""), can.page.style(can, document.body, kit.Dict(html.OVERFLOW, "")) }, - _plugin: function(can, button) { can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), ["", FLOW, PAGE].indexOf(button) > -1) && can.page.style(can, sub._output, html.MAX_HEIGHT, "") }) }, + _plugin: function(can, button) { can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), can.onexport.isauto(can)) && can.page.style(can, sub._output, html.MAX_HEIGHT, "") }) }, }) Volcanos(chat.ONEXPORT, { size: function(can, msg) { msg.Option(html.LEFT, can._output.offsetLeft), msg.Option(html.TOP, can._output.offsetTop) - msg.Option(html.WIDTH, can._output.offsetWidth), msg.Option(html.HEIGHT, can._output.offsetHeight) - msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X)), msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)) - msg.Option(html.SCROLL, can.user.isMobile? can._target.parentNode.parentNode.scrollTop: can._output.scrollTop) + msg.Option(html.HEIGHT, can._output.offsetHeight), msg.Option(html.WIDTH, can._output.offsetWidth) + msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)), msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X)) }, - layout: function(can) { return can._layout||can.misc.SearchOrConf(can, html.LAYOUT) }, - args: function(can, msg, cb) { can.core.Next(can._plugins, function(sub, next, index, array) { - cb(can.page.SelectArgs(can, sub._option, "", function(target) { return target.value }), sub, next, index, array) - }) }, - plugin: function(can, msg, arg, fields) { can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (meta.index.indexOf(arg[1]) == -1) { return } - var data = {ctx: ice.CAN, cmd: can._name, type: mdb.PLUGIN, name: sub._legend.innerHTML, text: shy("goto", function(event) { sub._scrollIntoView() })} - if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd } else { return } - msg.Push(data, fields) + layout: function(can) { return can._layout||can.misc.SearchOrConf(can, html.LAYOUT)||"" }, + isauto: function(can) { return ["", FLOW, PAGE].indexOf(can.onexport.layout(can)) > -1 }, + args: function(can, msg, cb) { can.core.Next(can._plugins, function(sub, next, index, array) { cb(sub.Option(), sub, next, index, array) }) }, + plugin: function(can, msg, arg, fields) { can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (!can.base.contains(meta.index, arg[1])) { return } + var data = {ctx: ice.CAN, cmd: can._name, type: chat.PLUGIN, name: sub._index, text: shy(sub._legend.innerHTML, function(event) { sub._target.click() })} + if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd } else { return } msg.Push(data, fields) }) }, command: function(can, msg, arg, fields) { var meta = can.onengine.plugin.meta; can.core.Item(arg[1] == ""? meta: meta[arg[1]]? kit.Dict(arg[1], meta[arg[1]]): {}, function(name, command) { msg.Push(kit.Dict(ice.CTX, ice.CAN, ice.CMD, ctx.COMMAND, mdb.TYPE, ice.CAN, mdb.NAME, name||command.name, mdb.TEXT, command.help, @@ -129,14 +121,18 @@ Volcanos(chat.ONENGINE, {_engine: function(event, sup, msg, can, cmds, cb) { }), can.base.isFunc(cb) && cb(msg) } return true }}) Volcanos(chat.ONKEYMAP, { + toggleLayout: function(can, layout) { can.onaction.layout(can, can.onexport.layout(can) == layout? ice.AUTO: layout) }, + toggleTheme: function(can, theme) { can.setHeader(chat.THEME, can.getHeaderTheme() == theme? ice.AUTO: theme) }, _mode: {normal: { j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) }, k: function(event, can, target) { target.scrollBy(0, event.ctrlKey? -300: -30) }, - t: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == TABVIEW? ice.AUTO: TABVIEW, true) }, - h: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == HORIZON? ice.AUTO: HORIZON, true) }, - v: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == VERTICAL? ice.AUTO: VERTICAL, true) }, - b: function(event, can) { can.search(event, ["Header.onaction.black"]) }, - w: function(event, can) { can.search(event, ["Header.onaction.white"]) }, + t: function(event, can) { can.onkeymap.toggleLayout(can, TABVIEW) }, + h: function(event, can) { can.onkeymap.toggleLayout(can, HORIZON) }, + v: function(event, can) { can.onkeymap.toggleLayout(can, VERTICAL) }, + b: function(event, can) { can.onkeymap.toggleTheme(can, cli.BLACK) }, + w: function(event, can) { can.onkeymap.toggleTheme(can, cli.WHITE) }, + l: function(event, can) { can.onkeymap.toggleTheme(can, html.LIGHT) }, + d: function(event, can) { can.onkeymap.toggleTheme(can, html.DARK) }, c: function(event, can) { can.user.toimage(can, can.user.title(), can._target.parentNode, true) }, ":": function(event, can) { can.onengine.signal(can, chat.ONCOMMAND_FOCUS), can.onkeymap.prevent(event) }, " ": function(event, can) { can.onengine.signal(can, chat.ONSEARCH_FOCUS), can.onkeymap.prevent(event) }, @@ -145,8 +141,8 @@ Volcanos(chat.ONKEYMAP, { }}, _engine: {}, }) Volcanos(chat.ONPLUGIN, {_plugin: shy("默认插件", [mdb.NAME, ice.LIST, ice.BACK]), - layout: shy("界面布局", {_init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)) }}, ["layout:select=auto,tabs,tabview,horizon,vertical,flow,free,grid,page", ice.RUN], function(can, msg, arg) { - can.misc.localStorage(can, "can.layout", arg[0] == ice.AUTO? "": arg[0]), can.onaction.layout(can, arg[0]) + layout: shy("界面布局", {_init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)) }}, ["layout:select=auto,tabs,tabview,horizon,vertical,grid,free,flow,page", ice.RUN], function(can, msg, arg) { + can.onaction.layout(can, arg[0]) }), "parse": shy("生成网页", { "show": function(can, msg, arg) { var name = arg[1]||ice.CAN; can.isCmdMode() && can.user.title(name) diff --git a/panel/footer.css b/panel/footer.css index befa8410..566566d7 100644 --- a/panel/footer.css +++ b/panel/footer.css @@ -5,10 +5,11 @@ fieldset.Footer>div.output div.title { float:left; } fieldset.Footer>div.output div.state { font-family:monospace; float:right; } fieldset.Footer>div.output div.state label { font-size:12px; } fieldset.Footer>div.output div.toast { background-color:darkcyan; float:right; } -fieldset.Footer>div.output div.cmd { padding:0; float:left; } -fieldset.Footer>div.output div.cmd:hover input[name=cmd] { width:320px; transition:all 0.5s; } -fieldset.Footer>div.output input[name=cmd] { margin-left:40px; width:120px; transition:all 1s; } -fieldset.Footer>div.output input[name=cmd]:focus { width:320px; transition:all 0.5s; } +fieldset.Footer>div.output div.cmd { padding:0; margin-left:40px; } +fieldset.Footer>div.output div.cmd>span.delete { top:1px; right:5px; } +fieldset.Footer>div.output div.cmd>input[name=cmd] { margin-right:0; width:120px; transition:all 1s; } +fieldset.Footer>div.output div.cmd>input[name=cmd]:focus { width:320px; transition:all 0.5s; } +fieldset.Footer>div.output div.cmd:hover>input[name=cmd] { width:320px; transition:all 0.5s; } .picker { box-shadow:4px 4px 20px 4px #626bd0; } div.view span.keyword { color:#5cadd4; } diff --git a/panel/footer.js b/panel/footer.js index b1605bc9..3d16264f 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -2,28 +2,34 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.ui = {}, can.db = {} can.onimport._title(can, msg, target), can.onimport._state(can, msg, target), can.onimport._toast(can, msg, target), can.onimport._command(can, msg, target) }, - _title: function(can, msg, target) { can.user.isMobile || can.core.List(msg.result, function(item) { can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "联系站长"}]) }) }, - _state: function(can, msg, target) { can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [NTIP, NCMD, NLOG]).reverse(), function(item) { + _title: function(can, msg, target) { can.user.isMobile || can.core.List(can.Conf(chat.TITLE)||msg.result, function(item) { + can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "联系站长"}]) + }) }, + _state: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [NTIP, NCMD, NLOG]).reverse(), function(item) { can.page.Append(can, target, [{view: [chat.STATE, html.DIV, can.Conf(item)], list: [ {text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", html.SPAN, item]}, ], onclick: function(event) { can.onexport[item](can) }}]) }) }, _toast: function(can, msg, target) { can.toast = can.page.Append(can, target, [{view: chat.TOAST, onclick: function(event) { can.onexport[NTIP](can) }}])._target }, - _command: function(can, msg, target) { can.onappend.input(can, {type: html.TEXT, name: ice.CMD, onkeydown: function(event) { can.onkeymap.input(event, can); if (event.key != lang.ENTER) { return } switch (event.target.value) { + _command: function(can, msg, target) { can.onappend.input(can, {type: html.TEXT, name: ice.CMD, onkeydown: function(event) { can.onkeymap.input(event, can) + function close() { can.ui.cli && can.ui.cli.close() } + if (event.key == lang.ESCAPE) { return close() } if (event.key != lang.ENTER) { return } + switch (event.target.value) { case cli.CLEAR: - case cli.CLOSE: can.ui.cli && can.ui.cli.close(); break - default: can.ui.cli && can.ui.cli.close(); var list = can.core.Split(event.target.value, ice.SP) + case cli.CLOSE: close(); break + default: close(); var list = can.core.Split(event.target.value, ice.SP) can.onexport._float(can, "cli", list[0], list.slice(1), function(sub) { can.ui.cli.close = function() { can.page.Remove(can, sub._target), delete(can.ui.cli) } can.getActionSize(function(left) { can.page.style(can, sub._target, html.LEFT, left, html.RIGHT, "") }) }) - } }}, "", target, [chat.TITLE]) }, + } + }}, "", target, [chat.TITLE]) }, _data: function(can, name, item) { can[name] = can[name]||can.request(), can[name].Push(item), can.onimport.count(can, name) }, count: function(can, name) { can.page.Select(can, can._output, can.core.Keys(html.SPAN, name), function(item) { item.innerHTML = can.Conf(name, parseInt(can.Conf(name)||"0")+1+"")+"" }) }, toast: function(can, msg, title, content, fileline, time) { can.onimport._data(can, NTIP, {time: time, fileline: fileline, title: title, content: content}), can.page.Modify(can, can.toast, [time, title, content].join(ice.SP)) }, ncmd: function(can, msg, _follow, _cmds) { can.onimport._data(can, NCMD, {time: can.base.Time(), follow: _follow, cmds: _cmds}), can.onimport.nlog(can, NLOG) }, nlog: function(can, name) { can.onimport.count(can, name) }, }) -Volcanos(chat.ONACTION, {_init: function(can) { if (can.user.isExtension || can.user.mod.isPod) { can.onmotion.hidden(can) } }, +Volcanos(chat.ONACTION, {_init: function(can) { if (can.user.mod.isPod || can.user.isExtension) { can.onmotion.hidden(can) } }, onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, onlogin: function(can, msg) { can.run({}, [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) }, ontoast: function(can, msg) { can.core.CallFunc(can.onimport.toast, {can: can, msg: msg}) }, @@ -43,7 +49,7 @@ Volcanos(chat.ONEXPORT, {height: function(can) { return can._target.offsetHeight Volcanos(chat.ONPLUGIN, { alert: shy("提示", [wiki.CONTENT], function(can, arg) { arg.length > 0 && can.user.alert(arg[0]) }), toast: shy("提示", { - inputs: shy(function(can, sup, msg, arg) { var list = {}; can.core.List(sup[NTIP][arg[0]], function(item) { if (arg.length > 1 && item.indexOf(arg[1]) == -1) { return } + inputs: shy(function(can, sup, msg, arg) { var list = {}; can.core.List(sup[NTIP][arg[0]], function(item) { if (!can.base.contains(item, arg[1])) { return } if (list[item]) { return } list[item] = true; msg.Push(arg[0], item) }) }), create: shy([wiki.CONTENT, wiki.TITLE], function(can, content, title) { can.user.toast(can, content, title) }), @@ -62,7 +68,7 @@ Volcanos(chat.ONPLUGIN, { return {view: [html.ITEM, html.SPAN], list: [{text: ice.SP+can.page.unicode.close+ice.SP}, {text: [(_ls[1] == location.origin? _ls[2].split("?")[0]+ice.DF+_ls[3]: item).split("?")[0], html.SPAN, nfs.PATH], onclick: function(event) { if (can.onexport.record(can, list[1], mdb.LINK, {time: list[0], link: list[1], type: list[2], path: ice.USR_VOLCANOS, file: _ls[2].split("?")[0], line: _ls[3]})) { return } if (vimer) { return can.page.Remove(can, vimer._target), vimer = null } - vimer = can.onappend.plugin(_can, {index: "web.code.inner", args: [ice.USR_VOLCANOS, _ls[2], _ls[3]]}, function(sub) {}, event.target.parentNode) + vimer = can.onappend.plugin(_can, {index: web.CODE_INNER, args: [ice.USR_VOLCANOS, _ls[2], _ls[3]]}, function(sub) {}, event.target.parentNode) }}]} } if (!can.base.isObject(item)) { return {text: (index > 0? ice.SP: "")+item} } return {view: [mdb.DATA, html.SPAN], _init: function(target) { @@ -78,31 +84,17 @@ Volcanos(chat.ONPLUGIN, { ]} })) }]); arg && arg[1] && can.page.Select(can, can._output, html.TR, function(tr) { can.page.ClassList.set(can, tr, html.HIDE, tr.innerText.indexOf(arg[1]) == -1) }) can.onappend._status(can, [ {name: mdb.TIME, value: can.base.Time()}, {name: mdb.COUNT, value: can.page.Select(can, can._output, html.TR+html.NOT_HIDE).length+"x1"}, - ].concat(can.core.List(["onremote", "wss", "info", "warn", "error"], function(item) { return {name: item, value: stat[item]||"0"} }))) + ].concat(can.core.List([chat.ONREMOTE, "wss", log.INFO, log.WARN, log.ERROR], function(item) { return {name: item, value: stat[item]||"0"} }))) }) }), - localStorage: shy("本地存储", [mdb.NAME, mdb.VALUE, ice.LIST, ice.BACK], function(can, msg, arg) { - if (arg.length == 0) { can.core.Item(localStorage, function(name, value) { if (can.base.isFunc(value) || name == "length") { return } - msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) - }); return msg.StatusTimeCount() } if (arg.length > 1) { localStorage.setItem(arg[0], arg[1]) } msg.Echo(localStorage.getItem(arg[0])) - }), - sessionStorage: shy("会话存储", [mdb.NAME, mdb.VALUE, ice.LIST, ice.BACK], function(can, msg, arg) { - if (arg.length == 0) { can.core.Item(sessionStorage, function(name, value) { if (can.base.isFunc(value) || name == "length") { return } - msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) - }); return msg.StatusTimeCount() } if (arg.length > 1) { sessionStorage.setItem(arg[0], arg[1]) } msg.Echo(sessionStorage.getItem(arg[0])) - }), data: shy("网页数据", [mdb.KEY], function(can, msg, arg) { can.onmotion.delay(can, function() { var can = msg._can if (can.Option(mdb.KEY)) { can.page.AppendData(can, can._output, can.Option(mdb.KEY), can.Option(mdb.KEY).split(ice.PT).pop(), can.core.Value(can._root, can.Option(mdb.KEY)), function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click() - } else { - can.page.AppendData(can, can._output, "", can._root._name, can._root, function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click() - } + } else { can.page.AppendData(can, can._output, "", can._root._name, can._root, function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click() } }) }), view: shy("网页标签", [mdb.KEY], function(can, msg, arg) { can.onmotion.delay(can, function() { var can = msg._can - if (can.Option(mdb.KEY)) { - can.page.Append(can, can._output, [can.page.AppendView(can, can.page.SelectOne(can, document.body, can.Option(mdb.KEY))||document.body)]) - } else { + if (can.Option(mdb.KEY)) { can.page.Append(can, can._output, [can.page.AppendView(can, can.page.SelectOne(can, document.body, can.Option(mdb.KEY))||document.body)]) } else { var ui = can.page.Append(can, can._output, [can.page.AppendView(can, document, "html", [ can.page.AppendView(can, document.head, "head"), can.page.AppendView(can, document.body, "body", null, false, function(target) { var list = []; for (var p = target; p && p.tagName && p != document.body; p = p.parentNode) { diff --git a/panel/header.css b/panel/header.css index bcb87749..26d61a56 100644 --- a/panel/header.css +++ b/panel/header.css @@ -1,19 +1,13 @@ -fieldset.Header { font-size:1.1rem; line-height:21px; padding:0 5px; height:31px; overflow:auto; z-index:10; } -fieldset.Header>div.output { overflow:hidden; } -fieldset.Header>div.output div.menu { padding:5px; height:31px; float:left; cursor:pointer; } -fieldset.Header>div.output div.title { padding:5px; height:31px; float:left; cursor:pointer; } -fieldset.Header>div.output div.state { padding:5px; height:31px; float:left; cursor:pointer; } +fieldset.Header>div.output { font-size:1.1rem; line-height:21px; padding:0 5px; height:31px; overflow:hidden; } +fieldset.Header>div.output div { height:31px; float:left; cursor:pointer; } fieldset.Header>div.output div:hover { background-color:#2e515f; } -fieldset.Header>div.output div.title { float:left; } -fieldset.Header>div.output div.state { float:right; } -fieldset.Header>div.output div.state.avatar { padding:0; height:31px; } +fieldset.Header>div.output div.menu { padding:5px; } +fieldset.Header>div.output div.title { padding:5px; } +fieldset.Header>div.output div.state { padding:5px; float:right; } +fieldset.Header>div.output div.state.avatar { padding:0; } fieldset.Header>div.output div.state.avatar>img { height:31px; } -fieldset.Header>div.output div.search.title { padding:5px 0; margin-left:20px; float:left; position:relative; } -fieldset.Header>div.output div.search>input { margin-top:-5px; margin-right:0; height:30px; transition:all 1s; } +fieldset.Header>div.output div.search.title { padding:0; margin-left:20px; } +fieldset.Header>div.output div.search>span.delete { top:1px; right:5px; } +fieldset.Header>div.output div.search>input { margin-right:0; transition:all 1s; } fieldset.Header>div.output div.search>input:focus { width:320px; transition:all 0.5s; } fieldset.Header>div.output div.search:hover>input { width:320px; transition:all 0.5s; } -fieldset.Header>div.output div.search:hover>span.icon { visibility:visible; } -fieldset.Header>div.output div.search>span.icon { font-size:20px; position:absolute; top:5px; right:5px; visibility:hidden; } -fieldset.Header>div.output div.river { margin-right:100px; } -fieldset.Header>div.output div.search { float:left; } - diff --git a/panel/header.js b/panel/header.js index 6b61b6bc..2b516fba 100644 --- a/panel/header.js +++ b/panel/header.js @@ -1,34 +1,17 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { - can.onimport._title(can, msg, target) - can.onimport._state(can, msg, target) - can.onimport._avatar(can, msg, target) - can.onimport._background(can, msg, target) - can.onimport._search(can, msg, target) - // can.onimport._menus(can, msg, target) - var themeMedia = window.matchMedia("(prefers-color-scheme: light)") - can.__theme = themeMedia.matches? html.LIGHT: html.DARK, themeMedia.addListener(function(event) { - can.__theme = event.matches? html.LIGHT: html.DARK - can.onengine.signal(can, "onthemechange", can.request(event, {theme: can.__theme})) - }) - }, - _title: function(can, msg, target) { if (can.user.isMobile) { return } - can.core.List(can.base.getValid(can.Conf(chat.TITLE)||msg.result, ["shylinux.com/x/contexts"]), function(item) { - can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "返回主页", onclick: function(event) { can.onaction.title(event, can) }}]) - }) - }, - _state: function(can, msg, target) { if (can.user.isMobile) { return } - can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [aaa.USERNICK, aaa.AVATAR, mdb.TIME]).reverse(), function(item) { - // can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [aaa.AVATAR, aaa.USERNICK, mdb.TIME]).reverse(), function(item) { - if (item == aaa.AVATAR ) { if (can.user.isLocalFile) { return } - can.page.Append(can, target, [{view: can.base.join([chat.STATE, item]), list: [{img: ice.SP}], onclick: function(event) { - can.onaction.carte(event, can, [can.page.Format(html.IMG, can.onexport.avatar(can), 160)]) - }}]); return - } - can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, (can.Conf(item)||msg.Option(item)||"").split("@")[0].slice(0, 10)], onclick: function(event) { - can.core.CallFunc([can.onaction, item], [event, can, item]) - }, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) }}]) - }) + can.onimport._title(can, msg, target), can.onimport._state(can, msg, target), can.onimport._avatar(can, msg, target), can.onimport._background(can, msg, target), can.onimport._search(can, msg, target) }, + _title: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.getValid(can.Conf(chat.TITLE)||msg.result, ["shylinux.com/x/contexts"]), function(item) { + can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "返回主页", onclick: function(event) { can.onaction.title(event, can) }}]) + }) }, + _state: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [aaa.USERNICK, aaa.AVATAR, mdb.TIME]).reverse(), function(item) { + if (item == aaa.AVATAR ) { can.user.isLocalFile || can.page.Append(can, target, [{view: [[chat.STATE, item]], list: [{img: ice.SP}], onclick: function(event) { + can.onaction.carte(event, can, [can.page.Format(html.IMG, can.onexport.avatar(can), 160)]) + }}]); return } + can.page.Append(can, target, [{view: [[chat.STATE, item], html.DIV, (can.Conf(item)||msg.Option(item)||"").split(ice.AT)[0].slice(0, 10)], onclick: function(event) { + can.core.CallFunc([can.onaction, item], [event, can, item]) + }, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) }}]) + }) }, _avatar: function(can, msg) { can.user.isExtension || can.user.isLocalFile || can.page.Modify(can, "div.state.avatar>img", {src: can.onexport.avatar(can)}) }, _background: function(can, msg) { can.user.isExtension || can.user.isLocalFile || can.onlayout.background(can, can.onexport.background(can)) }, _search: function(can, msg, target) { @@ -37,116 +20,128 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { }}, "", target, [chat.TITLE]) can.user.isMobile || can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) }) }, - _menus: function(can, msg, target) { if (can.user.mod.isPod || can.user.isMobile) { return } - can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.onaction._menus), function(event, button) { - can.core.CallFunc(can.onaction[button]||function(event, can) { can.runAction(event, button, [], function(msg) { can.user.toastSuccess(can, button) }) }, {event: event, can: can, button: button}) - }) - }, - _time: function(can, target) { can.core.Timer({interval: 100}, function() { can.onimport.time(can, target) }) - can.onappend.figure(can, {action: "date"}, target) - }, + _time: function(can, target) { can.core.Timer({interval: 100}, function() { can.onimport.time(can, target) }), can.onappend.figure(can, {action: "date"}, target) }, time: function(can, target) { can.onimport.theme(can), target.innerHTML = can.user.time(can, null, "%w %H:%M:%S") }, - avatar: function(event, can, avatar) { if (can.user.isExtension || can.user.isLocalFile) { return } - can.runAction(event, aaa.AVATAR, [avatar], function(msg) { can.user.info.avatar = avatar, can.onimport._avatar(can, msg), can.user.toastSuccess(can) }) - }, - background: function(event, can, background) { if (can.user.isExtension || can.user.isLocalFile) { return } - can.runAction(event, aaa.BACKGROUND, [background], function(msg) { can.user.info.background = background, can.onimport._background(can, msg), can.user.toastSuccess(can) }) - }, - theme: function(can, theme) { theme && (can._theme = can.base.Obj(theme).join(ice.SP)), can.user.theme(can, can.onexport.theme(can)) }, + avatar: function(event, can, avatar) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.AVATAR, [avatar], function(msg) { + can.user.info.avatar = avatar, can.onimport._avatar(can, msg), can.user.toastSuccess(can) + }) }, + background: function(event, can, background) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.BACKGROUND, [background], function(msg) { + can.user.info.background = background, can.onimport._background(can, msg), can.user.toastSuccess(can) + }) }, + language: function(can, language) { can.runAction(event, aaa.LANGUAGE, [language], function(msg) { can.user.reload() }) }, + theme: function(can, theme) { theme && (can.misc.localStorage(can, "can.theme", can._theme = theme == ice.AUTO? "": can.base.Obj(theme).join(ice.SP))), can.user.theme(can, can.onexport.theme(can)) }, menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds]) return can.page.Append(can, can._output, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) { if (can.base.isString(item)) { return {view: [html.MENU, html.DIV, can.user.trans(can, item, trans)], onclick: function(event) { can.base.isFunc(cb) && cb(event, item, [item]) }} } - if (can.base.isArray(item)) { - return {view: [html.MENU, html.DIV, can.user.trans(can, item[0], trans)], onmouseenter: function(event) { - can.onaction.carte(event, can, item.slice(1), function(event, button, meta, index) { can.base.isFunc(cb) && cb(event, button, item) }, trans) - }} - } if (can.base.isObject(item)) { return item } + if (can.base.isArray(item)) { return {view: [html.MENU, html.DIV, can.user.trans(can, item[0], trans)], onclick: function(event) { can.onkeymap.prevent(event) }, onmouseenter: function(event) { + can.onaction.carte(event, can, item.slice(1), function(event, button, meta) { can.base.isFunc(cb) && cb(event, button, item) }, trans) + }} } if (can.base.isObject(item)) { return item } }) }])._target }, }) -Volcanos(chat.ONACTION, { - _menus: [["setting", chat.BLACK, chat.WHITE, chat.PRINT, code.WEBPACK, web.TOIMAGE]], - _trans: kit.Dict( - "setting", "设置", chat.BLACK, "黑色主题", chat.WHITE, "白色主题", chat.PRINT, "打印主题", code.WEBPACK, "打包页面", web.TOIMAGE, "生成图片", - "shareuser", "共享用户", "setnick", "设置昵称", aaa.PASSWORD, "修改密码", aaa.LANGUAGE, "语言地区", aaa.CHINESE, "中文", web.CLEAR, "清除背景", aaa.LOGOUT, "退出登录", - ), - onsize: function(can) { can.onimport.theme(can), can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, - onmain: function(can) { can.onimport.theme(can) +Volcanos(chat.ONACTION, {_init: function(can) { var themeMedia = window.matchMedia("(prefers-color-scheme: light)") + can.__theme = themeMedia.matches? html.LIGHT: html.DARK, themeMedia.addListener(function(event) { can.__theme = event.matches? html.LIGHT: html.DARK + can.onengine.signal(can, chat.ONTHEMECHANGE, can.request(event, {theme: can.__theme})) + }), can.onimport.theme(can) + }, + onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, + onmain: function(can) { can.run({}, [], function(msg) { if (!can.Conf(aaa.USERNICK, msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME))) { return msg.Option(chat.SSO)? can.user.jumps(msg.Option(chat.SSO)): can.user.login(can, function() { can.onengine.signal(can, chat.ONMAIN, msg) }, msg.Option(aaa.LOGIN)) - } can.user.info.usernick = can.Conf(aaa.USERNICK), can.user.info.language = can.misc.Search(can, aaa.LANGUAGE)||msg.Option(aaa.LANGUAGE) - can.user.info.background = msg.Option(aaa.BACKGROUND), can.user.info.avatar = msg.Option(aaa.AVATAR) - msg.Option(nfs.SCRIPT) && can.require(can.base.Obj(msg.Option(nfs.SCRIPT)), function(can) { can.onaction.source(can, msg) }) + } can.user.info.usernick = can.Conf(aaa.USERNICK), can.user.info.avatar = msg.Option(aaa.AVATAR), can.user.info.background = msg.Option(aaa.BACKGROUND) + can.user.info.language = msg.SearchOrOption(aaa.LANGUAGE), msg.Option(nfs.SCRIPT) && can.require(can.base.Obj(msg.Option(nfs.SCRIPT)), function(can) { can.onaction.source(can, msg) }) can.onmotion.clear(can), can.onimport._init(can, msg, can._output), can.onengine.signal(can, chat.ONLOGIN, msg) }) }, - onstorm_select: function(can, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) }, onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, onsearch_focus: function(can) { can._search && can._search.focus() }, onshare: function(can, msg, args) { can.user.share(can, msg, [ctx.ACTION, chat.SHARE].concat(args||[])) }, onwebpack: function(can, msg) { can.user.input(msg._event, can, [{name: mdb.NAME, value: can.user.title()}], function(data) { - can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ice.MSG_SESSID, ""], function(key) { delete(msg[key]) }) }) - can.runAction(can.request({}, {args: "name,river,storm,theme,layout", _toast: "打包中...", - name: data.name, content: JSON.stringify(Volcanos.meta.pack), river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), theme: can._theme, layout: can.getAction(html.LAYOUT), + can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ""], function(key) { delete(msg[key]) }) }) + can.runAction(can.request({}, {args: "name,river,storm,title,theme,layout", _toast: "打包中...", content: JSON.stringify(Volcanos.meta.pack), + name: data.name, river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), theme: can._theme, title: can.user.title(), layout: can.getAction(html.LAYOUT), }), code.WEBPACK, [], function(msg) { can.user.download(can, web.SHARE_LOCAL+msg.Result(), name, nfs.HTML), can.user.toastSuccess(can, "打包成功", code.WEBPACK) }) }) }, - title: function(event, can) { var args = {}; can.core.List([chat.TITLE, chat.THEME], function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) }); can.user.jumps(can.misc.MergeURL(can, args, true)) }, - black: function(event, can, button) { can.onimport.theme(can, button) }, - white: function(event, can, button) { can.onimport.theme(can, button) }, - print: function(event, can, button) { can.onimport.theme(can, [chat.WHITE, button]), can.onengine.signal(can, chat.ONPRINT) }, - webpack: function(event, can) { can.onengine.signal(can, "onwebpack", can.request(event)) }, - toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) }, - + title: function(event, can) { var args = {}; can.core.List(can.onaction._params, function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) }); can.user.jumps(can.misc.MergeURL(can, args, true)) }, carte: function(event, can, list, cb, trans) { can.user.carte(event, can, can.onaction, list, cb, null, trans) }, share: function(event, can, args) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(args||[])) }, - - usernick: function(event, can) { if (can.user.mod.isPod || can.user.isExtension || can.user.isLocalFile) { return } - can.onaction.carte(event, can, ["shareuser", "setnick", aaa.PASSWORD, [aaa.LANGUAGE, aaa.CHINESE, aaa.ENGLISH], cli.CLEAR, aaa.LOGOUT]) - }, + usernick: function(event, can) { can.user.mod.isPod || can.user.isExtension || can.user.isLocalFile || can.onaction.carte(event, can, can.onaction._menus) }, shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN]) }, + toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) }, + webpack: function(event, can) { can.onengine.signal(can, chat.ONWEBPACK) }, setnick: function(event, can) { can.user.input(event, can, [{name: aaa.USERNICK, value: can.Conf(aaa.USERNICK)}], function(list) { can.runAction(event, aaa.USERNICK, [list[0]], function(msg) { can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.USERNICK), function(item) { can.page.Modify(can, item, can.Conf(aaa.USERNICK, list[0])) }), can.user.toastSuccess(can) }) }) }, password: function(event, can) { var ui = can.user.input(event, can, [{name: html.PASSWORD, type: html.PASSWORD, action: ice.AUTO}, {name: html.PASSWORD, type: html.PASSWORD, action: ice.AUTO}], function(list) { if (list[0] != list[1]) { return can.user.toast(can, "密码不一致"), ui.focus(), true } can.runAction(event, aaa.PASSWORD, [list[0]], function() { can.user.toastSuccess(can) }) }) }, - chinese: function(event, can) { can.runAction(event, aaa.LANGUAGE, ["zh"], function(msg) { can.user.reload() }) }, - english: function(event, can) { can.runAction(event, aaa.LANGUAGE, ["en"], function(msg) { can.user.reload() }) }, clear: function(event, can) { can.onimport.background(event, can, ""), can.onimport.avatar(event, can, "") }, logout: function(event, can) { can.user.logout(can) }, + + _params: [chat.TITLE, chat.THEME], + _menus: ["shareuser", + [chat.THEME, ice.AUTO, html.DARK, html.LIGHT, "print", cli.WHITE, cli.BLACK], + [aaa.LANGUAGE, "zh", "en"], + [nfs.SAVE, web.TOIMAGE, code.WEBPACK], + [aaa.USER, "setnick", aaa.PASSWORD, cli.CLEAR, aaa.LOGOUT], + ], + _trans: kit.Dict( + "shareuser", "共享用户", chat.THEME, "界面主题", aaa.LANGUAGE, "语言地区", nfs.SAVE, "保存网页", web.TOIMAGE, "生成图片", code.WEBPACK, "打包页面", + aaa.USER, "用户信息", "setnick", "设置昵称", aaa.PASSWORD, "修改密码", web.CLEAR, "清除背景", aaa.LOGOUT, "退出登录", + ), }) Volcanos(chat.ONEXPORT, {height: function(can) { return can._target.offsetHeight }, - theme: function(can) { - return can._theme || can.misc.Search(can, chat.THEME) || can.misc.localStorage(can, "can.theme") || can.__theme || (can.base.isNight()? "dark": "light") - }, - background: function(can) { return can.user.info.background == "void"? "": can.user.info.background }, avatar: function(can) { return can.user.info.avatar == "void"? "": can.user.info.avatar }, + background: function(can) { return can.user.info.background == "void"? "": can.user.info.background }, + theme: function(can) { return can._theme || can.misc.SearchOrConf(can, chat.THEME) || can.__theme || (can.base.isNight()? html.DARK: html.LIGHT) }, }) Volcanos(chat.ONPLUGIN, { - title: shy("应用标题", [chat.TITLE], function(can, msg, arg) { msg.Echo(can.user.title(arg[0])) }), - theme: shy("界面主题", {_init: function(can) { can.Option(chat.THEME, can.getHeader(chat.THEME)) }}, ["theme:select=auto,dark,light,white,black,print", ice.RUN], function(can, msg, arg) { - if (arg[0] == "auto") { arg[0] = "", can._theme = "" } can.misc.localStorage(can, "can.theme", arg[0]), can.onimport.theme(can, arg[0]) + cookie: shy("会话参数", { + create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.Cookie(can, name, value) }), + remove: shy(function(can, name) { name && can.misc.Cookie(can, name, "") }), + modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.Cookie(can, msg.Option(mdb.NAME), arg[1]) } else { + can.misc.Cookie(can, arg[1], msg.Option(mdb.VALUE)), can.misc.Cookie(can, msg.Option(mdb.NAME), "") + } }), + }, [html.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) + can.core.Item(can.misc.Cookie(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) }) + }), + localStorage: shy("本地存储", { + create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.localStorage(can, name, value) }), + remove: shy(function(can, name) { name && can.misc.localStorage(can, name, "") }), + modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.localStorage(can, msg.Option(mdb.NAME), arg[1]) } else { + can.misc.localStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.localStorage(can, msg.Option(mdb.NAME), "") + } }), + }, [html.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) + can.core.Item(can.misc.localStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) }) + }), + sessionStorage: shy("会话存储", { + create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.sessionStorage(can, name, value) }), + remove: shy(function(can, name) { name && can.misc.sessionStorage(can, name, "") }), + modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.sessionStorage(can, msg.Option(mdb.NAME), arg[1]) } else { + can.misc.sessionStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.sessionStorage(can, msg.Option(mdb.NAME), "") + } }), + }, [html.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) + can.core.Item(can.misc.sessionStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) }) }), location: shy("请求地址", {copy: function(can) { can.user.copy(msg._event, can, location.href) }}, [mdb.LINK, ice.LIST, ice.COPY], function(can, msg, cb) { can.runAction(can.request({}, kit.Dict(mdb.LINK, location.href)), web.SHARE, [], function(res) { msg.Echo(res.Append(mdb.TEXT)).Status(kit.Dict(mdb.LINK, res.Append(mdb.NAME))), can.base.isFunc(cb) && cb(msg) }) }), - cookie: shy("请求参数", [mdb.NAME, mdb.VALUE, ice.LIST, ice.BACK], function(can, msg, arg) { arg.length > 1 && can.misc.Cookie(can, arg[0], arg[1]) - can.core.Item(can.misc.Cookie(can), function(key, value) { if (!key || !value || arg[0] && key != arg[0]) { return } - msg.Push(mdb.NAME, key), msg.Push(mdb.VALUE, value) - }), msg.StatusTimeCount() - }), avatar: shy("用户头像", [mdb.LINK], function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.avatar, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }), background: shy("背景图片", [mdb.LINK], function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.background, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }), - language: shy("语言地区", {_init: function(can) { can.Option(aaa.LANGUAGE, can.user.info.language) }}, ["language:select=auto,zh,en", ice.RUN], function(can, msg, arg) { - if (arg[0] == ice.AUTO) { arg[0] = "" } can.misc.localStorage(can, "can.language", arg[0]), can.runAction(event, aaa.LANGUAGE, [arg[0]], function(msg) { can.user.reload() }) + language: shy("语言地区", {_init: function(can) { can.Option(aaa.LANGUAGE, can.user.info.language||ice.AUTO) }}, ["language:select=auto,zh,en", ice.RUN], function(can, msg, arg) { + if (arg[0] == ice.AUTO) { arg[0] = "" } can.runAction(event, aaa.LANGUAGE, [arg[0]], function(msg) { can.user.reload() }) + }), + title: shy("网页标题", [chat.TITLE], function(can, msg, arg) { msg.Echo(can.user.title(arg[0])) }), + theme: shy("界面主题", {_init: function(can) { can.Option(chat.THEME, can.getHeader(chat.THEME)) }}, ["theme:select=auto,dark,light,print,white,black", ice.RUN], function(can, msg, arg) { + if (arg[0] == ice.AUTO) { arg[0] = "", can._theme = "" } can.misc.localStorage(can, "can.theme", arg[0]), can.onimport.theme(can, arg[0]) }), logout: shy("退出登录", kit.Dict(aaa.LOGOUT, shy("退出", function(can) { can.user.logout(can._root.Header, true) })), [aaa.LOGOUT]), }) diff --git a/panel/river.js b/panel/river.js index ab155edc..804843e5 100644 --- a/panel/river.js +++ b/panel/river.js @@ -3,8 +3,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var select; can.page.Append })), select && select.click() }, _main: function(can, msg) { can.river_list = {}, can.storm_list = {}, can.sublist = {} var ls = []; can.user.isExtension && (ls = (can.misc.localStorage(can, "main")||"").split(",")) - can._main_river = can.misc.Search(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||Volcanos.meta.args.river||can._main_river||ls[0]||"project" - can._main_storm = can.misc.Search(can, chat.STORM)||msg.Option(ice.MSG_STORM)||Volcanos.meta.args.storm||can._main_storm||ls[1]||"studio" + can._main_river = ls[0]||can.misc.SearchOrConf(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||can._main_river||"project" + can._main_storm = ls[1]||can.misc.SearchOrConf(can, chat.STORM)||msg.Option(ice.MSG_STORM)||can._main_storm||"studio" }, _menu: function(can, msg) { if (can.user.mod.isPod) { return } return can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.ondetail._menus), function(event, button) { diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index 32cd1c71..0e77481b 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -15,6 +15,7 @@ fieldset.inner>div.output>div.project * { font-size:14px; font-family:monospace; fieldset.inner>div.output>div.project>div.zone>div.item span.icon { font-size:22px; line-height:18px; width:20px; float:right; display:none; } fieldset.inner>div.output>div.project>div.zone:hover>div.item span.icon { display:block; } fieldset.inner>div.output>div.project>div.zone div.action>div.item { padding-right:0; width:100%; } +fieldset.inner>div.output>div.project>div.zone div.action>div.item>span.delete { top:3px; right:5px; } fieldset.inner>div.output>div.project>div.zone div.action>div.item>input { width:100%; } fieldset.inner>div.output>div.project>div.zone fieldset.plug { position:static; } fieldset.inner>div.output>div.layout.flow { position:relative; } @@ -73,8 +74,6 @@ body.mobile fieldset.inner>form.option input[name=file] { width:90px; } body.mobile fieldset.word fieldset.inner>form.option input[type=text] { display:none; } div.carte.history.float * { tab-size:2; } -div.vimer.find.float div.item>span.icon { margin-left:-20px; margin-right:10px; visibility:hidden; } -div.vimer.find.float div.item:hover>span.icon { visibility:visible; } div.vimer.open.float td:first-child { display:none; } div.path span.item { padding:5px; cursor:pointer; } div.carte.path.float { font-size:14px; border-radius:0; } div.carte.path.float div.item { padding:5px; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 40b89b39..8d1daa07 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -284,6 +284,7 @@ Volcanos(chat.ONSYNTAX, {_init: function(can, msg, cb) { src: can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)}), height: can.ui.content.offsetHeight, width: can.ui.content.offsetWidth}], can.ui._content)) } var index = msg.Option(ctx.INDEX).split(ice.FS), meta = {type: chat.STORY, index: index[0], args: index.slice(1)} return can.onimport.plug(can, meta, function(sub) { + sub.onimport.size(sub, can.ui.content.offsetHeight, can.ui.content.offsetWidth, true) sub.onimport._open = function(sub, msg, arg) { var url = can.base.ParseURL(arg), ls = url.origin.split("/chat/pod/") arg.indexOf(location.origin) == 0 && ls.length > 1? can.onimport.tabview(can, can.Option(nfs.PATH), ls[1].split(ice.PS)[0], web.DREAM): can.user.open(arg), sub.Update() } diff --git a/plugin/local/wiki/draw.js b/plugin/local/wiki/draw.js index 0e3ab1c1..9cb974d1 100644 --- a/plugin/local/wiki/draw.js +++ b/plugin/local/wiki/draw.js @@ -3,7 +3,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( can.core.Item(kit.Dict(svg.GRID, 10, svg.FONT_SIZE, 24, svg.FONT_FAMILY, svg.MONOSPACE, svg.STROKE_WIDTH, 2, svg.STROKE, cli.YELLOW, svg.FILL, cli.PURPLE, svg.GO, can.isCmdMode()? ice.AUTO: ice.RUN, svg.SHAPE, svg.RECT), function(key, value) { can.Action(key, can.svg.Value(key, can.svg.Value(key)||value)) }) can.ondetail._select(can, can.misc.SearchHash(can)[0]||can.Option(svg.PID)||can.svg.Value(svg.PID), function(target) { can.onimport._profile(can, target), can.onmotion.toggle(can, can.ui.profile) }) - }), can.isCmdMode()? (can.keylist = [], can.onkeymap._init(can)): can.onmotion.hidden(can, can._action) + }), can.isCmdMode()? (can.keylist = [], can.onkeymap._build(can)): can.onmotion.hidden(can, can._action) }, _show: function(can, msg) { can.svg = null, can.group = null, can.temp = null, can.current = null, can.points = [], can._display_heights = {} can.ui = can.onlayout.profile(can), can.page.Modify(can, can.ui.content, msg.Results()||can.onexport.content(can)), can.onmotion.hidden(can, [can.ui.project, can.ui.profile]) diff --git a/plugin/state.js b/plugin/state.js index 49906429..68395655 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -104,7 +104,7 @@ Volcanos(chat.ONACTION, {list: [ }) }, "远程控制": function(event, can) { can.onaction.keyboard(event, can) }, "共享工具": function(event, can) { var meta = can.Conf() - can.onmotion.share(event, can, [{name: chat.TITLE, value: meta.name}, {name: chat.THEME, values: [can.getHeader(chat.THEME), "light", "dark", cli.WHITE, cli.BLACK]}], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) + can.onmotion.share(event, can, [{name: chat.TITLE, value: meta.name}, {name: chat.THEME, values: [can.getHeader(chat.THEME), html.DARK, html.LIGHT, cli.WHITE, cli.BLACK]}], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) }, "打开链接": function(event, can) { can.user.open(can.onexport.link(can)) }, "生成链接": function(event, can) { can.onmotion.share(event, can, [], [mdb.LINK, can.user.copy(event, can, can.onexport.link(can))]) }, diff --git a/proto.js b/proto.js index 74b739d1..c4becc66 100644 --- a/proto.js +++ b/proto.js @@ -84,6 +84,7 @@ var web = { } var aaa = { LOGIN: "login", LOGOUT: "logout", INVITE: "invite", TOKEN: "token", + USER: "user", PASSWORD: "password", USERNAME: "username", USERNICK: "usernick", BACKGROUND: "background", AVATAR: "avatar", LANGUAGE: "language", ENGLISH: "english", CHINESE: "chinese", VOID: "void", TECH: "tech", @@ -177,6 +178,7 @@ var chat = { ONOPENSEARCH: "onopensearch", ONSEARCH_FOCUS: "onsearch_focus", ONCOMMAND_FOCUS: "oncommand_focus", ONTHEMECHANGE: "onthemechange", ONLAYOUT: "onlayout", + ONWEBPACK: "onwebpack", ONTOAST: "ontoast", ONDEBUG: "ondebug", ONSHARE: "onshare", ONPRINT: "onprint", _INIT: "_init", _TRANS: "_trans", _STYLE: "_style", _ENGINE: "_engine", _SEARCH: "_search", _OUTPUTS_CURRENT: "_outputs.-1", _NAMES: "_names", _TOAST: "_toast",