1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 16:58:06 +08:00

add studiolayout

This commit is contained in:
IT 老营长 @云轩领航-创始人 2024-04-17 04:15:08 +08:00
parent d3e9a345ef
commit 2a0b5dcc29
10 changed files with 102 additions and 19 deletions

View File

@ -425,8 +425,10 @@ var icon = {
key: "bi bi-hash", hash: "bi bi-hash", zone: "bi bi-diagram-3", id: "bi bi-sort-numeric-down",
modify: "bi bi-pencil-square", rename: "bi bi-pencil-square", remove: "bi bi-trash",
enable: "bi bi-toggle-off", disable: "bi bi-toggle-on",
expire: "bi bi-clock-history",
name: "bi bi-sort-alpha-down",
sess: "bi bi-telephone-forward",
path: "bi bi-folder2", file: "bi bi-file-earmark-text", line: "bi bi-sort-numeric-down",
start: "bi bi-play-circle", stop: "bi bi-stop-circle",
load: "bi bi-folder-plus", save: "bi bi-floppy", trash: "bi bi-trash",
@ -444,6 +446,7 @@ var icon = {
install: "bi bi-cloud-download",
runtime: "bi bi-info-square",
inspect: "bi bi-info-square",
info: "bi bi-info-square",
template: "bi bi-file-earmark-medical",
reboot: "bi bi-bootstrap-reboot",
restart: "bi bi-bootstrap-reboot",
@ -467,6 +470,7 @@ var icon = {
role: "bi bi-person-square",
title: "bi bi-textarea-t",
type: "bi bi-card-list",
scan: "bi bi-card-list",
send: "bi bi-send-check",
cmds: "bi bi-terminal",
localCreate: "bi bi-cloud-download",

View File

@ -393,7 +393,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) {
field: function(can, type, item, target) { type = type||html.STORY, item = item||{}
var name = can.core.Split(item.nick||item.index||"", " .").pop()||""; can.base.isIn(name,
tcp.SERVER, tcp.CLIENT, web.STUDIO, mdb.SEARCH, web.SERVICE, can.core.Split(can.ConfIndex(), ".").pop(), "launchTemplate",
) && (name = (item.index||"").split(".").slice(-2).join(".")), (type != html.PLUG && !can.base.isIn(can.ConfIndex(),
) && (name = (item.index||"").split(".").slice(-2).join(".")), (type != "story" && type != html.PLUG && !can.base.isIn(can.ConfIndex(),
web.DESKTOP, web.MESSAGE, web.VIMER,
)) && (name = can.core.Keys(item.space||item._space, name))
var title = item.title || can.user.isMobile && (can.user.isEnglish(can)? name: (item.help||name)) || (!item.help || name == item.help || can.user.isEnglish(can)? name: name+"("+can.core.Split(item.help)[0]+")")
@ -554,7 +554,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) {
if (key == mdb.STATUS && can.base.isIn(value, mdb.ENABLE, ice.TRUE)) { _value = `<i class="${icon.disable}">`
function onclick() { run(event, mdb.MODIFY, [mdb.STATUS, mdb.DISABLE]); return true }
}
return {className: option.indexOf(key) > -1? ice.MSG_OPTION: key == ctx.ACTION? ctx.ACTION: "", text: [msg.IsDetail() && key == mdb.KEY? can.user.trans(can, _value, null, html.INPUT): can.user.trans(can, _value, null, html.VALUE), html.TD], onclick: function(event) { var target = event.target
return {className: option.indexOf(key) > -1? ice.MSG_OPTION: key == ctx.ACTION? ctx.ACTION: "", text: [msg.IsDetail() && key == mdb.KEY? can.user.trans(can, _value, null, html.INPUT): value, html.TD], onclick: function(event) { var target = event.target
if (onclick()) { return }
if (key == cli.QRCODE && can.page.tagis(event.target, html.IMG)) { can.user.opens(event.target.title) }
if (can.page.tagis(target, html.INPUT) && target.type == html.BUTTON) { can.requestAction(request(event), target.name)
@ -572,6 +572,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) {
}, onmouseover: function(event) {
can.page.SelectChild(can, can._option, html.DIV_ITEM_TEXT, function(target) { can.page.ClassList.set(can, target, "will", can.page.ClassList.has(can, target, key)) })
}, _init: function(target) {
if (key == mdb.TYPE) { can.onappend.style(can, value, target.parentNode) }
if (key == ctx.ACTION && msg.IsDetail()) { can.onappend.style(can, ctx.ACTION, target.parentNode) }
key == ctx.ACTION && can.onappend.mores(can, target, data, msg.IsDetail()? 20: html.TABLE_BUTTON)
var list = can.page.Select(can, target, html.INPUT, function(target) {
@ -723,7 +724,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) {
ui.layout(can.ConfHeight(), can.ConfWidth()), can.onimport._layout && can.onimport._layout(can)
can.Action(html.FILTER) && can.onmotion.filter(can, can.Action(html.FILTER))
}
can.onimport._layout = can.onimport._layout||function(can) { if (!can.ui.content) { return }
can.onimport._layout = can.onimport._layout||function(can) { if (!can.ui.content || !can.ui.content.innerHTML) { return }
can.page.style(can, can.ui.content, html.HEIGHT, can._output.style[html.HEIGHT], html.MAX_HEIGHT, can._output.style[html.MAX_HEIGHT])
can.page.style(can, can.ui.project, html.HEIGHT, can.ui.content.offsetHeight+can.ui.display.offsetHeight)
can.onlayout.expand(can, can.ui.content)
@ -913,7 +914,7 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) {
},
},
scrollHold: function(can, cb, target) { target = target || can._output; var left = target.scrollLeft; cb(), target.scrollLeft = left },
scrollIntoView: function(can, target, margin) { if (!target || can._scroll) { return } can._scroll = true, margin = margin||0
scrollIntoView: function(can, target, margin) { if (!target || !target.parentNode || can._scroll) { return } can._scroll = true, margin = margin||0
var offset = (target.offsetTop-margin) - target.parentNode.scrollTop, step = offset < 0? -20: 20
if (Math.abs(offset) > 3000) {
return target.parentNode.scrollTop = (target.offsetTop-margin), delete(can._scroll)

View File

@ -125,6 +125,7 @@ table.content th.select[data-asc="1"] i.bi-sort-down-alt { display:none; }
table.content td.option { cursor:pointer; }
table.content td { padding:var(--table-padding); }
table.content td i { padding:var(--input-padding); }
table.content.detail td:first-child { word-break:keep-all; white-space:pre; }
table.content.detail td:first-child { text-align:center; }
table.content.detail td:first-child { background-color:var(--plugin-bg-color); position:sticky; left:0; }
table.content.detail td i { display:none; }
@ -866,7 +867,7 @@ fieldset>div.output.form>div.item>span { padding:var(--input-padding); }
fieldset>div.output.form>div.item>span.need { color:red; }
fieldset>div.output.form>div.item>div.item>input { font-size:20px; height:38px; width:var(--form-width); }
fieldset>div.output.form>div.item>div.item>input[type=button] { font-size:20px; height:48px; border:var(--box-notice); }
fieldset.studio>div.action>div.item:not(.icons) { font-style:italic; padding:var(--input-margin) var(--button-padding); }
fieldset.studio>div.action>div.item:not(.icons) { font-style:italic; }
fieldset.studio>div.output>fieldset>form.option div.icon.delete { display:none; }
fieldset.studio>div.output>fieldset>form.option div.icon:nth-child(2) { margin-left:var(--plugin-margin); }
fieldset.studio>div.output>fieldset>div.output>table.content { width:100%; }
@ -879,8 +880,7 @@ fieldset.plug.dream.zone>div.output>div.item>span { line-height:var(--action-hei
fieldset.cmd>div.item.state { line-height:22px; padding:var(--input-padding) var(--button-padding); float:right; }
fieldset.cmd>div.item.avatar { padding:0; height:var(--action-height); }
fieldset.cmd>div.item.avatar>img { height:var(--action-height); }
fieldset.cmd>div.action>div.tabs.select { border-bottom:var(--box-notice3); }
fieldset.cmd>div.output>div.project div.item.select { border-right:var(--box-notice3); }
/* fieldset.cmd>div.action>div.tabs.select { border-bottom:var(--box-notice3); } */
fieldset.Search div.story[data-type=spark] { margin:0; }
fieldset.Search>div.output>div.profile { border-left:none; width:unset; }
fieldset.Search>div.output>div.content>table.content td { cursor:pointer; }

View File

@ -134,7 +134,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp
"\u271A": shy({transform: "translate(0 2px)"}, function(event) { can.onaction.open(event, can, "open") }),
"\u2756": shy({}, function(event) { can.onaction.plug(event, can, "plug") }),
"\u25E7": function(event) { var show = can.onmotion.toggle(can, can.ui.project); can.onimport.layout(can), can.isCmdMode() && can.onexport.session(can, PROJECT_HIDE, show? "": html.HIDE) },
"\u25E8": shy({transform: "rotate(90deg) translate"+(can.user.isWindows? "(-2px)": "(1px)")}, function(event) { if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } can.onaction.exec(event, can) }),
"\u25E8": shy({transform: "rotate(90deg) translate"+(can.user.isWindows? "(-2px)": "(1px,-2px)")}, function(event) { if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } can.onaction.exec(event, can) }),
"\u25E8 ": function(event) { if (can.page.isDisplay(can.ui.profile)) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } can.onaction.show(event, can) },
}, function(text, cb) { return cb && {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} }))
},
@ -282,8 +282,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp
if (can.ui.zone && can.ui.zone.source) {
var p = can.ui.zone.source[can.Option(nfs.PATH)+can.Option(nfs.FILE)]
can.page.Select(can, can.ui.zone.source._target, "div.name", function(target) {
can.page.ClassList.del(can, target, "current")
}), p && can.page.ClassList.add(can, p, "current")
can.page.ClassList.del(can, target.parentNode, "current")
}), p && can.page.ClassList.add(can, p.parentNode, "current")
}
var content = can.ui.content; if (!content) { return } if (content._root) { can.ui.content = content._root }
can.ui.size = {profile: can._msg.Option(html.WIDTH), display: can._msg.Option(html.HEIGHT)}

View File

@ -15,8 +15,10 @@ fieldset.vimer>div.output.normal>div.layout>div.tabs>div.tabs>div.tabs.select {
fieldset.vimer>div.output.insert>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-danger3); }
fieldset.vimer>div.output.normal>div.layout>div.path span.mode.normal { color:var(--notice-bg-color); }
fieldset.vimer>div.output.insert>div.layout>div.path span.mode.insert { color:var(--danger-bg-color); }
fieldset.vimer>div.output.insert>div.project div.name.current { background-color:var(--danger-bg-color); color:var(--danger-fg-color); }
fieldset.vimer>div.output.normal>div.project div.name.current { background-color:var(--notice-bg-color); color:var(--notice-fg-color); }
/* fieldset.vimer>div.output.insert>div.project div.item.current { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } */
/* fieldset.vimer>div.output.normal>div.project div.item.current { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } */
fieldset.vimer>div.output.insert>div.project div.item.current { background-color:var(--hover-bg-color); border-right:var(--box-danger3); }
fieldset.vimer>div.output.normal>div.project div.item.current { background-color:var(--hover-bg-color); border-right:var(--box-notice3); }
fieldset.vimer>div.output.normal>div.project div.expand.open { color:var(--notice-bg-color); }
fieldset.vimer>div.output.insert>div.project div.expand.open { color:var(--danger-bg-color); }
div.input.vimer.open.float input[type=text] { width:100% !important; }

View File

@ -67,7 +67,7 @@ Volcanos(chat.ONACTION, {list: [
"后台", "桌面", "官网"], _trans: {show: "预览", exec: "展示"},
_run: function(event, can, button, args, cb) { can.runAction(event, button, args, cb||function(msg) {
if (msg.IsErr()) { return can.user.toastFailure(can, msg.Result()) }
can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)), can.user.toastSuccess(can, button), can.ui.zone.source.refresh()
can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)), can.ui.zone.source.refresh()
}) },
_runs: function(event, can, button, cb) { var meta = can.Conf(); can.request(event, {action: button}), can.user.input(event, can, meta.feature[button], function(args) { can.onaction._run(event, can, button, args, cb) }) },
save: function(event, can, button) { can.request(event, {file: can.Option(nfs.FILE), content: can.onexport.content(can)})
@ -81,7 +81,7 @@ Volcanos(chat.ONACTION, {list: [
if (can.onexport.parse(can) == nfs.GO) { var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content)
can.ui.content._max = 0, can.core.List(msg.Result().split(lex.NL), function(item) { can.onaction.appendLine(can, item) })
can.onaction.selectLine(can, line+imports(msg.Result())-imports(msg.Option(nfs.CONTENT)))
} can.user.toastSuccess(can, button, can.Option(nfs.PATH)+can.Option(nfs.FILE))
} can.user.toastSuccess(can, can.Option(nfs.PATH)+can.Option(nfs.FILE), button)
})
},
trash: function(event, can, button) { can.onaction._run(event, can, button, [can.Option(nfs.PATH)+can.Option(nfs.FILE)], function() { can._msg._tab._close() }) },

View File

@ -13,13 +13,27 @@ Volcanos(chat.ONIMPORT, {
_inner: function(can, sub, msg) { sub = sub||can, can.onmotion.scrollIntoView(can, can.onappend.table(sub, msg)), can.onmotion.scrollIntoView(can, can.onappend.board(sub, msg)), can.onmotion.story.auto(sub) },
_cookie: function(can, msg) { can.misc.Cookie(can, msg._arg[0], msg._arg[1]), can.Update() },
_session: function(can, msg) { can.misc.sessionStorage(can, msg._arg[0], msg._arg[1]), can.Update() },
_field: function(can, msg, cb) { var height = can.base.Max(html.STORY_HEIGHT, can.ConfHeight()-2*html.ACTION_HEIGHT), width = can.ConfWidth()
msg.Table(function(item) { if (can.page.tagis(can._target, html.FIELDSET_STORY) || can._msg && can._msg.IsDetail()) { item.style = item.style||html.FLOAT }
_field: function(can, msg, cb) {
var height = can.base.Max(html.STORY_HEIGHT, can.ConfHeight()-can.onexport.actionHeight(can)-can.onexport.statusHeight(can)), width = can.ConfWidth()
var tabs = false
if (msg.Option("field.tabs")) { height = can.ConfHeight()-can.onexport.actionHeight(can)-can.onexport.statusHeight(can)
can.sub && can.sub.onimport.tabs(can, [{name: msg.Option("field.tabs")}], function() {
can.onmotion.cache(can, function() { return msg.Option("field.tabs") })
}), tabs = true
}
msg.Table(function(item) {
// if (can.page.tagis(can._target, html.FIELDSET_STORY) || can._msg && can._msg.IsDetail()) { item.style = item.style||html.FLOAT }
can.onappend._plugin(can, item, {index: item.index, args: can.base.Obj(item.args||item.arg, []), height: height, width: width}, function(sub) {
can._plugins = (can._plugins||[]).concat([sub])
sub.run = function(event, cmds, cb) { var index = msg.Option(ice.MSG_INDEX); can.run(can.request(event, {pod: item.space}), (msg[ice.MSG_PREFIX]? msg[ice.MSG_PREFIX]: index? [ctx.RUN, index]: []).concat(cmds), cb, true) }
if (item.style != html.FLOAT && can.base.isIn(sub.ConfIndex(), wiki.PORTAL, chat.IFRAME, chat.DESKTOP, wiki.WORD, code.VIMER,)) { height = can.base.Max(can.onexport.outputHeight(can), can.ConfHeight(), 480) }
can.page.ClassList.has(can, sub._target, html.FLOAT)? can.onmotion.float(sub): sub.onimport.size(sub, height, width, true), cb && cb(sub)
if (item.style == html.FLOAT) { return } can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, sub._target) }, 300)
sub.onexport.output = function() {
tabs && sub.sub.onimport.tabs(can, [{name: msg.Option("field.tabs")}], function() {
tabs || can.onmotion.cache(can, function() { return msg.Option("field.tabs") })
}), tabs = false
}
if (can.base.isIn(sub.ConfIndex(), wiki.WORD)) { sub.onexport.output = function() { can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "") } }
})
})
@ -97,6 +111,7 @@ Volcanos(chat.ONIMPORT, {
(can.page.style(can, can._output, html.HEIGHT, height, html.WIDTH, width, html.MAX_HEIGHT, "", html.MAX_WIDTH, ""), can.page.style(can, can._target, html.WIDTH, width))
if (can.misc.Search(can, log.DEBUG) == ice.TRUE) { can.Status(html.HEIGHT, can.base.Max(height, can._output.offsetHeight), html.WIDTH, width) }
can.page.style(can, can._status, html.MAX_WIDTH, width)
can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, height, width, false) })
var sub = can.sub; if (!sub) { return auto } sub.Mode(mode), sub.ConfHeight(height), sub.ConfWidth(width), can.onimport._size(can)
mode? sub.onlayout[mode](sub, height, width): sub.onlayout._init(sub, height, width)
return auto

View File

@ -0,0 +1,17 @@
fieldset.studiolayout>div.output>div.project div.item { font-family:var(--code-font-family); border-left:var(--box-border3); }
fieldset.studiolayout>div.output>div.project div.item.select { border-left:var(--box-notice3); }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story { box-shadow:none; margin:0px; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story { box-shadow:none; margin:0px; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story { box-shadow:none; margin:0px; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>div.action>div.item.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>div.action>div.item.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>div.action>div.item.state { display:none; }
body.cmd { --box-shadow:none; }
body.cmd legend { margin-right:0; }

View File

@ -0,0 +1,44 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.project(can, msg, aaa.SESS, function(event, sess, value) { return {
content: {index: "web.code.redis.keys", args: sess},
profile: {index: "web.code.redis.configs", args: sess, style: html.OUTPUT},
display: {index: "web.code.redis.shells", args: sess, style: html.OUTPUT},
} })
},
_nick: function(can, value) { return value.name },
project: function(can, msg, key, cb) { can.ui = can.onappend.layout(can), can.onappend.style(can, "studiolayout", can._fields)
var _select; msg.Table(function(value) { value.nick = can.onimport._nick(can, value)
var target = can.onimport.item(can, value, function(event, value) { can.misc.SearchHash(can, value[key])
if (can.onmotion.cache(can, function(save, load) {
save({
_content: can.ui._content_plugin,
_profile: can.ui._profile_plugin,
_display: can.ui._display_plugin,
}), load(value[key], function(bak) {
can.ui._content_plugin = bak._content
can.ui._profile_plugin = bak._profile
can.ui._display_plugin = bak._display
})
return value[key]
}, can.ui.content, can.ui.profile, can.ui.display)) {
can.onmotion.select(can, can._action, html.DIV_TABS, value._tabs); return
} value._tabs = can.onimport.tabs(can, [value], function() { target.click() })
can.core.Item(cb(event, value[key], value), function(key, item) { can.onmotion.toggle(can, can.ui[key], true)
can.onappend.plugin(can, item, function(sub) { can.ui["_"+key+"_plugin"] = sub
can.onimport.layout(can), sub.onexport.output = function() { can.onimport.layout(can) }
}, can.ui[key])
})
}); _select = _select||target, can.db.hash[0] == value.sess && (_select = target)
}), _select && _select.click()
},
layout: function(can) {
can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) {
var height = can.ConfHeight(), width = (can.ConfWidth()-can.ui.project.offsetWidth-2), margin = 0
can.ui._profile_plugin && (width /= 2), can.ui._display_plugin && (height /= 2)
can.ui._content_plugin && can.ui._content_plugin.onimport.size(can.ui._content_plugin, height-margin, width-margin, false)
can.ui._profile_plugin && can.ui._profile_plugin.onimport.size(can.ui._profile_plugin, height-margin, width-margin, false)
can.ui._display_plugin && can.ui._display_plugin.onimport.size(can.ui._display_plugin, height-margin-2, width*2-margin, false)
})
},
}, [""])

View File

@ -120,9 +120,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) {
can.user.carteItem(event, can, item)
}
var icon = item.icon||item.icons
var ui = can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.status]], list: [
var ui = can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.role, item.status]], list: [
icon && (can.base.contains(icon, ice.HTTP, ".ico", ".png", ".jpg")? {img: can.misc.Resource(can, icon)}: {icon: icon}),
{text: item.nick||item.name||item.zone}], title: item.title, onclick: function(event) {
{text: item.nick||item.name||item.sess||item.zone}], title: item.title, onclick: function(event) {
can.onmotion.select(can, target, html.DIV_ITEM, event.currentTarget)
cb(event, item, event.currentTarget._list && can.onmotion.toggle(can, event.currentTarget._list))
}, oncontextmenu: oncontextmenu,
@ -189,7 +189,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) {
} cbs && cbs(tabs), can.page.Remove(can, target)
can.onexport.tabs(can)
}
return {view: html.TABS, title: tabs.title||tabs.text, list: [{text: [tabs.nick||tabs.name, html.SPAN, mdb.NAME]}, {icon: mdb.DELETE, onclick: function(event) {
return {view: [[html.TABS, tabs.type, tabs.role, tabs.status]], title: tabs.title||tabs.text, list: [{text: [tabs.nick||tabs.name, html.SPAN, mdb.NAME]}, {icon: mdb.DELETE, onclick: function(event) {
close(tabs._target), can.onkeymap.prevent(event)
}}], onclick: function(event) {
can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs)