(function() { const PROJECT_HIDE = "project:hide", TABVIEW_HIDE = "tabview:hide" const PROFILE_ARGS = "profile:args:", DISPLAY_ARGS = "display:args:" const CURRENT_FILE = "web.code.inner:currentFile", SELECT_LINE = "selectLine" const VIEW_CREATE = "tabview.view.create", VIEW_REMOVE = "tabview.view.remove", LINE_SELECT = "tabview.line.select" Volcanos(chat.ONIMPORT, { _init: function(can, msg, cb) { can.onappend.style(can, code.INNER), can.Mode(msg.Option("mode")||can.Mode()) if (can.Mode() == ice.MSG_RESULT) { msg.result = msg.result||[can._output.innerHTML], can.Mode(chat.SIMPLE), can.sup.Mode(chat.SIMPLE) } can.onmotion.clear(can, can._output), msg.result = msg.result||[""] var paths = can.core.Split(can.Option(nfs.PATH)); can.Option(nfs.PATH, paths[0]) can.core.List([nfs.PATH, nfs.FILE, nfs.LINE], function(key) { msg.Option(key) && can.Option(key, msg.Option(key)) }) can.db = {tabview: {}, history: [], _history: [], toolkit: {}}, can.db.tabview[can.onexport.keys(can)] = msg can.db.hash = can.isCmdMode()? can.misc.SearchHash(can): [] can.ui = can.onappend.layout(can, [html.PROJECT, [html.TABS, nfs.PATH, [html.CONTENT, html.PROFILE], html.DISPLAY, html.PLUG]]) can.ui._content = can.ui.content, can.ui._profile = can.ui.profile, can.ui._display = can.ui.display can.onmotion.clear(can, can.ui.project), can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.tabs), can.onmotion.hidden(can, can.ui.plug) can.db.value = {} var show = !can.user.isMobile switch (can.Mode()) { case chat.SIMPLE: // no break case chat.FLOAT: break case chat.CMD: can.onappend.style(can, html.OUTPUT) if (can.onexport.session(can, PROJECT_HIDE) == html.HIDE) { show = false } if (can.onexport.session(can, TABVIEW_HIDE) == html.HIDE) { show = false } else { can.onmotion.toggle(can, can.ui.tabs, true), can.onmotion.toggle(can, can.ui.plug, true) } var tool = (can.base.Obj(msg.Option(ice.MSG_TOOLKIT), []).reverse()); msg.Option(ice.MSG_TOOLKIT, "[]") can.onimport._tabs(can), tool && tool.length > 0? can.core.Next(tool, function(item, next) { can.onimport.toolkit(can, item, next) }): can.onmotion.hidden(can, can.ui.plug) case chat.FULL: // no break default: can.onmotion.toggle(can, can.ui.project, show), can.onimport.project(can, can.db.paths = paths), can.onkeymap._build(can) } can.onimport.layout(can), can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.Option(nfs.LINE), function() { cb && cb(msg) }) }, _tabs: function(can) { if (!can.isCmdMode()) { return can.ui._tabs = can._action } var ui = can.page.Append(can, can.ui.tabs, ["tabs", "head"]); can.ui._tabs = ui.tabs, can.page.Append(can, ui.head, can.user.header(can)) }, _tabIcon: function(can) { can.page.Append(can, can.ui.path, can.core.Item({ "\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,-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 ": shy({width: 32}, function(event) { if (can.page.isDisplay(can.ui.profile)) { can._msg._profile_hidden = true 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} })) }, _tabMode: function(can) { var mode = can.db.mode||"", target = can.ui.current; if (target && mode != mdb.PLUGIN) { mode += lex.SP+target.selectionStart+nfs.PS+target.value.length } can.page.Append(can, can.ui.path, [{text: [mode, "", [ice.MODE, can.db.mode||""]], onclick: function(event) { var list = {}; can.core.Item(can.onkeymap._mode[can.db.mode], function(k, cb) { list[k+" "+cb.help] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } }) can.core.Item(can.onkeymap._mode[can.db.mode+"_ctrl"], function(k, cb) { list["C-"+k+" "+cb.help] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } }) list._style = "inner mode" can.user.carte(event, can, list, []) }}]) }, _tabFunc: function(can, target, cache) { if (cache) { var func = can.db._func||{list: []} } else { var func = can.onexport.func(can); can.db._func = func } if (func.list.length > 0) { can.db.tabFunc = can.db.tabFunc||{} var last = can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)]||{}; can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)] = last var carte, list = [web.FILTER]; can.core.Item(last, function(key) { list.push(key) }), list = list.concat(func.list) } can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"func")+nfs.PS+can.ui.content._max+func.percent+lex.SP+can.base.Size(can._msg.result[0].length)], onclick: function(event) { carte = can.user.carte(event, can, {_style: "inner "+nfs.PATH}, list, function(ev, button) { last[button] = true, carte.close() var line = can.core.Split(button, nfs.DF, nfs.DF).pop() can.onimport.tabview(can, "", can.Option(nfs.FILE), line, function() { can.onaction.selectLine(can, line, true) }) }) carte && can.onmotion.delay(can, function() { can.page.Select(can, carte._target, html.DIV_ITEM, function(target) { can.onappend.style(can, can.base.beginWith(target.innerText, "- ")? aaa.PRIVATE: aaa.PUBLIC, target) }) }) }}]) }, __tabPath: function(can, cache) { var target = can.ui.path function _space(grow) { can.page.Append(can, target, [{view: ["_space", html.SPAN], style: {"flex-grow": grow||"1"}}]) } can.onimport._tabPath(can, nfs.PS, nfs.PATH, can.base.Path(can.Option(nfs.PATH), can.Option(nfs.FILE)), function(p) { var ls = can.onexport.split(can, p); can.onimport.tabview(can, ls[0], ls[1]) }, target), _space(), can.onimport._tabFunc(can, target, cache), _space(), can.onimport._tabMode(can), _space("4"), can.onimport._tabIcon(can) target.ondblclick = function(event) { if (event.target != target && !can.page.tagis(event.target, "span._space")) { return } var show = can.onmotion.toggle(can, can.ui.tabs); can.onmotion.toggle(can, can.ui.plug, show), can.onmotion.toggle(can, can.ui.project, show), can.onimport.layout(can) can.isCmdMode() && can.onexport.session(can, TABVIEW_HIDE, show? "": html.HIDE) } }, _tabPath: function(can, ps, key, value, cb, target) { var args = value.split(mdb.FS); can.onmotion.clear(can, can.ui.path) can.core.List(can.core.Split(args[0], ps), function(value, index, list) { can.page.Append(can, target, [{text: [value+(index 10? [web.FILTER]: []).concat(msg.Table(function(value) { var p = can.core.Split(value[key], ps).pop()+(can.base.endWith(value[key], ps)? ps: ""); return _trans[p] = value[key], p })), function(event, button) { if (can.base.endWith(button, ps)) { can.onimport.tabPath(event, can, ps, key, pre+button, cb, carte); return true } else { cb(_trans[button], pre) } }, parent)||{})._target, file = can.core.Split(event.target.innerHTML.trim(), nfs.PT)[0] carte && can.page.Select(can, carte, html.DIV_ITEM, function(target) { target.innerHTML.trim() != event.target.innerHTML.trim() && can.base.beginWith(target.innerHTML, file+nfs.PT) && carte.insertBefore(target, carte.firstChild) target.innerHTML.trim() == event.target.innerHTML.trim() && can.onappend.style(can, html.SELECT, target) }), can.onmotion.delay(can, function() { carte.scrollTop = 0 }) }) }, openzone: function(can, path, file, line) { if (line == web.SPACE) { can.page.isDisplay(can.ui.zone.space._target) || can.ui.zone.space._legend.click() } else if (line == ctx.INDEX) { if (can.base.beginWith(file, "can.")) { can.page.isDisplay(can.ui.zone.plugin._target) || can.ui.zone.plugin._legend.click() } else { can.page.isDisplay(can.ui.zone.command._target) || can.ui.zone.command._legend.click() } } else { if (can.ui.zone && can.ui.zone.source) { can.page.isDisplay(can.ui.zone.source._target) || can.ui.zone.source._legend.click() } return true } }, tabview: function(can, path, file, line, cb) { path = path||can.Option(nfs.PATH), line && can.Option(nfs.LINE, line); var key = can.onexport.keys(can, path, file) 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.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)) } else if (isIndex()) { can.onmotion.hidden(can, can.ui.path) } else { can.onimport.__tabPath(can) } can.page.Select(can, can.ui.content.parentNode, "div.scrollbar", function(target) { can.page.style(can, target, "visibility", "hidden") }) can.page.SelectChild(can, can.ui._content.parentNode, can.page.Keys(html.DIV_CONTENT, html.DIV_LAYOUT, html.FIELDSET_STORY, [[[html.IFRAME, html.CONTENT]]]), function(target) { can.onmotion.toggle(can, target, target == content) }), can.ui.content._plugin = msg._plugin can.page.SelectChild(can, can.ui._profile.parentNode, can.page.Keys(html.DIV_PROFILE, [[[html.IFRAME, html.PROFILE]]]), function(target) { if (target == msg._profile) { can.ui.profile = msg._profile, msg._profile_hidden || can.onmotion.toggle(can, target, true) } }), can.ui.profile._plugin = msg._profile can.page.ClassList.set(can, can._output, nfs.SOURCE, can.onimport.openzone(can, path, file, line)), can.onimport.layout(can) can.onaction.selectLine(can, can.Option(nfs.LINE)), can.base.isFunc(cb) && cb(msg), cb = null var ls = can.onexport.path(can).split(nfs.PS); if (ls.length > 4) { ls = [ls.slice(0, 2).join(nfs.PS)+"/.../"+ls.slice(-2).join(nfs.PS)] } can.Status(kit.Dict(nfs.FILE, ls.join(nfs.PS))) }) } function load(msg) { can.db.tabview[key] = msg; var name = file msg.result = msg.result||[""] if (can.base.beginWith(file, web.HTTP)) { name = decodeURI(file.split(web.QS)[0]) var link = can.misc.ParseURL(can, name); if (link.pod) { name = link.pod } name = can.base.trimPrefix(name, location.origin) } else { name = file.split(mdb.FS)[0].split(isIndex()? nfs.PT: nfs.PS).pop() } line && msg.Option(nfs.LINE, line) var tabs = can.onimport.tabs(can, [{name: name, text: (isIndex() || isSpace()? "": path)+file, _menu: shy(can.base.Obj(msg.Option(ice.MSG_ACTION), []), function(event, button, meta) { can.request(event, msg), can.onaction[button]? can.onaction[button](event, can, button): can.onaction._runs(event, can, button) })}], function(event, tabs) { can._tab = msg._tab = tabs._target, show(), msg._item && (can.page.isSelect(msg._item) || msg._item.click(), can.onmotion.scrollIntoView(can, msg._item)) }, function(tabs) { can.onengine.signal(can, VIEW_REMOVE, msg), delete(can.db.tabview[key]) msg._content != can.ui._content && can.page.Remove(can, msg._content), msg._profile != can.ui._profile && can.page.Remove(can, msg._profile) can.onmotion.cacheClear(can, key, can.ui._content, can.ui._profile, can.ui._display) }, can.ui._tabs) } can._msg._tab && can.onmotion.scrollIntoView(can, can._msg._tab) if (can.db.tabview[key]) { return can.isSimpleMode()? show(): can._msg._tab? (can._msg._tab.click(), show()): load(can.db.tabview[key]) } isIndex()||isSpace()? load(can.request({}, {index: file, line: line})): can.run({}, [path, file], load, true) }, history: function(can, record) { can.base.Eq(record, can.db.history[can.db.history.length-1], mdb.TEXT) || can.db.history.push(record) return can.Status(ice.BACK, can.db.history.length), record }, project: function(can) { can.onimport.zone(can, can.core.Item(can.onfigure, function(name, cb) { if (can.base.isFunc(cb)) { return {name: name, _toggle: function(zone) { var target = can.page.isDisplay(zone._target)? zone._target: can.ui.zone.source._target can.core.Item(can.ui.zone, function(key, zone) { key.indexOf(nfs.PS) > 0 || zone.toggle(zone._target == target) }), can.onimport.layout(can) }, _init: function(target, zone) { var onclick = zone._legend.onclick zone._legend.onclick = function(event) { if (can.page.isDisplay(zone._target)) { return } onclick(event) } return cb(can, target, zone, can.db.hash) }} } }), can.ui.project) }, profile: function(can, msg) { var _msg = can.db.tabview[can.onexport.keys(can)]; _msg.Option(html.WIDTH, msg.Option(html.WIDTH)), border = 1 var height = can.ui.content.offsetHeight, width = can.onexport.size(can, _msg.Option(html.WIDTH)||0.5, can.ConfWidth()-can.ui.project.offsetWidth)+border if (msg.Result().indexOf("