From 9f1c7644fa77672e1e2c6486eab062da6555c6f7 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Mon, 17 May 2021 20:43:33 +0800 Subject: [PATCH] opt frame.js --- frame.js | 59 +++++++++++++++-------------------- lib/core.js | 9 +++--- lib/page.js | 20 ++++++------ lib/user.js | 2 +- page/index.css | 1 + page/index.js | 7 ----- panel/Action.js | 10 ++++-- panel/Header.js | 65 +++++++++++++++++++-------------------- panel/River.js | 3 +- plugin/input/date.js | 6 ++-- plugin/input/key.js | 4 +-- plugin/input/province.js | 2 +- plugin/local/wiki/feel.js | 2 +- plugin/local/wiki/word.js | 2 +- 14 files changed, 90 insertions(+), 102 deletions(-) diff --git a/frame.js b/frame.js index 5aade20a..26c99a1c 100644 --- a/frame.js +++ b/frame.js @@ -29,8 +29,9 @@ Volcanos("onengine", {help: "搜索引擎", list: [], _init: function(can, meta, "list": cmds.slice(2), "cb": cb, "target": sub._target, }, mod) }, + _engine: function(event, can, msg, panel, cmds, cb) { return false }, _remote: function(event, can, msg, panel, cmds, cb) { - if (panel.onengine.engine(event, can, msg, panel, cmds, cb)) { return } + if (panel.onengine._engine(event, can, msg, panel, cmds, cb)) { return } var key = panel._name+"."+cmds.join(",") if (can.user.isLocalFile) { var msg = can.request(event); msg.Clear("append") @@ -39,11 +40,10 @@ Volcanos("onengine", {help: "搜索引擎", list: [], _init: function(can, meta, } can.misc.Run(event, can, {names: (can.Conf("iceberg")||"/chat/")+panel._name, daemon: can.ondaemon._list[0]+"."+msg._daemon}, cmds, function(msg) { - delete(msg._handle), delete(msg._toast) - Volcanos.meta.pack[key] = msg + Volcanos.meta.pack[key] = msg, delete(msg._handle), delete(msg._toast) can.base.isFunc(cb) && cb(msg) }) - }, engine: function(event, can, msg, panel, cmds, cb) { return false }, + }, listen: shy("监听事件", {}, [], function(can, name, cb) { arguments.callee.meta[name] = (arguments.callee.meta[name]||[]).concat(cb) @@ -57,33 +57,25 @@ Volcanos("onengine", {help: "搜索引擎", list: [], _init: function(can, meta, for (var k in sub["river"]) { can.onengine["river"] = sub["river"]; break } }, }) -Volcanos("ondaemon", {help: "推荐引擎", list: [], _init: function(can) { - if (can.user.isLocalFile) { return } - can.misc.WSS(can, {type: "chrome", name: can.user.Search(can, "daemon")||""}, function(event, msg, cmd, arg) { if (!msg) { return } - if (can.base.isFunc(can.ondaemon[cmd])) { - can.core.CallFunc(can.ondaemon[cmd], { - "can": can, "msg": msg, "cmd": cmd, "arg": arg, - "cb": function() { msg.Reply() }, - }) - } else { - can.onengine._search({}, can, msg, can, ["_search", cmd].concat(arg), function() { - msg.Reply() - }) - } +Volcanos("ondaemon", {help: "推荐引擎", list: [], _init: function(can, name) { if (can.user.isLocalFile) { return } + can.misc.WSS(can, {type: "chrome", name: can.user.Search(can, "daemon")||name}, function(event, msg, cmd, arg) { if (!msg) { return } + can.base.isFunc(can.ondaemon[cmd])? can.core.CallFunc(can.ondaemon[cmd], { + "can": can, "msg": msg, "cmd": cmd, "arg": arg, "cb": function() { msg.Reply() }, + }): can.onengine._search({}, can, msg, can, ["_search", cmd].concat(arg), function() { + msg.Reply() + }) }) }, _list: [""], - toast: function(can, msg, arg) { arg[0] = can - can.onmotion.float.add(can, "float", can.core.CallFunc(can.user.toast, {can: can, msg: msg, cmds: arg})) - }, + pwd: function(can, msg, arg) { can.ondaemon._list[0] = arg[0] }, grow: function(can, msg, arg) { var sub = can.ondaemon._list[msg.Option("_target")] - if (!sub._outputs || !sub._outputs.length) { return } + if (!sub || !sub._outputs || !sub._outputs.length) { return } var out = sub._outputs[sub._outputs.length-1] out.onimport._grow(out, arg.join("")) }, - pwd: function(can, msg, arg) { - can.ondaemon._list[0] = arg[0] + toast: function(can, msg, arg) { + can.onmotion.float.add(can, "float", can.core.CallFunc(can.user.toast, {can: can, msg: msg, cmds: arg})) }, }) Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, list, cb, target, field) { @@ -95,9 +87,9 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, var output = can.page.Select(can, field, "div.output")[0] var status = can.page.Select(can, field, "div.status")[0] - var sub = Volcanos(meta.name, {_follow: can._follow+"."+meta.name, + var sub = Volcanos(meta.name, {_follow: can.core.Keys(can._follow, meta.name), _target: field, _legend: legend, _option: option, _action: action, _output: output, _status: status, - _target: field, _inputs: {}, _outputs: [], _history: [], + _inputs: {}, _outputs: [], _history: [], Option: function(key, value) { if (key == undefined) { value = {} sub.page.Select(sub, option, "textarea.args,input.args,select.args", function(item) { @@ -190,7 +182,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, key.indexOf("on") == 0 && !input._target[key] && (input._target[key] = function(event) { value(event, input) }) - }), can.onappend.figure(input, item, item.value, input._target) + }), can.onappend.figure(input, item, item.value, function() {}, input._target) can.core.CallFunc([input.onaction, "_init"], [input, item, [], next, input._target]) }) @@ -383,7 +375,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, return sort && can.page.RangeTable(can, table, sort), table }, - board: function(can, text, target) { text = can.page.Display(text||"") + board: function(can, text, target) { text = can.page.Color(text||"") var code = text && can.page.Append(can, target||can._output, [{view: ["code", "div", text]}]).code can.page.Select(can, code, "input[type=button]", function(target) { target.onclick = function(event) { @@ -395,13 +387,13 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, return code }, - figure: function(can, meta, key, target) { + figure: function(can, meta, key, cb, target) { if (!key || key[0] != "@") { return } var list = can.core.Split(key, "@=", "@=") var pkey = list[0], pval = list[1]||"" target.type != "button" && (target.value = pval||""), can.require(["/plugin/input/"+pkey+".js"], function(can) { - can.core.Item(can.onfigure[pkey], function(key, cb) { if (key.indexOf("on") == 0) { target[key] = function(event) { + can.core.Item(can.onfigure[pkey], function(key, on) { if (key.indexOf("on") == 0) { target[key] = function(event) { can.onappend._init(can, {type: "input", name: pkey, pos: "float"}, [], function(sub) { sub.run = function(event, cmds, cb) { var msg = sub.request(event, can.Option()); @@ -411,7 +403,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta, can.onmotion.float.add(can, "input", sub) meta.style && sub.page.Modify(sub, sub._target, {style: meta.style}) - cb(event, sub, meta, target) + on(event, sub, meta, cb, target) }, document.body) } } }) }) @@ -568,11 +560,10 @@ Volcanos("onmotion", {help: "动态特效", list: [], _init: function(can, targe }, auto: function(can, target, key) { var that = this + var list = can.core.List(arguments).slice(2) can.page.Modify(can, target, {onmouseover: function(event) { - if (event.target.tagName == "img") { return } - can.core.List(arguments, function(key, index) { - index > 1 && that.del(can, key) - }) + if (event.target.tagName == "IMG") { return } + can.core.List(list, function(key, index) { that.del(can, key) }) }}) }, }, diff --git a/lib/core.js b/lib/core.js index 507e07bf..8f907186 100644 --- a/lib/core.js +++ b/lib/core.js @@ -103,7 +103,7 @@ Volcanos("core", {help: "数据结构", return res }), - List: shy("迭代器", function(list, cb, interval, cbs) { list = list || [] + List: shy("迭代器", function(list, cb, interval, cbs) { if (typeof list == "string") { // 默认序列 list = [list] @@ -116,20 +116,19 @@ Volcanos("core", {help: "数据结构", } } + list = list || [] + if (interval > 0) { // 时间序列 function loop(i) { if (i >= list.length) { return typeof cbs == "function" && cbs(list) } cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) } typeof cb == "function" && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) - } else { // 选择序列 var slice = [], res for (var i = 0; i < list.length; i++) { typeof cb == "function"? (res = cb(list[i], i, list)) != undefined && slice.push(res): slice.push(list[i]) - } - list = slice + }; list = slice } - return list }), Next: shy("迭代器", function(list, cb, cbs) { diff --git a/lib/page.js b/lib/page.js index 476b0106..4a1c2864 100644 --- a/lib/page.js +++ b/lib/page.js @@ -163,7 +163,7 @@ Volcanos("page", {help: "网页模块", ClassList: { // 递归节点 item.list && can.page.Append(can, node, item.list, value) target && target.append && target.appendChild(node) - typeof item._init == "function" && item._init(node) + can.base.isFunc(item._init) && item._init(node) }) return value }), @@ -182,7 +182,7 @@ Volcanos("page", {help: "网页模块", ClassList: { }]) can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) { return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return } - return cb(can.page.Display(line[key]).trim(), key, index, line, array) + return cb(can.page.Color(line[key]).trim(), key, index, line, array) })} })) return can.page.OrderTable(can, table) @@ -248,13 +248,19 @@ Volcanos("page", {help: "网页模块", ClassList: { } }, - Display: function(text) { if (typeof text != "string") { return "" } + Format: function(type, src) { + switch (type) { + case "a": return ""+(arguments[2]||arguments[1])+"" + case "img": return arguments[2]? "": "" + } + }, + Color: function(text) { if (typeof text != "string") { return "" } if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) { var ls = text.split(" "); text = ""+ls[0]+""+ls.slice(1).join(" ") }; text = text.replace(/\\n/g, "
") - // if (!text.indexOf("\033\[")) { return text } + if (text.indexOf("\033\[") == -1) { return text } text = text.replace(/\033\[31m/g, "") text = text.replace(/\033\[32m/g, "") text = text.replace(/\033\[33m/g, "") @@ -267,12 +273,6 @@ Volcanos("page", {help: "网页模块", ClassList: { text = text.replace(/\033\[m/g, "") return text }, - Format: function(type, src) { - switch (type) { - case "a": return ""+(arguments[2]||arguments[1])+"" - case "img": return arguments[2]? "": "" - } - }, Cache: function(name, output, data) { var cache = output._cache || {}; output._cache = cache if (data) { if (output.children.length == 0) { return } var temp = document.createDocumentFragment() diff --git a/lib/user.js b/lib/user.js index aed0a8df..e0e6793d 100644 --- a/lib/user.js +++ b/lib/user.js @@ -169,7 +169,7 @@ Volcanos("user", {help: "用户操作", agent: { }); can.run(event, cmds, cb, true) } - can.onappend.figure(can, item, item.value, target) + can.onappend.figure(can, item, item.value, function() {}, target) target.value = target.value || msg.Option(item.name) } diff --git a/page/index.css b/page/index.css index 1a3d77d9..7399cdfc 100644 --- a/page/index.css +++ b/page/index.css @@ -161,6 +161,7 @@ table.content tr { table.content th { background-color:#0fbd45; padding:2px 6px; + cursor:pointer; } table.content td { padding:2px 6px; diff --git a/page/index.js b/page/index.js index 223762f3..1c199626 100644 --- a/page/index.js +++ b/page/index.js @@ -112,9 +112,6 @@ Volcanos({name: "chat", iceberg: "/chat/", volcano: "/frame.js", ]}, }}, "operate": {name: "运维群", storm: { - "ctx": {name: "模块 ctx", index: [ - "context", "command", "config", - ]}, "cli": {name: "系统 cli", index: [ "system", "daemon", "python", "output", "runtime", "process", @@ -123,10 +120,6 @@ Volcanos({name: "chat", iceberg: "/chat/", volcano: "/frame.js", "route", "serve", "space", "dream", "spide", "share", "cache", "story", ]}, - "aaa": {name: "权限 aaa", index: [ - "user", "sess", "role", "totp", - ]}, - "nfs": {name: "文件 nfs", index: [ "nfs.cat", "nfs.dir", "nfs.tail", "nfs.trash", ]}, diff --git a/panel/Action.js b/panel/Action.js index b895d5e8..22e5463a 100644 --- a/panel/Action.js +++ b/panel/Action.js @@ -62,7 +62,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg) }, }) Volcanos("onengine", {help: "解析引擎", list: [], - engine: function(event, page, msg, can, cmds, cb) { + _engine: function(event, page, msg, can, cmds, cb) { var river = can.onengine.river[cmds[0]] var storm = river && river.storm[cmds[1]] if (!storm || cmds.length != 2) { return false } @@ -92,7 +92,7 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, var share = can.user.Search(can, can._SHARE); if (share) { can.run({}, ["_share", share], function(msg) { msg.Length()>0? can.onimport._share(can, msg, share): - can.onengine.engine({}, can, msg, can, [msg.Option("sess.river"), msg.Option("sess.storm")], function(msg) { + can.onengine._engine({}, can, msg, can, [msg.Option("sess.river"), msg.Option("sess.storm")], function(msg) { can.onimport._share(can, msg, share) }) }) @@ -136,7 +136,11 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, can.onmotion.select(can, can._output, "fieldset.plugin", 0) can.onmotion.select(can, can._action, "div.item", 0) } - + if (key == "free") { + can.page.Select(can, can._target, "div.output>fieldset.plugin", function(item, index) { + can.onmotion.move(can, item, {left: 10*index, top: 10*index}) + }) + } var header = can.get("Header", "height") var footer = can.get("Footer", "height") diff --git a/panel/Header.js b/panel/Header.js index ca086599..bd298ead 100644 --- a/panel/Header.js +++ b/panel/Header.js @@ -1,12 +1,4 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { - const GRANT = "grant"; if (can.user.Search(can, GRANT)) { - if (can.user.confirm(GRANT+" "+can.user.Search(can, GRANT))) { - can.run(event, [can._ACTION, GRANT, "space", can.user.Search(can, GRANT)]) - } - can.user.Search(can, GRANT, "") - return - } - can._trans = { "river": "菜单", "search": "搜索", @@ -24,16 +16,37 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, } can.onmotion.clear(can) + can.onimport._agent(can, msg, target) + can.onimport._grant(can, msg, target) can.onimport._title(can, msg, target) can.onimport._state(can, msg, target) can.onimport._search(can, msg, target) can.onimport._background(can, msg, target) - can.onimport._agent(can, msg, target) can.onimport._menu(can, msg, target) - can.base.isFunc(cb) && cb(msg) - can.onmotion.float.auto(can, can._output, "carte", "input") + can.base.isFunc(cb) && cb(msg) + }, + _agent: function(can, msg, target) { + if (can.user.isMobile) { + can.onaction.River(can) + can.onaction.Footer(can) + } else if (can.user.isExtension) { + can.onaction.River(can) + } else if (can.user.Search(can, "pod")) { + can.onaction.River(can) + can.onaction.Footer(can) + } + can.user.isWeiXin && can.onimport._weixin(can) + }, + _grant: function() { + const GRANT = "grant"; if (can.user.Search(can, GRANT)) { + if (can.user.confirm(GRANT+" "+can.user.Search(can, GRANT))) { + can.run(event, [can._ACTION, GRANT, "space", can.user.Search(can, GRANT)]) + } + can.user.Search(can, GRANT, "") + return true + } }, _title: function(can, msg, target) { can.user.title(can.user.Search(can, can._TITLE)||can.user.Search(can, "pod")) @@ -68,26 +81,11 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, // ; can.onmotion.autosize(can, ui.input, 240, 120) can.user.isMobile && can.page.Modify(can, ui.first, {style: {float: "right"}}) }, - _avatar: function(can, msg) { - !can.user.isLocalFile && can.page.Modify(can, "div.output div.state.avatar>img", {src: can.Conf(can._AVATAR, msg.Option(can._AVATAR))}) - }, _background: function(can, msg) { if (can.user.isLocalFile) { return } if (can.user.isExtension) { return } can.onlayout.background(can, msg.Option(can._BACKGROUND), document.body) }, - _agent: function(can, msg, target) { - if (can.user.isMobile) { - can.onaction.River(can) - can.onaction.Footer(can) - } else if (can.user.isExtension) { - can.onaction.River(can) - } else if (can.user.Search(can, "pod")) { - can.onaction.River(can) - can.onaction.Footer(can) - } - can.user.isWeiXin && can.onimport._weixin(can) - }, _menu: function(can, msg, target) { can.onimport.menu(can, can.user.isMobile||can.user.isExtension||can.user.Search(can, "pod")? ["header", can._RIVER]: ["header", ["setting", "black", "white", "print", "pack"]], function(event, item) { @@ -121,17 +119,18 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, }) }) }) }, - + _avatar: function(can, msg) { + !can.user.isLocalFile && can.page.Modify(can, "div.output div.state.avatar>img", {src: can.Conf(can._AVATAR, msg.Option(can._AVATAR))}) + }, _time: function(can, target) { can.core.Timer({interval: 1000}, function() { can.onimport.time(can, target) }) - can.onappend.figure(can, {style: {"min-width": 306}}, "@date", target) - - target.onmouseenter = function(event) { target.click() - can.core.Timer(10, function() { - // can.onlayout.figure(event, can, Volcanos.meta.float.input._target) + can.onappend.figure(can, {style: {"min-width": 306}}, "@date", function(sub) { + can.search({}, ["Action.onexport.size"], function(msg, top) { + can.page.Modify(can, sub._target, {style: {top: top, left: window.innerWidth-sub._target.offsetWidth}}) }) - } + }, target), target.onmouseenter = function() { target.click() } }, + time: function(can, target) { can.onlayout.topic(can) target.innerHTML = can.base.Time(null, "%w %H:%M:%S") }, diff --git a/panel/River.js b/panel/River.js index 4c77c19f..5adca586 100644 --- a/panel/River.js +++ b/panel/River.js @@ -89,7 +89,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, }}) }, }) -Volcanos("onengine", {help: "解析引擎", list: [], engine: function(event, can, msg, panel, cmds, cb) { +Volcanos("onengine", {help: "解析引擎", list: [], _engine: function(event, can, msg, panel, cmds, cb) { cmds.length == 0 && can.core.Item(can.onengine.river, function(key, value) { msg.Push({hash: key, name: value.name}) }); if (cmds.length != 1 && cmds[1] != "tool") { return false } @@ -153,6 +153,7 @@ Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg, var carte = can.user.carte(event, can, can.ondetail, list, cb) can.page.Modify(can, carte._target, {style: { left: event.clientX-event.offsetX+event.target.offsetWidth-3, + top: carte._target.offsetTop-event.target.offsetHeight, }}) }, diff --git a/plugin/input/date.js b/plugin/input/date.js index d4636e4a..88c888b0 100644 --- a/plugin/input/date.js +++ b/plugin/input/date.js @@ -1,6 +1,6 @@ -Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(event, can, item, target) { +Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(event, can, meta, cb, target) { function set(now) { target.value = can.base.Time(now), can.page.Remove(can, can._target) - item && item.action == "auto" && can.run({}) + meta && meta.action == "auto" && can.run({}) } // 添加控件 @@ -56,7 +56,7 @@ Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(e for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")} for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")} - return can.onlayout.figure(event, can), now + return can.onlayout.figure(event, can), cb(can), now }; show(now) }} }, ["/plugin/input/date.css"]) diff --git a/plugin/input/key.js b/plugin/input/key.js index 8a4caeb7..0b4f8ce2 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -1,5 +1,5 @@ -Volcanos("onfigure", {help: "控件详情", list: [], key: {onclick: function(event, can, item, target) { - can.run(event, ["action", "inputs", item.name, target.value], function(msg) { +Volcanos("onfigure", {help: "控件详情", list: [], key: {onclick: function(event, can, meta, cb, target) { + can.run(event, ["action", "inputs", meta.name, target.value], function(msg) { if (msg.Length() == 0) { return can.page.Remove(can, can._target) } can.onappend._action(can, ["关闭", "清空"], can._action, { diff --git a/plugin/input/province.js b/plugin/input/province.js index 2644bdc7..7ee83079 100644 --- a/plugin/input/province.js +++ b/plugin/input/province.js @@ -1,4 +1,4 @@ -Volcanos("onfigure", {help: "控件详情", list: [], province: {onclick: function(event, can, item, target) { +Volcanos("onfigure", {help: "控件详情", list: [], province: {onclick: function(event, can, meta, cb, target) { can.require(["/require/github.com/shylinux/echarts/echarts.js","/require/github.com/shylinux/echarts/china.js"], function() { can.onappend._action(can, ["关闭", "清空"], can._action, { "关闭": function(event) { can.page.Remove(can, can._target) }, diff --git a/plugin/local/wiki/feel.js b/plugin/local/wiki/feel.js index 1f3ef822..0ffbfa9c 100644 --- a/plugin/local/wiki/feel.js +++ b/plugin/local/wiki/feel.js @@ -86,7 +86,7 @@ Volcanos("ondetail", {help: "组件菜单", list: ["关闭", "下载", "上一 can.onappend._init(can, {type: "story feel float"}, [], function(sub) { can.sub = sub sub.run = function(event, cmds, cb) { return can.run(event, cmds, cb, true) } - sub.search(["Action.onexport.size"], function(msg, left, top, width, height) { + sub.search({}, ["Action.onexport.size"], function(msg, left, top, width, height) { sub.page.Modify(sub, sub._target, {style: {left: left, top: top}}) sub.page.Modify(sub, sub._output, {style: {"max-width": width, "max-height": height}}) sub.onappend._action(can, can.ondetail.list, sub._action, can.ondetail) diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js index 234b950a..66eaad30 100644 --- a/plugin/local/wiki/word.js +++ b/plugin/local/wiki/word.js @@ -45,7 +45,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, item.type = "story" can.onappend._init(can, item, ["/plugin/state.js"], function(sub) { sub.run = function(event, cmds, cb, silent) { - can.run(event, (cmds && cmds[0] == "search"? []: ["action", "story", data.type, data.name, data.text]).concat(cmds), cb, true) + can.run(event, (cmds && cmds[0] == "_search"? []: ["action", "story", data.type, data.name, data.text]).concat(cmds), cb, true) } can.page.Modify(can, sub._output, {style: {"max-width": item.width-40}})