diff --git a/const.js b/const.js index 1170e022..49593df1 100644 --- a/const.js +++ b/const.js @@ -451,7 +451,9 @@ var icon = { 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", + load: "bi bi-folder-plus", save: "bi bi-floppy", + trash: "bi bi-trash", + copy: "bi bi-copy", pull: "bi bi-cloud-download", push: "bi bi-cloud-upload", upload: "bi bi-box-arrow-in-up", download: "bi bi-box-arrow-down", "import": "bi bi-folder-plus", "export": "bi bi-floppy", @@ -480,6 +482,7 @@ var icon = { branch: "bi bi-diagram-3", commit: "bi bi-hash", message: "bi bi-wechat", + plugin: "bi bi-window-stack", preview: "bi bi-window-stack", show: "bi bi-window-stack", display: "bi bi-window-desktop", exec: "bi bi-window-desktop", chat: "bi bi-chat-dots", help: "bi bi-question-square", doc: "bi bi-question-square", diff --git a/frame.js b/frame.js index 1745e16a..33b9f785 100644 --- a/frame.js +++ b/frame.js @@ -289,7 +289,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { full: !can.isCmdMode() && "切换全屏", open: !can.isCmdMode() && "打开链接", chat: can.user.isTechOrRoot(can) && can.ConfIndex() != chat.MESSAGE && "发送聊天", - help: can.page.ClassList.has(can, can._fields||can._target, html.PLUGIN) && can.Conf("_help") && can.Conf("_help") != "" && "查看文档", + // help: can.page.ClassList.has(can, can._fields||can._target, html.PLUGIN) && can.Conf("_help") && can.Conf("_help") != "" && "查看文档", }, function(key, value) { return (value || value === "") && {view: [[html.ITEM, html.BUTTON, key, mdb.ICONS, "state"]], list: [{icon: icon[key]}], title: key == "_space"? "": can.user.trans(can, key), onclick: function(event) { @@ -356,7 +356,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }, target: output}), msg.Defer() }) }, - _status: function(can, list, status, msg) { list && list.Option && (list = list.Option(ice.MSG_STATUS)||list) + _status: function(can, list, status, msg) { list && list.Option && (list = list.Option(ice.MSG_STATUS)||[]) status = status||can._status, can.onmotion.clear(can, status) var keys = {} var fileline = can.Conf("_fileline")||"" @@ -635,7 +635,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }) can.core.List(list, function(target) { can.onappend.style(can, html.ICONS, target); var _icon = (can.page.icons(can, target.name)||{}).icon; if (target.name == mdb.DELETE) { _icon = icon.trash } - can.page.insertBefore(can, [{icon: _icon, title: can.user.trans(can, target.name), onclick: target.onclick||function(event) { + can.page.insertBefore(can, [{icon: _icon+(" "+(can.page.buttonStyle(can, target.name)||"")), title: can.user.trans(can, target.name), onclick: target.onclick||function(event) { can.onengine.signal(can, "onevent", can.request(event, {_type: html.BUTTON})) can.Update(request(event)._event, [ctx.ACTION, target.name]), can.onkeymap.prevent(event) }}], target.nextSibling, target.parentNode) diff --git a/index.css b/index.css index b18eb1ed..e155dc1f 100644 --- a/index.css +++ b/index.css @@ -86,29 +86,29 @@ body { --code-font-size:14px; --code-line-height:20px; --code-tabs-height:43px; --icon-font-size:var(--legend-font-size); --svg-font-size:24px; --svg-stroke-width:1; } -body.web.code.vimer.cmd { --code-line-height:24px; } -body.en { --card-button:3; } -body.mobile { --footer-height:60px; --svg-font-size:13px; } +body.width6 { /* 1920-2240 大显示器 */ + --project-width:280px; --river-width:280px; --input-width:180px; --url-input-width:1000px; --qrcode-width:420px; --card-height:160px; + --plug-height:480px; --plug-width:1200px; +} +body.width5 { /* 1600-1920 */ +} +body.width4 { /* 1280-1600 笔记本 显示器调试 */ + --float-width:1000px; +} +body.width3 { /* 960-1280 平板横屏 */ + --float-width:1000px; +} +body.width2 { /* 640-960 手机横屏 平板竖屏 笔记本调试 */ + --input-width:80px; --url-input-width:160px; +} body.width1 { /* 320-640 手机竖屏 */ --project-width:120px; --river-width:280px; --input-width:80px; --url-input-width:160px; --form-width:290px; --river-margin:0; --plugin-margin:0; --legend-margin:5px; --button-margin:5px; --table-button:2; --card-button:3; } -body.width2 { /* 640-960 手机横屏 平板竖屏 笔记本调试 */ - --input-width:80px; --url-input-width:160px; -} -body.width3 { /* 960-1280 平板横屏 */ - --float-width:1000px; -} -body.width4 { /* 1280-1600 笔记本 显示器调试 */ - --float-width:1000px; -} -body.width5 { /* 1600-1920 */ -} -body.width6 { /* 1920-2240 大显示器 */ - --project-width:280px; --river-width:280px; --input-width:180px; --url-input-width:1000px; --qrcode-width:420px; --card-height:160px; - --plug-height:480px; --plug-width:1200px; -} +body.en { --card-button:3; } +body.mobile { --footer-height:60px; --svg-font-size:13px; } +body.web.code.vimer.cmd { --code-line-height:24px; } /* element */ * { box-sizing:border-box; padding:0; border:0; margin:0; tab-size:4; } legend { padding:0 var(--legend-padding); } @@ -132,7 +132,7 @@ table.content.checkbox td:first-child { text-align:center; padding:var(--table-p table.content.action th:last-child { text-align:center; padding:var(--table-padding); position:sticky; right:2px; } table.content.action td:last-child { text-align:center; padding:var(--table-padding); position:sticky; right:2px; } table.content.action td:last-child i { color:var(--notice-bg-color); } -table.content.action td:last-child i.bi-trash { color:var(--danger-bg-color); } +table.content.action td:last-child i.danger { color:var(--danger-bg-color); } table.content.action td:last-child input { border:none; color:var(--notice-bg-color); } table.content.action td:last-child input:hover { background-color:var(--hover-bg-color); color:var(--notice-bg-color); } table.content.action td:last-child input.danger { border:none; color:var(--danger-bg-color); } @@ -340,9 +340,10 @@ div.toast.float div.action>div.item input { padding:0 20px; } div.toast.float div.action>div.item.danger input { border:var(--box-danger); } div.toast.float div.action>div.item.notice input { border:var(--box-notice); } div.toast.float div.action>div.item.open input { border:var(--box-notice); } -body>div.carte { padding:0; } +body>div.carte { border:0; padding:0; } body>div.carte input[name=filter] { margin:var(--input-margin); width:calc(100% - 10px); position:sticky; top:var(--input-margin); } body>div.carte div.item { white-space:pre; padding:var(--button-padding); } +body>div.carte div.item i:first-child { margin-right:var(--button-margin); } body>div.carte div.item span.icon.next { line-height:22px; height:22px; float:right; } body>div.carte.select.float>div.item { text-align:center; } body>div.carte.header.avatar img { width:370px; } @@ -529,9 +530,10 @@ fieldset.panel.auto>div.output { background-color:var(--panel-bg-color); color:v fieldset.panel.main>div.output { background-color:var(--action-output-bg-color); } fieldset:not(.panel) { background-color:var(--plugin-bg-color); color:var(--plugin-fg-color); } fieldset.input div.output { background-color:var(--input-bg-color); } +fieldset.input div.output>table.content { border-collapse:collapse; } fieldset.input tr:hover { background-color:var(--tr-hover-bg-color); } fieldset.input td:hover { background-color:var(--td-hover-bg-color); } -fieldset.input>span.close { padding:var(--input-padding); position:absolute; top:var(--input-padding); right:var(--input-padding); } +fieldset.input>span.close { padding:var(--input-padding); position:absolute; top:0; right:0; line-height:16px; } fieldset.input>span.close:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); cursor:pointer; } div.float { background-color:var(--float-bg-color); } div.carte div.item:hover { background-color:var(--hover-bg-color); } @@ -660,10 +662,12 @@ form.option>div.item.icon.refresh { font-size:28px; line-height:26px; display:fl form.option>div.item.icon.goback { font-size:28px; line-height:26px; display:flex; align-items:flex-start; } form.option>div.icon.delete { font-size:20px; line-height:33px; display:flex; align-items:flex-start; } form.option>div.item.icon.play { font-size:16px; } -body.windows form.option>div.item.icon.delete { line-height:32px; display:flex; align-items:flex-start; } -body.windows form.option>div.item.icon.menu { font-size:18px; line-height:32px; padding:0 3px; } -body.windows form.option>div.item.icon.refresh { font-size:24px; line-height:32px; } -body.windows form.option>div.item.icon.goback { font-size:24px; line-height:32px; } +body.windows form.option>div.item.icon.delete { line-height:28px; display:flex; align-items:flex-start; } +body.windows form.option>div.item.icon.menu { font-size:18px; line-height:28px; padding:0 3px; } +body.windows form.option>div.item.icon.refresh { font-size:24px; line-height:28px; } +body.windows form.option>div.item.icon.goback { font-size:24px; line-height:28px; } +body.windows div.item.button.refresh>span.icon { font-size:22px; line-height:28px; } +body.windows div.item.button.create>span.icon { line-height:28px; } div.item.text { position:relative; } div.item.text.filter input { padding-left:24px; } div.item.text._icon input { padding-left:24px; } @@ -697,8 +701,6 @@ div.item.button.refresh { display:flex; align-items:flex-start; } div.item.button.create>span.icon { font-size:28px; line-height:26px; height:var(--action-height); } div.item.button.insert>span.icon { font-size:28px; line-height:26px; height:var(--action-height); } div.item.button.refresh>span.icon { font-size:28px; line-height:26px; height:var(--action-height); } -body.windows div.item.button.create>span.icon { line-height:28px; } -body.windows div.item.button.refresh>span.icon { font-size:22px; line-height:32px; } div.item.button._space.icons { flex-grow:1; min-width:var(--button-margin); } div.item.button._space.icons:hover { background-color:unset; cursor:unset; } fieldset.inner fieldset.story div.item.button._space.icons { margin-left:0; flex-grow:1; } @@ -1008,8 +1010,9 @@ fieldset.panel.Action>div.output::-webkit-scrollbar { width:0 !important; height fieldset.dream>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.input.key::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.input.key>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } -body.windows fieldset>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } -body.windows *::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.word>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.xterm div.xterm-viewport::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.web.code.git.search>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } + +body.windows *::-webkit-scrollbar { width:0 !important; height:0 !important; } +body.windows * { scrollbar-width:none; } diff --git a/lib/page.js b/lib/page.js index 65374b7a..b0115471 100644 --- a/lib/page.js +++ b/lib/page.js @@ -387,6 +387,7 @@ Volcanos("page", { icons: function(can, name, space) { if (!name) { return } if (can.base.contains(name, ".ico", ".png", ".jpg")) { return {img: can.misc.Resource(can, (name.indexOf(nfs.PS) == -1? nfs.USR_ICONS: "")+name, space)} } // if (can.page.unicode[name]) { return {text: [can.page.unicode[name], "", "icon"]} } + if (name == mdb.DELETE) { return {icon: "bi bi-trash"} } if (can.base.beginWith(name, "bi ")) { return {icon: name} } var _icon = can.Conf("_icons."+name)||can.Conf("_trans.icons."+name)||can.core.Value(can.onaction, ["_trans.icons."+name])||icon[name]; if (_icon) { return {icon: _icon} } @@ -439,8 +440,8 @@ Volcanos("page", { return action }, buttonStyle: function(can, name) { - return can.base.isIn(name, mdb.CREATE, mdb.INSERT, mdb.IMPORT, nfs.CLONE, cli.START, ctx.RUN, web.UPLOAD, web.CONFIRM, aaa.LOGIN, code.AUTOGEN, "sso", "add", "pull", "push", "commit", "preview", "auto-preview", ice.APP)? html.NOTICE: - can.base.isIn(name, mdb.REMOVE, mdb.DELETE, mdb.PRUNES, mdb.PRUNE, nfs.TRASH, cli.RESTART, cli.STOP, cli.CLOSE, cli.REBOOT, web.CANCEL, code.UPGRADE, "del", "drop", "access", "kill", "prockill")? html.DANGER: "" + return can.core.Value(can.onaction, ["_trans", "style", name])||(can.base.isIn(name, mdb.CREATE, mdb.INSERT, mdb.IMPORT, nfs.CLONE, cli.START, ctx.RUN, web.UPLOAD, web.CONFIRM, aaa.LOGIN, code.AUTOGEN, "sso", "add", "pull", "push", "commit", "preview", "auto-preview", ice.APP)? html.NOTICE: + can.base.isIn(name, mdb.REMOVE, mdb.DELETE, mdb.PRUNES, mdb.PRUNE, nfs.TRASH, cli.RESTART, cli.STOP, cli.CLOSE, cli.REBOOT, web.CANCEL, code.UPGRADE, "del", "drop", "access", "kill", "prockill")? html.DANGER: "") }, exportValue: function(can, msg, target) { target = target||can._output msg.OptionDefault(ice.MSG_THEME, can.getHeaderTheme()) diff --git a/lib/user.js b/lib/user.js index f6936e9b..10f64b11 100644 --- a/lib/user.js +++ b/lib/user.js @@ -17,6 +17,7 @@ Volcanos("user", { }, info: {}, isTesla: navigator.userAgent.indexOf("Tesla") > -1, isChrome: navigator.userAgent.indexOf("Chrome") > -1, + isSafari: navigator.userAgent.indexOf("Safari") > -1, isMailMaster: navigator.userAgent.indexOf("MailMaster") > -1, isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1, isIPhone: navigator.userAgent.indexOf("iPhone") > -1, @@ -168,12 +169,16 @@ Volcanos("user", { input: [html.FILTER, function(event) { if (event.key == code.ESCAPE) { return carte.close() } can.onkeymap.selectItems(event, can, carte._target) } ], _init: function(target) { can.onmotion.delay(can, function() { target.placeholder = "search in "+(can.core.List(list, function(item) { if (item) { return item } }).length-1)+" items", target.focus() }) } } } - if (can.base.isString(item)||can.base.isNumber(item)) { var _style = can.page.buttonStyle(can, item) + if (can.base.isString(item)||can.base.isNumber(item)) { + if (can.base.beginWith(item, "<")) { + return {view: [html.ITEM, html.DIV, item]} + } + var _style = can.page.buttonStyle(can, item) return { - // view: [[html.ITEM, item, _style], html.DIV, (isinput || meta._style == ice.CMD) && !trans? item: can.user.trans(can, item, trans)], - view: [[html.ITEM, item, _style], html.DIV, can.user.trans(can, item, trans)], - onmouseenter: function(event) { remove_sub(carte) }, + view: [[html.ITEM, item, _style]], + list: [can.page.icons(can, item), {text: can.user.trans(can, item, trans)}], onclick: function(event) { click(event, item, index) }, + onmouseenter: function(event) { remove_sub(carte) }, } } if (can.base.isArray(item)) { @@ -181,6 +186,7 @@ Volcanos("user", { can.onimport && can.onimport[item[0]]? can.onimport[item[0]](can, button, event): click(event, button, index) }, carte, trans); carte._sub = sub } return {view: html.ITEM, list: [ + can.page.icons(can, item[0]), {text: can.user.trans(can, item[0], trans)}, {text: [lex.SP+can.page.unicode.next, "", [html.ICON, "next"]]} ], onmouseenter: subs, onclick: subs} diff --git a/panel/action.js b/panel/action.js index 69ae52de..80ae6ea3 100644 --- a/panel/action.js +++ b/panel/action.js @@ -23,7 +23,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var river = can.Conf(chat.R can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, sub._target) can.onmotion.select(can, can._action, html.DIV_ITEM, sub._tabs) can.onmotion.select(can, can._header_tabs, html.DIV_TABS, sub._header_tabs) - can.onmotion.delay(can, function() { sub._header_tabs.scrollIntoViewIfNeeded() }) + // can.onmotion.delay(can, function() { sub._header_tabs.scrollIntoViewIfNeeded() }) var layout = can.onexport.layout(can); layout == FREE || (can._output.scrollTop = sub._target.offsetTop-10) can.isCmdMode() || can.misc.SearchHash(can, can.Conf(chat.RIVER), can.Conf(chat.STORM), sub.ConfIndex(), layout) sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can)) diff --git a/panel/footer.css b/panel/footer.css index 7616e51e..22a96d71 100644 --- a/panel/footer.css +++ b/panel/footer.css @@ -1,6 +1,7 @@ // fieldset.Footer { width:100%; } fieldset.Footer>div.output { font-style:italic; height:var(--footer-height); display:flex; } fieldset.Footer>div.output div.item { padding:7px; height:var(--footer-height); } +fieldset.Footer>div.output div.item.button { padding:7px 0; } fieldset.Footer>div.output div.title:first-child { margin-left:var(--header-height); } fieldset.Footer:not(.tabview)>div.output div.title:first-child { font-weight:bold; text-align:center; width:var(--river-width); } fieldset.Footer>div.output input[type=button] { background-color:transparent; color:var(--panel-fg-color); border:0; } diff --git a/panel/header.js b/panel/header.js index 6a7f7ea4..2176c325 100644 --- a/panel/header.js +++ b/panel/header.js @@ -169,7 +169,13 @@ Volcanos(chat.ONACTION, {_init: function(can) {}, "change language to zh-cn", "切换语言为中文", "change language to en-us", "切换语言为英文", - "en-us", "英文", "zh-cn", "中文", "auto", "默认" + "en-us", "英文", "zh-cn", "中文", "auto", "默认", + "icons", { + shareuser: "bi bi-link-45deg", + theme: "bi bi-columns-gap", + language: "bi bi-spellcheck", + user: "bi bi-person-square", + }, ), }) Volcanos(chat.ONEXPORT, { diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index f0c1f156..db1fe4bb 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -47,6 +47,7 @@ fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div { padding:0 var(- fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.online { margin-left:0 !important; margin-right:0 !important; flex-direction: row-reverse; } fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.online img { height:24px; } fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar { padding:0; } +fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.qrcode i { margin-top:3px; } fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar>img { height:32px; clip-path:circle(40%); } fieldset.inner.cmd>div.output>div.layout>div.path:not(.hide) { display:flex; } fieldset.inner.cmd>div.output>div.layout>div.plug { box-shadow:var(--th-box-shadow); height:var(--action-height); overflow:auto; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 2029707c..325fe6d9 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -115,7 +115,8 @@ Volcanos(chat.ONIMPORT, { function isIndex() { return line == ctx.INDEX } function isSpace() { return line == web.SPACE } function show() { can._msg && can._msg.Option && can._msg.Option(nfs.LINE, can.Option(nfs.LINE)), can._msg = can.db.tabview[key] can.Option(can.onimport.history(can, {path: path, file: file, line: can._msg.Option(nfs.LINE)||can.onexport.session(can, SELECT_LINE+nfs.DF+path+file)||1})) - can.onsyntax._init(can, can._msg, function(content) { var msg = can._msg; can.onexport.hash(can), can.isCmdMode() && can.onexport.title(can, (isIndex()||isSpace()? "": path)+file) + can.onsyntax._init(can, can._msg, function(content) { var msg = can._msg; can.onexport.hash(can) + can.onexport.title(can, isIndex()||isSpace()? file: file.split("/").slice(-2).join("/")) can.onmotion.select(can, can.ui._tabs, html.DIV_TABS, msg._tab), can.onmotion.toggle(can, can.ui.path, true) if (isSpace()) { can.base.contains(file, "/") || can.onmotion.hidden(can, can.ui.path) can.ui.path.innerHTML = can.page.Format(html.A, can.base.trimPrefix(can.misc.MergePodCmd(can, {pod: file}), location.origin)) diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index 2ec6a25a..fabe7ac2 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -9,7 +9,7 @@ Volcanos(chat.ONIMPORT, { _project: function(can, msg, hash) { msg.Table(function(value) { value.nick = `${value.hash}(${value.name||value.type||"ish"})`, value._select = value.hash == hash[0] can.onimport.item(can, value, function(event, item, show, target) { - can.onimport.tabsCache(can, can.request(), value.hash, value, target, function() { + can.onimport.tabsCache(can, can.request(), value.hash, value, target, function() { can.onappend._status(can) value._term = can.onimport._connect(can, value, can.ui.content) }) }) diff --git a/plugin/state.js b/plugin/state.js index 1e8b82c7..6dfce7f8 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -332,7 +332,10 @@ Volcanos(chat.ONEXPORT, { return can.misc.sessionStorage(can, [can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), key, location.pathname], value) }, title: function(can, title) { if (can.base.isIn(title, web.DESKTOP)) { return } - var pod = can.misc.Search(can, ice.POD); can.isCmdMode() && can.user.title(title+(pod && title != pod? " "+pod: "")) + var list = [title] + function push(p) { p && list.indexOf(p) == -1 && list.push(p) } + push(can.ConfIndex()), push(can.ConfSpace()||can.misc.Search(can, ice.POD)) + can.isCmdMode() && can.user.title(list.join(" ")) }, args: function(can) { return can.Option() }, link: function(can) { diff --git a/plugin/table.js b/plugin/table.js index 1fa09f28..541a5b8d 100644 --- a/plugin/table.js +++ b/plugin/table.js @@ -209,7 +209,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target, cb) { tabsCache: function(can, msg, key, value, target, cb) { if (value._tabs) { return value._tabs.click() } value._tabs = can.onimport.tabs(can, [value], function() { can.onexport.hash(can, key), can.Status(value), can.db.value = value can.page.isSelect(target) || can.onmotion.delay(can, function() { target.click() }) - if (can.onmotion.cache(can, function() { return key }, can.ui.content, can.ui.profile, can.ui.display)) { return can.onimport.layout(can) } + if (can.onmotion.cache(can, function() { return key }, can.ui.content, can.ui.profile, can.ui.display, can._status)) { return can.onimport.layout(can) } if (cb && cb()) { return } if (msg.Append(ctx.INDEX)) { msg.Table(function(value, index) { index == 0 && can.onappend.plugin(can, value, function(sub) { can.db.value._content_plugin = sub, can.onimport.layout(can) }, can.ui.content)