diff --git a/frame.js b/frame.js index 7939fc01..1f41f099 100644 --- a/frame.js +++ b/frame.js @@ -256,6 +256,11 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { {type: html.SELECT, style: [INPUT_STYLE]}, {type: html.SELECT, style: [INPUT_HOVER_STYLE]}, {type: html.INPUT, style: [INPUT_STYLE]}, {type: html.INPUT, style: [INPUT_HOVER_STYLE]}, {type: html.INPUT+":not([type=button])", style: _b_r(0)}, {type: html.INPUT+":not([type=button])", name: [html.HOVER], style: {border: color.info+SOLID}}, + {type: html.INPUT+":not([type=button]):focus", style: {border: color.info+SOLID}}, + {type: html.INPUT+".select:focus", style: {border: color.info+SOLID}}, + {type: html.INPUT+".select:hover", style: {border: color.info+SOLID}}, + {type: html.TEXTAREA+":focus", style: {border: color.info+SOLID}}, + {type: html.TEXTAREA+":hover", style: {border: color.info+SOLID}}, {type: html.TEXTAREA, style: [INPUT_STYLE]}, {type: html.TEXTAREA, style: _b_r(0)}, {type: html.FORM_OPTION, list: [{type: html.DIV_ITEM, name: [html.SELECT], style: [GLASS_STYLE]}]}, {type: html.FORM_OPTION, list: [{type: html.DIV_ITEM, name: [html.HOVER], style: [GLASS_STYLE]}]}, @@ -331,6 +336,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { if (item.range) { input._init = function(target) { can.onappend.figure(can, item, target, function(sub, value, old) { target.value = value, can.core.CallFunc([can.onaction, item.name], [event, can, item.name]) }) } } + /* if (item.type == html.SELECT) { var ui = can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.name].concat(style)], list: [input].concat([{type: html.INPUT, value: _item.value||_item.values[0], data: {type: html.BUTTON}, onclick: function(event) { var target = event.target var carte = can.user.carte(event, can, {}, _item.values, function(event, button) { target.value = button, ui.select.value = button, ui.select.onchange({target: ui.select}) }) @@ -339,7 +345,19 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { target.value = ui.select.value, can.page.style(can, target, html.WIDTH, ui.select.offsetWidth+10), can.onappend.style(can, html.HIDE, ui.select) }) }}, {text: ["\u25BF", html.SPAN, html.ICON]}]) }]); return ui[item.name] } - var _input = can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.name].concat(style)], list: [input].concat(icon)}])[item.name]; return _input + */ + var _input = can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.name].concat(style)], list: [input].concat(icon), _init: function(target, _input) { + item.type == html.SELECT && can.onappend.select(can, _input.select, _item) + }}])[item.name]; return _input + }, + select: function(can, select, item) { + return can.page.Append(can, select.parentNode, [{view: [html.SELECT, html.INPUT], value: item.value||item.values[0], data: {type: html.BUTTON}, onclick: function(event) { var target = event.target + var carte = can.user.carte(event, can, {}, item.values, function(event, button) { if (target.value == button) { return } + target.value = button, select.value = button, select.onchange && select.onchange({target: select}) }) + can.onappend.style(can, [html.SELECT, item.name], carte._target), can.page.style(can, carte._target, html.MIN_WIDTH, event.target.offsetWidth) + }, _init: function(target) { can.onmotion.delay(can, function() { + target.value = select.value, can.page.style(can, target, html.WIDTH, select.offsetWidth+10), can.onappend.style(can, html.HIDE, select) + }) }}, {text: ["\u25BF", html.SPAN, html.ICON]}]) }, table: function(can, msg, cb, target, keys) { if (!msg || msg.Length() == 0) { return } var meta = can.base.Obj(msg.Option(mdb.META)) var table = can.page.AppendTable(can, msg, target||can._output, msg.append, cb||function(value, key, index, line, array) { @@ -448,6 +466,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { sub.hidden = function() { return !can.page.isDisplay(sub._target) }, sub.close = function() { can.page.Remove(can, sub._target), delete(target._can) } meta.mode && can.onappend.style(sub, meta.mode), can.page.style(sub, sub._target, meta.style) can.base.isFunc(meta._init) && meta._init(sub, sub._target), show(sub, cb) + sub._target._close = sub.close }, can._root._target) }}) }) } }), can.onfigure[input]._init && can.onfigure[input]._init(can, meta, target, _cb) @@ -530,7 +549,11 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { scrollHold: function(can, cb, target) { target = target || can._output var top = target.scrollTop, left = target.scrollLeft; cb(), target.scrollTop = top, target.scrollLeft = left }, - clearFloat: function(can) { can.page.SelectChild(can, document.body, "div.float", function(target) { can.page.Remove(can, target) }) }, + clearFloat: function(can) { + var list = ["fieldset.input.float", "div.input.float", "div.carte.float"]; for (var i = 0; i < list.length; i++) { + if (can.page.Select(can, document.body, list[i], function(target) { return target._close? target._close(): can.page.Remove(can, target) }).length > 0) { return true } + } + }, clearCarte: function(can) { can.page.SelectChild(can, document.body, "div.carte.float", function(target) { can.page.Remove(can, target) }) }, clearInput: function(can) { can.page.SelectChild(can, document.body, "div.input.float", function(target) { can.page.Remove(can, target) }) }, hidden: function(can, target, show) { target = target||can._target @@ -580,7 +603,11 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { can.page.style(can, target, html.WIDTH, _target.offsetWidth+10, html.LEFT, (window.innerWidth-_target.offsetWidth)/2) }) }) }, delayLong: function(can, cb, interval, key) { can.onmotion.delay(can, cb, interval||300, key) }, - delayOnce: function(can, cb, interval, list) { can.core.Item(list, function(key) { delete(list[key]) }) + delayOnce: function(can, cb, interval, list) { + if (!list) { + var call = can.misc.fileLine(2), _call = "_delay_"+call.file+call.line + list = can[_call] = can[_call]||{} + } can.core.Item(list, function(key) { delete(list[key]) }) var key = can.base.Time(null, "%H:%M:%S.%s"); can.onmotion.delay(can, list[key] = function() { list[key] && cb() }, interval) }, delay: function(can, cb, interval, key) { if (!key) { return can.core.Timer(interval||30, cb) } diff --git a/index.css b/index.css index 514a3cf8..fecba752 100644 --- a/index.css +++ b/index.css @@ -98,7 +98,7 @@ body>div.carte div.item span.icon.gt { float:right; } body>div.input td { padding:5px; } body>div.input td span.icon { font-size:14px; margin-left:-25px; margin-right:10px; visibility:hidden; } body>div.input td:hover span.icon { visibility:visible; } -body>div.input select { width:200px; } +body>div.input select { width:190px; } body>div.input textarea { height:120px; width:200px; } body>div.input input:not([type=button]) { width:200px; } body>div.input div.action input[type=button] { width:90px; } @@ -152,7 +152,7 @@ fieldset.plug>form.option>div.icon { margin-left:5px; } div.carte.select.float { border-radius:0; } div.carte.select.float>div.item { text-align:center; } div.item.select span { margin-left:-20px; margin-right:10px; } -div.item.select input { font-family:monospace; border-radius:0; } +div.item.select input { font-family:monospace; border-radius:0; min-width:60px; } /* hover */ legend:hover { background-color:skyblue; } select:hover { background-color:gray; color:cyan; } diff --git a/lib/misc.js b/lib/misc.js index 1bd7b20a..d19c5ae5 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -129,8 +129,8 @@ Volcanos("misc", { value === ""? delete(args[key]): (args[key] = value) } var search = can.base.Args(args); return location.search = search }, - SearchHash: function(can) { if (!can.isCmdMode()) { return [] } - if (arguments.length > 1) { location.hash = encodeURIComponent(can.core.List(arguments).slice(1).join(ice.DF)) } + SearchHash: function(can) { if (!can.isCmdMode() && can._name != "Action") { return [] } + if (arguments.length > 1) { location.hash = can.core.List(arguments, function(item) { return encodeURIComponent(item) }).slice(1).join(ice.DF) } return can.core.Split(decodeURIComponent(location.hash.slice(1)), ice.DF)||[] }, 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 }, diff --git a/lib/user.js b/lib/user.js index f76aaf52..4a55b84d 100644 --- a/lib/user.js +++ b/lib/user.js @@ -132,7 +132,8 @@ Volcanos("user", { {view: html.OPTION, list: [{type: html.TABLE, list: can.core.List(form, function(item) { item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT), need[item.name] = item.need - item._init = function(target) { if (item.type == html.PASSWORD || item.type == html.USERNAME) { return } + item._init = function(target) { if (item.type == html.SELECT) { return can.onappend.select(can, target, item) } + if (item.type == html.PASSWORD || item.type == html.USERNAME) { return } if (item.name && item.name != ctx.ACTION) { target.value = msg.Option(item.name)||can.Option(item.name)||target.value||"" } item.mode = chat.SIMPLE, can.onappend.figure(can, can.base.Copy({run: function(event, cmds, cb) { var _msg = can.request(event, {_handle: ice.TRUE, action: msg.Option(html.ACTION)}, msg, can.Option()) can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { item.name && item.value && _msg.Option(item.name, item.value) }) diff --git a/panel/action.js b/panel/action.js index e78101f8..4d295260 100644 --- a/panel/action.js +++ b/panel/action.js @@ -1,11 +1,13 @@ (function() { const TABS = "tabs", TABVIEW = "tabview", HORIZON = "horizon", VERTICAL = "vertical", GRID = "grid", FREE = "free", FLOW = "flow", PAGE = "page", CAN_LAYOUT = "can.layout" -Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM) +Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM), list = can.misc.SearchHash(can) can.onmotion.clear(can), can.core.Next(msg.Table(), function(item, next) { item.type = chat.PLUGIN, item.mode = can.Mode() can.onappend.plugin(can, item, function(sub, meta, skip) { can._plugins = (can._plugins||[]).concat([sub]), can.onimport._tabs(can, sub, meta), skip || next() sub.run = function(event, cmds, cb) { return can.run(event, (river == web.SHARE? [ctx.ACTION]: []).concat([river, storm, meta.id||meta.index], cmds), cb) } sub._target.onclick = function(event) { event.target == sub._target && can.onmotion.scrollHold(can, function() { sub._tabs.click() }) } }) - }, function() { can.isCmdMode() || can.onmotion.delay(can, function() { can.onaction.layout(can) }) }) + }, function() { can.isCmdMode() || can.onmotion.delay(can, function() { can.onaction.layout(can) + list[0] == river && list[1] == storm && can.core.List(can._plugins, function(sub) { sub.Conf(ctx.INDEX) == list[2] && can.onmotion.delay(can, function() { sub._tabs.click() }) }) + }) }) }, _share: function(can, share) { share && can.runAction({}, web.SHARE, [share], function(msg) { can.user.title(msg.SearchOrOption(chat.TITLE)), can.setHeader(chat.THEME, msg.SearchOrOption(chat.THEME)), can.Mode(web.SHARE), msg.Length() == 1 && can.onaction._onaction_cmd(can) @@ -16,6 +18,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.R 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.isauto(can)) } can.onexport.layout(can) == FREE || (can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN) + can.misc.SearchHash(can, can.Conf(chat.RIVER), can.Conf(chat.STORM), meta.index) }, 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 } @@ -147,7 +150,9 @@ Volcanos(chat.ONKEYMAP, { ":": 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) }, Enter: function(event, can) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event)) }, - Escape: function(event, can) { can.onmotion.clearFloat(can), can._root.Search && can.onmotion.hidden(can, can._root.Search._target) }, + Escape: function(event, can) { + can.onmotion.clearFloat(can) || can._root.Search && can.onmotion.hidden(can, can._root.Search._target) + }, }, }, _engine: {}, toggleTheme: function(can, theme) { can.setHeader(chat.THEME, can.getHeaderTheme() == theme? ice.AUTO: theme) }, diff --git a/plugin/input/date.js b/plugin/input/date.js index e6a9fdd4..32f312e5 100644 --- a/plugin/input/date.js +++ b/plugin/input/date.js @@ -1,6 +1,5 @@ Volcanos(chat.ONFIGURE, {date: { - onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { - if (can._output.innerHTML) { return } + onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { if (can._output.innerHTML) { return } const TODAY = "today", YEAR = "year", MONTH = "month", HOUR = "hour", MINUTE = "minute", SECOND = "second" var today = new Date(), now = can.base.Date((target.value||"").trim()); function _cb(_now) { cb(can, can.user.time(can, now = _now), target.value) } can.onappend._action(can, [cli.CLOSE, [HOUR].concat(can.core.List(24)), [MINUTE].concat(can.core.List(0, 60, 5)), [SECOND].concat(can.core.List(0, 60, 5)), diff --git a/plugin/input/key.js b/plugin/input/key.js index 43396b6c..c822ca61 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -1,38 +1,26 @@ Volcanos(chat.ONFIGURE, {key: { _show: function(can, msg, cb, target, name) { if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value) { return can.onmotion.hidden(can) } - if (msg.append[msg.append.length-1] == ctx.ACTION) { msg.append = msg.append.slice(0, -1) } - if (msg.append[msg.append.length-1] == "cb") { msg.append = msg.append.slice(0, -1) } - can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, line) { value = line[key] - return {text: [value, html.TD, value == ""? "hr": ""], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) { - can.onmotion.delay(can, function() { target.blur(), can.close() }) - if (msg.cb && msg.cb[index]) { return msg.cb[index](value) } - can._delay_hidden = false, cb(can, value, target.value), msg.Option(ice.MSG_PROCESS) == ice.PROCESS_AGAIN && can.onmotion.delay(can, function() { can._load(event, can, cb, target, name, value) }) + if (can.base.isIn(msg.append[msg.append.length-1], ctx.ACTION, "cb")) { msg.append = msg.append.slice(0, -1) } + can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, item) { value = item[key] + return {text: [value, html.TD, value == ""? html.HR: ""], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) { + can.close(); if (msg.cb && msg.cb[index]) { return msg.cb[index](value) } cb(can, value, target.value) + msg.Option(ice.MSG_PROCESS) == ice.PROCESS_AGAIN && can.onmotion.delay(can, function() { can._load(event, can, cb, target, name, value) }) }} }), can.onappend._status(can, [mdb.TOTAL, mdb.INDEX]), can.Status(mdb.TOTAL, msg.Length()) - msg.append.length == 1 && can.page.ClassList.add(can, can._target, chat.SIMPLE) - can.onlayout.figure({target: target}, can, can._target) + msg.append.length == 1 && can.page.ClassList.add(can, can._target, chat.SIMPLE), can.onlayout.figure({target: target}, can, can._target) }, _load: function(event, can, cb, target, name, value) { can.runAction(event, mdb.INPUTS, [name, value||""], function(msg) { name == ctx.INDEX && can.core.Item(can.onengine.plugin.meta, function(key) { msg.Push(ctx.INDEX, can.core.Keys(ice.CAN, key)) }) can._show(can, msg, cb, target, name) }) }, - onclick: function(event, can, meta, target, cbs) { - can.onfigure.key.onfocus(event, can, meta, target, cbs) - can.onmotion.focus(can, target) - }, + onclick: function(event, can, meta, target, cbs) { can.onmotion.focus(can, target) }, onfocus: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return } meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value) }) }, - onblur: function(event, can, sub) { can.onmotion.delay(can, function() { - if (sub) { sub._delay_hidden || sub.close(), sub._delay_hidden = false } - }, 300) }, - onkeydown: function(event, can, meta, cb, target, sub, last) { - if (event.key == lang.ENTER && meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event)) { return sub.close() } - if (event.key == lang.ENTER) { return last(event) } - if (event.key == lang.ESCAPE) { return last(event) } - if (sub.hidden()) { return } - can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return cb(sub, td.innerText, target.value), td }) - || can.onmotion.delayOnce(can, function() { can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, - target.value.length < 3? 500: 150, sub._delay_select = sub._delay_select||{}) + onblur: function(event, can, sub) { sub && can.onmotion.delay(can, sub.close, 300) }, + onkeydown: function(event, can, meta, cb, target, sub, last) { if (event.key == lang.ESCAPE) { return last(event) } + if (event.key == lang.ENTER) { return meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event)? sub.close(): last(event) } + sub.hidden() || can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return cb(sub, td.innerText, target.value), td }) || can.onmotion.delayOnce(can, function() { + can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, target.value.length < 3? 500: 150) }, }}) diff --git a/plugin/input/province.js b/plugin/input/province.js index 2b60d7ae..11d8cbc7 100644 --- a/plugin/input/province.js +++ b/plugin/input/province.js @@ -1,5 +1,5 @@ Volcanos(chat.ONFIGURE, {province: { - onclick: function(event, can, meta, cbs, target) { cbs(function(can, cb) { + onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { can.require(["/require/shylinux.com/x/echarts/echarts.js", "/require/shylinux.com/x/echarts/china.js"], function() { var chart = echarts.init(can.page.Append(can, can._output, [{type: html.DIV, style: {width: can.page.width()/2, height: can.page.height()/2}}])._target) chart.setOption({geo: {map: 'china'}}), chart.on(html.CLICK, function(params) { target.value = params.name, can.close() }) diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 9f3794d3..24614930 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -380,11 +380,9 @@ Volcanos(chat.ONACTION, {list: ["首页", "官网", "调试", "百度"], }) }), can.runAction(can.request(event, {text: can.base.Format(list)}), button) }, - clear: function(event, can) { - var list = ["fieldset.input.float", "div.input.float", "div.carte.float", "div.vimer.find.float"]; for (var i = 0; i < list.length; i++) { - if (can.page.Select(can, can._root._target, list[i], function(item) { return can.page.Remove(can, item) }).length > 0) { return } - } - if (can.page.Select(can, can.ui.plug, "legend.select", function(item) { return item.click(), item }).length > 0) { return } + clear: function(event, can) { if (can.onmotion.clearFloat(can)) { return } + if (can.page.Select(can, document.body, "div.vimer.find.float", function(target) { return can.page.Remove(can, target) }).length > 0) { return } + if (can.page.Select(can, can.ui.plug, "legend.select", function(target) { return target.click(), target }).length > 0) { return } if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } if (can.page.isDisplay(can.ui.profile)) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } },