(function() { const RECOVER_TABS = "recover:tabs" const RECOVER_TOOL = "recover:tool" 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) { var paths = can.core.Split(can.Option(nfs.PATH), mdb.FS); can.Option(nfs.PATH, paths[0]) if (can.Mode() == ice.MSG_RESULT) { msg.result = msg.result||[can._output.innerHTML], can.Mode(chat.SIMPLE) } can.core.List(paths.concat(can.core.Split(msg.Option(nfs.REPOS))), function(p) { if (can.base.beginWith(p, nfs.USR_LOCAL_WORK) || can.base.endWith(p, "-dict/")) { return } if (p && paths.indexOf(p) == -1 && p[0] != nfs.PS) { paths.push(p) } }), can.onmotion.clear(can), can.onappend.style(can, code.INNER), can.sup.onimport._process = function(_can, msg) { if (msg.OptionProcess() == ice.PROCESS_REWRITE) { var args = {}, arg = msg._arg; for (var i = 0; i < arg.length; i += 2) { args[arg[i]] = arg[i+1] } can.onimport.tabview(can, args.path, args.file, args.line) } } can.db = {paths: paths, tabview: {}, history: [], _history: [], toolkit: {}}, can.db.tabview[can.onexport.keys(can)] = msg 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.hidden(can, can.ui.plug) can.onmotion.hidden(can, can.ui.profile), can.onmotion.hidden(can, can.ui.display) if (can.Conf(ctx.STYLE) == html.OUTPUT) { can.onmotion.hidden(can, can.ui.project), can.page.style(can, can.ui.content, html.HEIGHT, "") } switch (can.Mode()) { case chat.SIMPLE: // no break case chat.FLOAT: can.onmotion.hidden(can, can.ui.project); break case chat.CMD: can.onappend.style(can, html.OUTPUT) can.onexport.session(can, PROJECT_HIDE) == html.HIDE && can.onmotion.hidden(can, can.ui.project) if (can.onexport.session(can, TABVIEW_HIDE) == html.HIDE) { can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.tabs) } can.onengine.listen(can, chat.ONUNLOAD, function() { can.onexport.recover(can) }) case chat.FULL: // no break default: can.user.isMobile && can.onmotion.hidden(can, can.ui.project), can.onimport.project(can, paths), can.onimport._tabs(can) } var args = can.misc.SearchHash(can), tabs = can.onexport.session(can, RECOVER_TABS), tool = can.onexport.session(can, RECOVER_TOOL) can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.Option(nfs.LINE), function() { if (!can.isCmdMode()) { return } if (tabs) { can.core.Next(tabs, function(item, next) { can.onimport.tabview(can, item[0], item[1], item[2], function() { can.onmotion.delay(can, next) }) }, function() { args.length > 0 && can.onimport.tabview(can, args[args.length-3], args[args.length-2]||can.Option(nfs.FILE), args[args.length-1]) }) } else { args.length > 0 && can.onimport.tabview(can, args[args.length-3], args[args.length-2]||can.Option(nfs.FILE), args[args.length-1]) } tool && can.core.Next(tool, function(item, next) { can.onimport.toolkit(can, item, next) }) }), can.onkeymap._build(can) can.ui.profile.onclick = function(event) { if (can.page.tagis(event.target, html.A)) { var link = can.misc.ParseURL(can, event.target.href); if (!link.cmd) { return } can.onkeymap.prevent(event) link.cmd == web.CODE_VIMER? can.onimport.tabview(can, link.path, link.file, link.line): can.onimport.tabview(can, link.path, link.cmd, ctx.INDEX) } }, can.base.isFunc(cb) && cb(msg) }, _tabs: function(can) { if (!can.isCmdMode()) { return can.ui.tabs = can._action } can.page.Append(can, can.ui.tabs, can.core.List([ {name: can.page.unicode.menu, onclick: function() { can.user.carte(event, can, can.onaction, can.onaction.list) }}, {name: can.page.unicode.refresh, style: {"font-size": 26, "padding-top": 2}, onclick: function() { location.reload() }}, ], function(item) { return can.base.Copy(item, {view: [[html.ITEM, html.ICON], "", item.name]}) })), can.page.Append(can, can.ui.tabs, can.user.header(can)) }, __tabPath: function(can, cache) { var target = can.ui.path 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), can.onimport._tabFunc(can, target, cache), can.onimport._tabMode(can), can.onimport._tabIcon(can) target.ondblclick = function(event) { var show = can.onmotion.toggle(can, can.ui.tabs); 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) { can.base.endWith(button, ps)? can.onimport.tabPath(event, can, ps, key, pre+button, cb, carte): cb(_trans[button], pre) }, parent)._target, file = can.core.Split(event.target.innerHTML.trim(), nfs.PT)[0] 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) }) function remove(p) { if (p && p._sub) { remove(p._sub), can.page.Remove(can, p._sub), delete(p._sub) } } if (parent) { remove(parent), parent._sub = carte } }) }, _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: nfs.PATH}, list, function(ev, button) { last[button] = true, carte.close() can.onimport.tabview(can, "", can.Option(nfs.FILE), can.core.Split(button, nfs.DF, nfs.DF).pop()) }) }}]) }, _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[cb.help+lex.TB+k] = 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[cb.help+lex.TB+"C-"+k] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } }) can.user.carte(event, can, list, []) }}]) }, _tabIcon: function(can) { can.user.isWindows || can.page.Append(can, can.ui.path, can.core.Item({ "\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) }, "\u25E8": shy({"font-size": "23px", rotate: "90deg", translate: "1px 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) }), "\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) }, "\u2756": shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.plug(event, can) }), "\u271A": shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.open(event, can) }), }, function(text, cb) { return cb && {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} })) }, tabview: function(can, path, file, line, cb) { path = path||can.Option(nfs.PATH); var key = can.onexport.keys(can, path, file) function isIndex() { return line == ctx.INDEX } function isSpace() { return line == web.SPACE } function show(skip) { 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: line||can.onexport.session(can, SELECT_LINE+nfs.DF+path+file)||can._msg.Option(nfs.LINE)||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.onmotion.select(can, can.ui.tabs, html.DIV_TABS, msg._tab), can.isCmdMode() && msg._tab.scrollIntoView() if (isSpace()) { can.ui.path.innerHTML = can.page.Format(html.A, can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)})) } else if (isIndex()) { can.onimport._tabPath(can, nfs.PT, ice.CMD, can.Option(nfs.FILE), function(p, pre) { can.onimport.tabview(can, "", can.core.Keys(can.base.trimSuffix(pre, nfs.PT), p), ctx.INDEX) }, can.ui.path) } else { can.onimport.__tabPath(can) } can.page.SelectChild(can, can.ui._profile.parentNode, can.page.Keys(html.DIV_LAYOUT, html.DIV_CONTENT, html.FIELDSET_STORY, [[[html.IFRAME, html.CONTENT]]]), function(target) { can.onmotion.toggle(can, target, target == content) }), can.ui.content._plugin = msg._plugin, can.ui.profile._plugin = msg._profile can.page.SelectChild(can, can.ui._profile.parentNode, can.page.Keys(html.DIV_PROFILE, [[[html.IFRAME, html.PROFILE]]]), function(target) { if (can.onmotion.toggle(can, target, target == msg._profile)) { can.ui.profile = msg._profile } }) can.onimport.layout(can), can.ui.current && can.onmotion.toggle(can, can.ui.current, !isIndex() && !isSpace()) skip || can.onmotion.delay(can, function() { can.onaction.selectLine(can, can.Option(nfs.LINE), true) }), can.base.isFunc(cb) && cb(), 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) { var skip = false; can.db.tabview[key] = msg; var name = file 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() } var tabs = can.onimport.tabs(can, [{name: name, text: file, _menu: shy([nfs.SAVE, nfs.TRASH, web.REFRESH], function(event, button, meta) { can.request(event, msg) can.onaction[button](event, can, button) })}], function(event, tabs) { can._tab = msg._tab = tabs._target, show(skip), skip = true }, function(tabs) { can.onengine.signal(can, VIEW_REMOVE, msg), can.ui.zone.source.refresh() msg.__content || can.page.Remove(can, msg._content), msg._profile != can.ui._profile && can.page.Remove(can, msg._profile) can.ui._profile._cache && delete(can.ui._profile._cache[key]), can.ui._display._cache && delete(can.ui._display._cache[key]) delete(can.db.tabview[key]), can._cache_data && delete(can._cache_data[key]) can.onmotion.delay(can, function() { can.user.isWebview && can.onexport.recover(can) }) }, can.ui.tabs); tabs._list = [path, file, line], can.user.isWebview && can.onexport.recover(can) } if (can.db.tabview[key]) { return !can._msg._tab && !can.isSimpleMode()? load(can.db.tabview[key]): show() } 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, path) { can.onmotion.clear(can, can.ui.project), can.onimport.zone(can, can.core.Item(can.onfigure, function(name, cb) { if (can.base.isFunc(cb)) { return {name: name, _trans: can.onfigure._trans? can.onfigure._trans[name]||"": "", _toggle: function() { can.onimport.layout(can) }, _init: function(target, zone) { return cb(can, target, zone, path) }} } }), 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._root||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("